Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

Arduino UNO R4 WiFi-Controlled Stepper Motor with OLED Display Interface

View and Edit Project In Cirkit DesignerImage of Arduino UNO R4 WiFi-Controlled Stepper Motor with OLED Display Interface

Circuit Documentation

Summary

The circuit is designed to control a 28BYJ-48 stepper motor using an Arduino UNO R4 WiFi microcontroller. The control is facilitated through pushbuttons and limit switches, with feedback provided by a 128x64 OLED display. The user can navigate options on the OLED menu to select and configure the motor's direction, position, speed, and the display's brightness. The circuit also includes a rotary potentiometer to adjust the motor speed and a real-time clock (RTC) for timekeeping. The system is powered by a DC source and includes debouncing for the pushbuttons and error handling.

Component List

Wiring Details

Arduino UNO R4 WiFi

Limit Switches

Toggle Switch

Pushbuttons

0.96" OLED

Resistor (10k Ohms)

28BYJ-48 Stepper Motor

ULN2003A Breakout Board

Rotary Potentiometer (10k Ohms)

DC Source

128x64 OLED Display (I2C IIC SPI Serial)

Documented Code

/*
 * Arduino UNO R4 Project
 * This code controls a 28BYJ-48 stepper motor using push buttons Up,
 * Down, and Select to navigate options on 128x64 OLED menu. Menu items
 * should show direction, position, speed, brightness of display to be
 * selected and configured. It also displays the motor direction and speed
 * percentage on an OLED display using I2C via U8g2lib. Additionally, it
 * prints events to the serial monitor. If both up and select buttons are
 * pressed simultaneously, the motor will go until it reaches the top limit
 * switch. If the down and select buttons are pressed, it will go to the
 * lower limit switch. If only the up button is pressed, the motor will go
 * up until the button is released, stopping at the top limit switch. If
 * only the down button is pressed, the motor will go down until released,
 * stopping at the lower limit switch. If the select button is held down
 * for 10 seconds, the menu will be accessed. The display will feature time
 * and date displayed at all times in the top corners. Apply debouncing and
 * error handling, and print all events to serial console.
 */

#include <Wire.h>
#include <AccelStepper.h>
#include <RTClib.h>
#include <Bounce2.h>
#include <U8g2lib.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// OLED display
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 16, /* data=*/ 17);
// Stepper motor setup
AccelStepper stepper(AccelStepper::FULL4WIRE, 13, 12, 11, 10);

// Pushbutton pins
const int upButtonPin = 2;
const int downButtonPin = 4;
const int selectButtonPin = 3;

// Limit switch pins
const int upperLimitPin = 9;
const int lowerLimitPin = 8;

// Potentiometer pin
const int potPin = A0;

// RTC setup
RTC_DS3231 rtc;

// Variables
volatile int speedPercent = 0;
long position = 0;
long lastPosition = -1; // To track position changes
unsigned long selectButtonPressTime = 0;
bool menuActive = false;

// Debounce instances
Bounce upButton = Bounce();
Bounce downButton = Bounce();
Bounce selectButton = Bounce();

void setup() {
  // Initialize serial communication
  Serial.begin(9600);

  // Initialize display
  u8g2.begin();

  // Initialize pushbuttons with debounce
  upButton.attach(upButtonPin, INPUT_PULLDOWN);
  upButton.interval(25);
  downButton.attach(downButtonPin, INPUT_PULLDOWN);
  downButton.interval(25);
  selectButton.attach(selectButtonPin, INPUT_PULLDOWN);
  selectButton.interval(25);

  // Initialize limit switches
  pinMode(upperLimitPin, INPUT);
  pinMode(lowerLimitPin, INPUT);

  // Initialize potentiometer
  pinMode(potPin, INPUT);

  // Initialize stepper motor
  stepper.setMaxSpeed(1000);
  stepper.setAcceleration(500);

  // Initialize RTC
  if (!rtc.begin()) {
    Serial.println(F("Couldn't