/*
28BYJ-48 Stepper Motor Control with ULN2003 Driver
===================================================
Complete stepper motor control with multiple modes and directions
Hardware:
- Arduino Uno
- 28BYJ-48 5V Stepper Motor
- ULN2003 Driver Board
- Push Buttons for control
Features:
- Forward/Reverse rotation
- Variable speed control
- Step count display
- Multiple control modes
- Serial command interface
Author: Arduino Project
Date: 2024
*/
#include <Stepper.h>
// Motor specifications for 28BYJ-48
// Steps per revolution (full step mode)
#define STEPS_PER_REV 2048 // 28BYJ-48 has gear ratio of 64:1, 32 steps * 64 = 2048
// Pin definitions for ULN2003 driver (IN1, IN2, IN3, IN4)
#define IN1 8
#define IN2 9
#define IN3 10
#define IN4 11
// Button pins
#define BTN_FORWARD 2
#define BTN_REVERSE 3
#define BTN_SPEED_UP 4
#define BTN_SPEED_DOWN 5
#define BTN_STOP 6
// LED indicators
#define LED_FORWARD 12
#define LED_REVERSE 13
// Initialize stepper library
Stepper myStepper(STEPS_PER_REV, IN1, IN3, IN2, IN4);
// Control variables
int motorSpeed = 10; // RPM (5-15 recommended for 28BYJ-48)
int currentPosition = 0; // Track motor position
bool motorRunning = false;
int direction = 1; // 1 = forward, -1 = reverse
unsigned long stepCount = 0;
// Button state variables
bool lastBtnForward = HIGH;
bool lastBtnReverse = HIGH;
bool lastBtnSpeedUp = HIGH;
bool lastBtnSpeedDown = HIGH;
bool lastBtnStop = HIGH;
void setup() {
// Initialize serial communication
Serial.begin(9600);
Serial.println("========================================");
Serial.println(" 28BYJ-48 Stepper Motor Controller");
Serial.println("========================================");
Serial.println();
// Set button pins as input with pullup
pinMode(BTN_FORWARD, INPUT_PULLUP);
pinMode(BTN_REVERSE, INPUT_PULLUP);
pinMode(BTN_SPEED_UP, INPUT_PULLUP);
pinMode(BTN_SPEED_DOWN, INPUT_PULLUP);
pinMode(BTN_STOP, INPUT_PULLUP);
// Set LED pins as output
pinMode(LED_FORWARD, OUTPUT);
pinMode(LED_REVERSE, OUTPUT);
// Set initial motor speed
myStepper.setSpeed(motorSpeed);
// Turn off LEDs
digitalWrite(LED_FORWARD, LOW);
digitalWrite(LED_REVERSE, LOW);
// Display instructions
printInstructions();
}
void loop() {
// Check button inputs
checkButtons();
// Check serial commands
checkSerialCommands();
// Run motor if active
if (motorRunning) {
myStepper.step(direction);
stepCount++;
currentPosition += direction;
// Display status every 100 steps
if (stepCount % 100 == 0) {
displayStatus();
}
}
delay(1); // Small delay for stability
}
void checkButtons() {
// Forward button
bool btnForward = digitalRead(BTN_FORWARD);
if (btnForward == LOW && lastBtnForward == HIGH) {
delay(50); // Debounce
if (digitalRead(BTN_FORWARD) == LOW) {
rotateForward();
}
}
lastBtnForward = btnForward;
// Reverse button
bool btnReverse = digitalRead(BTN_REVERSE);
if (btnReverse == LOW && lastBtnReverse == HIGH) {
delay(50);
if (digitalRead(BTN_REVERSE) == LOW) {
rotateReverse();
}
}
lastBtnReverse = btnReverse;
// Speed up button
bool btnSpeedUp = digitalRead(BTN_SPEED_UP);
if (btnSpeedUp == LOW && lastBtnSpeedUp == HIGH) {
delay(50);
if (digitalRead(BTN_SPEED_UP) == LOW) {
increaseSpeed();
}
}
lastBtnSpeedUp = btnSpeedUp;
// Speed down button
bool btnSpeedDown = digitalRead(BTN_SPEED_DOWN);
if (btnSpeedDown == LOW && lastBtnSpeedDown == HIGH) {
delay(50);
if (digitalRead(BTN_SPEED_DOWN) == LOW) {
decreaseSpeed();
}
}
lastBtnSpeedDown = btnSpeedDown;
// Stop button
bool btnStop = digitalRead(BTN_STOP);
if (btnStop == LOW && lastBtnStop == HIGH) {
delay(50);
if (digitalRead(BTN_STOP) == LOW) {
stopMotor();
}
}
lastBtnStop = btnStop;
}
void checkSerialCommands() {
if (Serial.available() > 0) {
char command = Serial.read();
switch (command) {
case 'F':
case 'f':
rotateForward();
break;
case 'R':
case 'r':
rotateReverse();
break;
case 'S':
case 's':
stopMotor();
break;
case '+':
increaseSpeed();
break;
case '-':
decreaseSpeed();
break;
case '1':
rotate90Degrees();
break;
case '2':
rotate180Degrees();
break;
case '3':
rotate360Degrees();
break;
case 'H':
case 'h':
printInstructions();
break;
case 'I':
case 'i':
displayStatus();
break;
case 'Z':
case 'z':
resetPosition();
break;
}
}
}
void rotateForward() {
motorRunning = true;
direction = 1;
digitalWrite(LED_FORWARD, HIGH);
digitalWrite(LED_REVERSE, LOW);
Serial.println(">>> FORWARD ROTATION <<<");
Serial.print("Speed: ");
Serial.print(motorSpeed);
Serial.println(" RPM");
Serial.println();
}
void rotateReverse() {
motorRunning = true;
direction = -1;
digitalWrite(LED_FORWARD, LOW);
digitalWrite(LED_REVERSE, HIGH);
Serial.println(">>> REVERSE ROTATION <<<");
Serial.print("Speed: ");
Serial.print(motorSpeed);
Serial.println(" RPM");
Serial.println();
}
void stopMotor() {
motorRunning = false;
digitalWrite(LED_FORWARD, LOW);
digitalWrite(LED_REVERSE, LOW);
Serial.println(">>> MOTOR STOPPED <<<");
Serial.print("Total steps: ");
Serial.println(stepCount);
Serial.println();
}
void increaseSpeed() {
if (motorSpeed < 15) {
motorSpeed++;
myStepper.setSpeed(motorSpeed);
Serial.print("Speed increased to: ");
Serial.print(motorSpeed);
Serial.println(" RPM");
} else {
Serial.println("Maximum speed reached (15 RPM)");
}
}
void decreaseSpeed() {
if (motorSpeed > 1) {
motorSpeed--;
myStepper.setSpeed(motorSpeed);
Serial.print("Speed decreased to: ");
Serial.print(motorSpeed);
Serial.println(" RPM");
} else {
Serial.println("Minimum speed reached (1 RPM)");
}
}
void rotate90Degrees() {
int steps = STEPS_PER_REV / 4;
Serial.println("Rotating 90 degrees...");
myStepper.step(steps);
currentPosition += steps;
stepCount += steps;
Serial.println("90 degree rotation complete!");
Serial.println();
}
void rotate180Degrees() {
int steps = STEPS_PER_REV / 2;
Serial.println("Rotating 180 degrees...");
myStepper.step(steps);
currentPosition += steps;
stepCount += steps;
Serial.println("180 degree rotation complete!");
Serial.println();
}
void rotate360Degrees() {
Serial.println("Rotating 360 degrees (full rotation)...");
myStepper.step(STEPS_PER_REV);
currentPosition += STEPS_PER_REV;
stepCount += STEPS_PER_REV;
Serial.println("Full rotation complete!");
Serial.println();
}
void resetPosition() {
currentPosition = 0;
stepCount = 0;
Serial.println("Position counter reset to zero");
Serial.println();
}
void displayStatus() {
Serial.println("=== Motor Status ===");
Serial.print("Running: ");
Serial.println(motorRunning ? "YES" : "NO");
Serial.print("Direction: ");
Serial.println(direction == 1 ? "FORWARD" : "REVERSE");
Serial.print("Speed: ");
Serial.print(motorSpeed);
Serial.println(" RPM");
Serial.print("Position: ");
Serial.print(currentPosition);
Serial.println(" steps");
Serial.print("Total steps: ");
Serial.println(stepCount);
float rotations = (float)currentPosition / STEPS_PER_REV;
Serial.print("Rotations: ");
Serial.println(rotations, 2);
Serial.println("===================");
Serial.println();
}
void printInstructions() {
Serial.println("BUTTON CONTROLS:");
Serial.println(" Button 1 - Forward Rotation");
Serial.println(" Button 2 - Reverse Rotation");
Serial.println(" Button 3 - Increase Speed");
Serial.println(" Button 4 - Decrease Speed");
Serial.println(" Button 5 - Stop Motor");
Serial.println();
Serial.println("SERIAL COMMANDS:");
Serial.println(" F/f - Forward rotation");
Serial.println(" R/r - Reverse rotation");
Serial.println(" S/s - Stop motor");
Serial.println(" + - Increase speed");
Serial.println(" - - Decrease speed");
Serial.println(" 1 - Rotate 90 degrees");
Serial.println(" 2 - Rotate 180 degrees");
Serial.println(" 3 - Rotate 360 degrees");
Serial.println(" I/i - Display status");
Serial.println(" Z/z - Reset position counter");
Serial.println(" H/h - Show this help");
Serial.println();
Serial.println("Ready for commands!");
Serial.println("========================================");
Serial.println();
}
Comments
Post a Comment