Arduino-Controlled Stepper Motor with A4988 Driver and EEPROM Position Saving
View and Edit Project In Cirkit Designer
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)
- Description: A module to drive a bipolar stepper motor.
- Pins: ENABLE, MS1, MS2, MS3, RESET, SLEEP, STEP, DIR, VMOT, GND, 2B, 2A, 1A, 1B, VDD
Ceramic Capacitors
- Description: Capacitors used for noise reduction and decoupling.
- Capacitance: 100 nF (0.0000001 Farads)
Electrolytic Capacitors
- Description: Capacitors used for power supply filtering.
- Capacitance: 2.2 mF (0.0022 Farads) and 220 µF (0.00022 Farads)
LED: Two Pin (red)
- Description: A red LED for indication purposes.
Resistor
- Description: Resistors used for current limiting.
- Resistance: 200 Ohms
ams1117 3.3
- Description: A voltage regulator to provide a stable 3.3V output.
Tantalum Capacitor
- Description: A capacitor for voltage regulation stability.
- Capacitance: 10 µF (0.00001 Farads)
Diode
- Description: A diode used for reverse voltage protection.
Stepper Motor (Bipolar)
- Description: A bipolar stepper motor for precise motion control.
5V PSU
- Description: A power supply unit providing 5V.
Pushbutton
- Description: Buttons used for user input.
Rotary Encoder with Knob
- Description: An input device for user control, providing both rotation and pushbutton functionality.
Arduino UNO
- Description: A microcontroller board based on the ATmega328P.
OLED Display (128x32)
- Description: A small display for outputting text and graphics.
Wiring Details
A4988 Stepper Motor Driver (Red)
- ENABLE connected to Arduino UNO D6
- MS1 connected to Arduino UNO D7
- MS2 connected to Arduino UNO D8
- MS3 connected to Arduino UNO D9
- RESET connected to SLEEP
- SLEEP connected to RESET
- STEP connected to Arduino UNO D11
- DIR connected to Arduino UNO D12
- VMOT connected to 5V PSU 5V+ through a 200 Ohm resistor
- GND connected to system ground
- 2B connected to Stepper Motor C
- 2A connected to Stepper Motor D
- 1A connected to Stepper Motor B
- 1B connected to Stepper Motor A
- VDD connected to ams1117 3.3 OUT
Ceramic Capacitors
- All ceramic capacitors have one pin connected to system ground and the other pin connected to a power line (VDD or VMOT) for decoupling.
Electrolytic Capacitors
- All electrolytic capacitors have the negative pin connected to system ground and the positive pin connected to a power line (VMOT) for filtering.
LED: Two Pin (red)
- Cathode connected to system ground
- Anode connected to a 200 Ohm resistor
Resistor
- One resistor is connected between the anode of the red LED and the system ground.
- Another resistor is connected between VMOT of the A4988 and the 5V PSU 5V+.
ams1117 3.3
- VIN connected to 5V PSU 5V+
- OUT connected to A4988 VDD
- GND connected to system ground
Tantalum Capacitor
- Negative pin connected to system ground
- Positive pin connected to 5V PSU 5V+
Diode
- Cathode connected to Arduino UNO Vin
- Anode connected to system ground
Stepper Motor (Bipolar)
- A connected to A4988 1B
- B connected to A4988 1A
- C connected to A4988 2B
- D connected to A4988 2A
5V PSU
- 5V+ connected to VMOT of A4988 and VIN of ams1117 3.3
- GND connected to system ground
Pushbuttons
- Each pushbutton has one pin connected to system ground and another pin connected to a designated Arduino UNO digital pin.
Rotary Encoder with Knob
- Connected to Arduino UNO A0 and A1 for rotation detection.
OLED Display (128x32)
- VCC connected to Arduino UNO 5V
- GND connected to system ground
- SDA connected to Arduino UNO A4
- SCL connected to Arduino UNO A5
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 ?