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

Arduino-Controlled Stepper Motor with A4988 Driver and EEPROM Position Saving

View and Edit Project In Cirkit DesignerImage of Arduino-Controlled Stepper Motor with A4988 Driver and EEPROM Position Saving

Circuit Documentation

Summary

This circuit is designed to control a bipolar stepper motor using an A4988 stepper motor driver, interfaced with an Arduino UNO microcontroller. The circuit includes various capacitors for filtering and stability, resistors for current limiting, pushbuttons for user input, an LED for indication, a rotary encoder for additional input, and an OLED display for output. The Arduino UNO is programmed to control the stepper motor's direction, step size, and position based on button presses and to save positions to EEPROM for recall.

Component List

A4988 Stepper Motor Driver (Red)

Ceramic Capacitors

Electrolytic Capacitors

LED: Two Pin (red)

Resistor

ams1117 3.3

Tantalum Capacitor

Diode

Stepper Motor (Bipolar)

5V PSU

Pushbutton

Rotary Encoder with Knob

Arduino UNO

OLED Display (128x32)

Wiring Details

A4988 Stepper Motor Driver (Red)

Ceramic Capacitors

Electrolytic Capacitors

LED: Two Pin (red)

Resistor

ams1117 3.3

Tantalum Capacitor

Diode

Stepper Motor (Bipolar)

5V PSU

Pushbuttons

Rotary Encoder with Knob

OLED Display (128x32)

Documented Code

#include <Arduino.h>
#include <EEPROM.h>

const int stepPin = 11;
const int dirPin = 12;
const int enablePin = 6; // Changed from 5 to 6
const int ms1Pin = 7;
const int ms2Pin = 8;
const int ms3Pin = 9;

const int buttonAPin = 4;
const int buttonBPin = 10;
const int buttonCCWPin = 2;  // New button for CCW
const int buttonCWPin = 3;   // New button for CW
const int buttonSavePin = 5; // New button for saving position (changed from 6 to 5)

const int stepsPerRevolution = 200;
const int microsteps = 8;  // 1/8 step mode
const float correctionFactor = 180.0 / 180.0;  // Correction factor based on your observation
const float stepsPerDegree = ((stepsPerRevolution * microsteps) / 360.0) * correctionFactor;

int currentPosition = 0;  // Track the current position in degrees
int buttonAPosition = 0;  // Position for Button A
int buttonBPosition = 180; // Position for Button B
int lastButtonPressed = 0; // 1 for Button A, 2 for Button B

void setup() {
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(enablePin, OUTPUT);
  pinMode(ms1Pin, OUTPUT);
  pinMode(ms2Pin, OUTPUT);
  pinMode(ms3Pin, OUTPUT);
  
  pinMode(buttonAPin, INPUT_PULLUP);
  pinMode(buttonBPin, INPUT_PULLUP);
  pinMode(buttonCCWPin, INPUT_PULLUP);
  pinMode(buttonCWPin, INPUT_PULLUP);
  pinMode(buttonSavePin, INPUT_PULLUP);
  
  digitalWrite(enablePin, LOW);  // Enable the motor driver
  digitalWrite(dirPin, HIGH);    // Set initial direction
  
  // Set microstepping mode (1/8 step)
  digitalWrite(ms1Pin, HIGH);
  digitalWrite(ms2Pin, HIGH);
  digitalWrite(ms3Pin, LOW);
  
  Serial.begin(9600);
  Serial.println("Stepper Motor Button Control Begin");
  
  // Read saved positions from EEPROM
  buttonAPosition = EEPROM.read(0) | (EEPROM.read(1) << 8);
  buttonBPosition = EEPROM.read(2) | (EEPROM.read(3) << 8);
  
  Serial.print("Button A Position: ");
  Serial.println(buttonAPosition);
  Serial.print("Button B Position: ");
  Serial.println(buttonBPosition);
  
  homeMotor();
}

void loop() {
  if (digitalRead(buttonAPin) == LOW) {
    Serial.println("Button A pressed: Moving to saved position");
    moveToDegree(buttonAPosition);
    lastButtonPressed = 1;
    delay(500);  // Debounce delay
  }
  
  if (digitalRead(buttonBPin) == LOW) {
    Serial.println("Button B pressed: Moving to saved position");
    moveToDegree(buttonBPosition);
    lastButtonPressed = 2;
    delay(500);  // Debounce delay
  }

  if (digitalRead(buttonCCWPin) == LOW) {
    Serial.println("Button CCW pressed: Moving counterclockwise");
    moveSteps(-stepsPerDegree);  // Move 1 degree CCW
    currentPosition -= 1;
    delay(100);  // Debounce delay
  }

  if (digitalRead(buttonCWPin) == LOW) {
    Serial.println("Button CW pressed: Moving clockwise");
    moveSteps(stepsPerDegree);  // Move 1 degree CW
    currentPosition += 1;
    delay(100);  // Debounce delay
  }

  if (digitalRead(buttonSavePin) == LOW) {
    Serial.println("Button Save pressed: Saving current position");
    savePosition();
    delay(500);  // Debounce delay
  }
}

void moveSteps(int steps) {
  Serial.print("Moving steps: ");
  Serial.println(steps);
  digitalWrite(dirPin, steps > 0 ?