/*
Discord | Arduino | coding-help
Falo — 1/22/24 at 2:55 PM
I'm trying to code a stepper motor and write a function that will take
0, 1 or 2 as an argument for the step mode, one phase (wave), half step,
and two phase (full step).
(Microstepping is left as an exercise. :) )
https://www.instructables.com/Controlling-Bipolar-Stepper-Motors-with-Arduino-wi/
DO NOT CONNECT THE STEPPER LIKE THIS IRL!
USE ULN2003 DRIVER FOR STEPPER WITH EXTERNAL POWER!
*/
// pin definitions
const int IN1 = 8; // B- motor pin
const int IN2 = 9; // B+ motor pin
const int IN3 = 10; // A+ motor pin
const int IN4 = 11; // A- motor pin
const int BTN_MODE = 12;
const int BTN_DIR = 13;
const int SPD_PIN = A0;
const int NUM_MODES = 3;
// pin sequences for each mode
int waveStep[][4] = {
{1, 0, 0, 0}, // 1
{0, 0, 1, 0}, // 2
{0, 1, 0, 0}, // 3
{0, 0, 0, 1}, // 4
};
int halfStep[][4] = {
{1, 0, 0, 0}, // 1
{1, 0, 1, 0}, // 2
{0, 0, 1, 0}, // 3
{0, 1, 1, 0}, // 4
{0, 1, 0, 0}, // 5
{0, 1, 0, 1}, // 6
{0, 0, 0, 1}, // 7
{1, 0, 0, 1} // 8
};
int fullStep[][4] = {
{1, 0, 1, 0}, // 1
{0, 1, 1, 0}, // 2
{0, 1, 0, 1}, // 3
{1, 0, 0, 1}, // 4
};
// misc globals
bool direction = false; // false = CW
int mode = 0; // 0= 1 phase full, 1= half step, 2= 2 phase full
int currStep = 0;
unsigned long prevMillis = 0;
bool checkDir() {
static int oldBtnState = HIGH;
int btnState = digitalRead(BTN_DIR);
if (btnState != oldBtnState) {
oldBtnState = btnState;
if (btnState == LOW) {
//Serial.println("Mode button pressed");
direction = !direction;
Serial.print("Direction: ");
Serial.println(direction ? "CCW" : "CW");
} else {
//Serial.println("Mode button released\n");
}
delay(20); // for debounce
}
return direction;
}
int checkMode() {
static int oldBtnState = HIGH;
int btnState = digitalRead(BTN_MODE);
if (btnState != oldBtnState) {
oldBtnState = btnState;
if (btnState == LOW) {
//Serial.println("Mode button pressed");
mode++;
if (mode >= NUM_MODES) mode = 0;
Serial.print("Mode: ");
Serial.println(mode);
} else {
//Serial.println("Mode button released\n");
}
delay(20); // for debounce
}
return mode;
}
void moveStepper(bool direction, int mode, int stepDelay) {
int seqLength = 0;
if (millis() - prevMillis >= stepDelay) {
prevMillis = millis();
//Serial.print("Current step: ");
//Serial.println(currStep);
switch (mode) {
case 0:
// "wave" mode, less current, less torque, 1 phase
setPins(waveStep[currStep][0], waveStep[currStep][1], waveStep[currStep][2], waveStep[currStep][3]);
seqLength = 4;
break;
case 1:
// half step, more steps, less torque, 2 phase
setPins(halfStep[currStep][0], halfStep[currStep][1], halfStep[currStep][2], halfStep[currStep][3]);
seqLength = 8;
break;
case 2:
// full step, more current, more torque, 2 phase
setPins(fullStep[currStep][0], fullStep[currStep][1], fullStep[currStep][2], fullStep[currStep][3]);
seqLength = 4;
break;
default:
break;
}
if (direction == false) {
currStep++;
if (currStep >= seqLength) currStep = 0;
} else {
currStep--;
if (currStep < 0) currStep = seqLength - 1;
}
}
}
void setPins(int a, int b, int c, int d) {
digitalWrite(IN1, a);
digitalWrite(IN2, b);
digitalWrite(IN3, c);
digitalWrite(IN4, d);
}
void setup() {
Serial.begin(9600);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(BTN_DIR, INPUT_PULLUP);
pinMode(BTN_MODE, INPUT_PULLUP);
Serial.println("Ready...\n");
Serial.print("Mode: ");
Serial.println(mode);
Serial.print("Direction: ");
Serial.println(direction ? "CCW" : "CW");
}
void loop() {
int potValue = analogRead(SPD_PIN);
int stepDelay = map(potValue, 0, 1023, 200, 0);
direction = checkDir();
mode = checkMode();
moveStepper(direction, mode, stepDelay);
}
Speed
A+
A-
B+
B-