Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
sbright33's Arduino stepper motor driver demo
// EDIT: ***THIS VERSION IS OBSOLETE!!***
// PLEASE SEE NEW VERSION AT https://gist.github.com/4178431
// cobbled together from http://arduino.cc/forum/index.php/topic,85335.15.html
// all work by sbright33, not me.
#define dw digitalWrite
#define dm delayMicroseconds
const int mp1 = 4; // Blue - 28BYJ48 pin 1
const int mp2 = 5; // Pink - 28BYJ48 pin 2
const int mp3 = 6; // Yellow - 28BYJ48 pin 3
const int mp4 = 7; // Orange - 28BYJ48 pin 4
// Red - 28BYJ48 pin 5 VCC
int motorSpeed = 3000; // set stepper speed
int stepnum = 0;
float err = 0;
void setup() {
pinMode(mp1, OUTPUT);
pinMode(mp2, OUTPUT);
pinMode(mp3, OUTPUT);
pinMode(mp4, OUTPUT);
//Serial.begin(115200);
}
void loop() {
//long m=millis();
//Serial.println(millis()-m);
//if(random(4)) degrpm8(random(2),9*(random(20)+2),3200); else delay(100);
//degrpmslowCool4(1,long(360)*100*5,10*60);
//for(int i=0;i<90;i++) {degrpm(1,400,800);delay(50);}
//for(int i=0;i<8;i++) degrpm8(0,4500,2400);
//revRestart(1,2,2000,4);
//does not work 5v for(int i=0;i<500;i++){move(1); off(); delay(1);}
//for(int i=0;i<500;i++){move(1); off(); delay(1);} //<5ms ok w 12v Cool4 better
degrpm(1, 180 * 100, 2000);
//ramp(1,2000);
off();
delay(500);
}
void ramp(boolean bcw, int rpm100) {
//past 1200 it ramps in cwss() also that's bad
for (int i = 50; i < 1200; i += 100) //1200 or rpm100 for <1200
degrpmEZ(bcw, 900, i); //<900deg ignores speed
revRestart(bcw, 2, rpm100, 1);
}
void revRestart(boolean bcw, long revo, int rpm100, int xinrev) {
//xinrev small only
//in case it gets stuck due to torque load spike
for (long i = 0; i < revo * xinrev; i++)
degrpm(bcw, 36000 / xinrev, rpm100);
}
void rev(boolean bcw, long revo) {
long step2 = revo * 64 * 8 - 12; //not exactly right?
int rpm100 = 500;
if (bcw) cwss(12, rpm100); //ramp up speed
else ccwss(12, rpm100);
for (long i = 0; i < step2; i++)
if (bcw) cw();
else ccw();
off();
}
void degrpmslowCool4(boolean bcw, long deg100, int rph100) {
//ccw only, more torque, less current, less heat, most efficient code for maH
//but 4x as jerky
motorSpeed = 1000;
int step2 = deg100 * 64 * 8 / 360 / 100 / 2; //rounded down
int d = long(351500) * 2 / rph100; //div 2? see stepper.xls was /2 now *2
for (int i = 0; i < step2; i++) {
ccw();
ccw();
off();
delay(d);
} //for
off();
}
void degrpmslowCool(boolean bcw, long deg100, int rph100) {
//ccw only, more torque, less current, less heat
motorSpeed = 1500; //why 1500 needed?
int step2 = deg100 * 64 * 8 / 360 / 100; //rounded down
int d = long(351500) / 2 / rph100; //div 2? see stepper.xls
for (int i = 0; i < step2; i++) {
ccw4st1();
off();
delay(d); //cools while off
ccw4st2();
off();
delay(d);
} //for
off();
}
void degrpmslowHot(boolean bcw, long deg100, int rph100) {
//ccw only, more torque, hot w 12v
motorSpeed = 1000;
int step2 = deg100 * 64 * 8 / 360 / 100; //rounded down
int d = long(351500) / 2 / rph100; //div 2? see stepper.xls
for (int i = 0; i < step2; i++) {
ccw4st1();
delay(d);
ccw4st2();
delay(d);
} //for
off();
}
void degrpmslow2(boolean bcw, long deg100, int rph100) {
//ccw only, more torque, less current, less heat, 50% duty cycle
//compromise Hot,Cool
motorSpeed = 1000; //12v
int step2 = deg100 * 64 * 8 / 360 / 100; //rounded down
int d = long(351500) / 2 / rph100; //div 2? see stepper.xls
for (int i = 0; i < step2; i++) {
ccw4st1();
off();
delay(d / 4);
st1();
delay(d / 2);
off();
delay(d / 4);
ccw4st2();
off();
delay(d / 4);
st2();
delay(d / 2);
off();
delay(d / 4);
} //for
off();
}
void degrpmEZ(boolean bcw, long deg100, int rpm100) {
//max 64 turns or 23,000 deg or 2,300,000 deg100 long is bigger
//max 3500 rpm100 with 12v
int step2 = deg100 * 64 * 8 / 360 / 100; //rounded down
if (rpm100 < 50) rpm100 = 50; //minimum should use degrpmslow()
rpm100 = long(1463600) / rpm100 - 20; //see stepper.xls
if (bcw) cwss(step2, rpm100);
else ccwss(step2, rpm100);
}
void degrpm(boolean bcw, long deg100, int rpm100) {
//max 64 turns or 23,000 deg or 2,300,000 deg100 long is bigger
//max 3500 rpm100 with 12v
int step2 = deg100 * 64 * 8 / 360 / 100; //rounded down
if (rpm100 < 50) rpm100 = 50; //minimum should use degrpmslow()
rpm100 = long(1463600) / rpm100 - 20; //see stepper.xls
if (bcw) cwss(step2, rpm100);
else ccwss(step2, rpm100);
//with this code you can step by 2.00 deg 180x will be 360+-1
//0.50 deg 720x works to 360
//even though step size is >0.50 or 0.72?
float movedeg = float(step2) * 360 / 64 / 8; //float library adds 2K size to sketch
//Serial.println(movedeg);
//Serial.println(movedeg-(float)deg100/100); //moved too little only?
//ccw4st1 can help this
err += (movedeg - (float) deg100 / 100);
if (err < -1) {
motorSpeed = 1200;
if (bcw) cw();
else ccw();
err += (float(360) / 64 / 8);
//Serial.print("err=");Serial.println(err);
} //if err
//soft stop moves further than it should
//if(bcw) cwss(15,2000);
//else ccwss(15,2000);
delay(10); //so it stops and holds before off in loop
//off();
}
void degrpm8(boolean bcw, long deg100, int rpm100) {
//max 8 turns
//max <<3500 rpm100 with 12v cuz no ramping ~17RPM
const int min2start = 1200; //700 12v, 1200 5v
int step2 = deg100 * 64 * 64 / 360 / 100; //rounded down
if (rpm100 < 50) rpm100 = 50; //minimum should use degrpmslow()
rpm100 = long(1463600) / rpm100 - 20; //see stepper.xls same SAME
motorSpeed = rpm100;
if (motorSpeed < min2start) motorSpeed = min2start;
for (int i = 0; i < step2; i++) {
if (bcw) stepnum++;
else stepnum --;
st07();
}
//was if(bcw)cwss(step2,rpm100); else ccwss(step2,rpm100);
//does not adjust for err like degrpm cuz step 0.088 or 1/11 deg
float movedeg = float(step2) * 360 / 64 / 64; //float library adds 2K size to sketch
//Serial.println(movedeg);
err += (movedeg - (float) deg100 / 100);
//Serial.println(err);
//if(err<-1) {motorSpeed=1200; if(bcw) cw(); else ccw(); err+=(float(360)/64/8);}
//off();
}
//////////////////////////////////////////////////////////////////////////////
//set pins to ULN2003 high in sequence from 1 to 4
void ccw () {
// 1
digitalWrite(mp1, HIGH);
digitalWrite(mp2, LOW);
digitalWrite(mp3, LOW);
digitalWrite(mp4, LOW);
delayMicroseconds(motorSpeed);
// 2
digitalWrite(mp1, HIGH);
digitalWrite(mp2, HIGH);
digitalWrite(mp3, LOW);
digitalWrite(mp4, LOW);
delayMicroseconds(motorSpeed);
// 3
digitalWrite(mp1, LOW);
digitalWrite(mp2, HIGH);
digitalWrite(mp3, LOW);
digitalWrite(mp4, LOW);
delayMicroseconds(motorSpeed);
// 4
digitalWrite(mp1, LOW);
digitalWrite(mp2, HIGH);
digitalWrite(mp3, HIGH);
digitalWrite(mp4, LOW);
delayMicroseconds(motorSpeed);
// 5
digitalWrite(mp1, LOW);
digitalWrite(mp2, LOW);
digitalWrite(mp3, HIGH);
digitalWrite(mp4, LOW);
delayMicroseconds(motorSpeed);
// 6
digitalWrite(mp1, LOW);
digitalWrite(mp2, LOW);
digitalWrite(mp3, HIGH);
digitalWrite(mp4, HIGH);
delayMicroseconds(motorSpeed);
// 7
digitalWrite(mp1, LOW);
digitalWrite(mp2, LOW);
digitalWrite(mp3, LOW);
digitalWrite(mp4, HIGH);
delayMicroseconds(motorSpeed);
// 8
digitalWrite(mp1, HIGH);
digitalWrite(mp2, LOW);
digitalWrite(mp3, LOW);
digitalWrite(mp4, HIGH);
delayMicroseconds(motorSpeed);
}
//////////////////////////////////////////////////////////////////////////////
//set pins to ULN2003 high in sequence from 4 to 1
void cw() {
// 1
digitalWrite(mp4, HIGH);
digitalWrite(mp3, LOW);
digitalWrite(mp2, LOW);
digitalWrite(mp1, LOW);
delayMicroseconds(motorSpeed);
// 2
digitalWrite(mp4, HIGH);
digitalWrite(mp3, HIGH);
digitalWrite(mp2, LOW);
digitalWrite(mp1, LOW);
delayMicroseconds(motorSpeed);
// 3
digitalWrite(mp4, LOW);
digitalWrite(mp3, HIGH);
digitalWrite(mp2, LOW);
digitalWrite(mp1, LOW);
delayMicroseconds(motorSpeed);
// 4
digitalWrite(mp4, LOW);
digitalWrite(mp3, HIGH);
digitalWrite(mp2, HIGH);
digitalWrite(mp1, LOW);
delayMicroseconds(motorSpeed);
// 5
digitalWrite(mp4, LOW);
digitalWrite(mp3, LOW);
digitalWrite(mp2, HIGH);
digitalWrite(mp1, LOW);
delayMicroseconds(motorSpeed);
// 6
digitalWrite(mp4, LOW);
digitalWrite(mp3, LOW);
digitalWrite(mp2, HIGH);
digitalWrite(mp1, HIGH);
delayMicroseconds(motorSpeed);
// 7
digitalWrite(mp4, LOW);
digitalWrite(mp3, LOW);
digitalWrite(mp2, LOW);
digitalWrite(mp1, HIGH);
delayMicroseconds(motorSpeed);
// 8
digitalWrite(mp4, HIGH);
digitalWrite(mp3, LOW);
digitalWrite(mp2, LOW);
digitalWrite(mp1, HIGH);
delayMicroseconds(motorSpeed);
}
void move(boolean bcw) {
motorSpeed = 1200;
if (bcw) stepnum++;
else stepnum --;
st07();
}
void ccwss(int steps, int speed) {
//900 self starting 5v motor 5v ps
//800 most of 100% torque
//700 less torque
//600 almost none
//5v motor 12v supply:
//700 self starting
//400 decent torque
//6.6v 20RPM
//8.3v load 8.5v float 6x NiMh
//20RPM strong 28RPM weak
//15RPM 100% torque
//does not overheat
//5V 10RPM strong
//5V 20RPM weak
//5V 24RPM no torque
//12V 20RPM self start 35 max speed
//if(speed<700) steps-=10;
//ramp up speed
motorSpeed = 1000; //<12 steps, 800 for 12v
if (steps >= 12) {
motorSpeed = 3000;
if (speed < 1200) {
ccw();
ccw();
steps -= 2;
}
motorSpeed = 1200;
if (speed < 1200) {
ccw();
ccw();
steps -= 2;
}
motorSpeed = 800;
if (speed < 800) {
ccw();
ccw();
steps -= 2;
}
motorSpeed = 700;
if (speed < 700) for (int i = 0; i < 4; i++) {
ccw();
steps --;
}
motorSpeed = speed;
} //if
for (int i = 0; i < steps; i++) ccw(); //64*8 is 1 rev
}
void cwss(int steps, int speed) {
motorSpeed = 1000; //<12 steps, 800 for 12v
if (steps >= 12) {
motorSpeed = 3000;
if (speed < 1200) {
cw();
cw();
steps -= 2;
}
motorSpeed = 1200;
if (speed < 1200) {
cw();
cw();
steps -= 2;
}
motorSpeed = 800;
if (speed < 800) {
cw();
cw();
steps -= 2;
}
motorSpeed = 700;
if (speed < 700) for (int i = 0; i < 4; i++) {
cw();
steps --;
}
motorSpeed = speed;
} //if
for (int i = 0; i < steps; i++) cw(); //64*8 is 1 rev
}
void ccw4st1() {
// 1
dw(mp1, HIGH);
dw(mp2, LOW);
dw(mp3, LOW);
dw(mp4, LOW);
dm(motorSpeed);
// 2
dw(mp1, HIGH);
dw(mp2, HIGH);
dw(mp3, LOW);
dw(mp4, LOW);
dm(motorSpeed);
// 3
dw(mp1, LOW);
dw(mp2, HIGH);
dw(mp3, LOW);
dw(mp4, LOW);
dm(motorSpeed);
// 4
dw(mp1, LOW);
dw(mp2, HIGH);
dw(mp3, HIGH);
dw(mp4, LOW);
dm(motorSpeed);
}
void st1() {
dw(mp1, LOW);
dw(mp2, HIGH);
dw(mp3, HIGH);
dw(mp4, LOW);
}
void ccw4st2() {
// 5
dw(mp1, LOW);
dw(mp2, LOW);
dw(mp3, HIGH);
dw(mp4, LOW);
dm(motorSpeed);
// 6
dw(mp1, LOW);
dw(mp2, LOW);
dw(mp3, HIGH);
dw(mp4, HIGH);
dm(motorSpeed);
// 7
dw(mp1, LOW);
dw(mp2, LOW);
dw(mp3, LOW);
dw(mp4, HIGH);
dm(motorSpeed);
// 8
dw(mp1, HIGH);
dw(mp2, LOW);
dw(mp3, LOW);
dw(mp4, HIGH);
dm(motorSpeed);
}
void st2() {
dw(mp1, HIGH);
dw(mp2, LOW);
dw(mp3, LOW);
dw(mp4, HIGH);
}
void off() {
dw(mp1, LOW);
dw(mp2, LOW);
dw(mp3, LOW);
dw(mp4, LOW);
}
void st07() {
if (stepnum == -1) stepnum = 7;
if (stepnum == 8) stepnum = 0;
switch (stepnum) {
case 0:
dw(mp4, HIGH);
dw(mp3, LOW);
dw(mp2, LOW);
dw(mp1, LOW);
dm(motorSpeed);
break;
case 1:
dw(mp4, HIGH);
dw(mp3, HIGH);
dw(mp2, LOW);
dw(mp1, LOW);
dm(motorSpeed);
break;
case 2:
dw(mp4, LOW);
dw(mp3, HIGH);
dw(mp2, LOW);
dw(mp1, LOW);
dm(motorSpeed);
break;
case 3:
dw(mp4, LOW);
dw(mp3, HIGH);
dw(mp2, HIGH);
dw(mp1, LOW);
dm(motorSpeed);
break;
case 4:
dw(mp4, LOW);
dw(mp3, LOW);
dw(mp2, HIGH);
dw(mp1, LOW);
dm(motorSpeed);
break;
case 5:
dw(mp4, LOW);
dw(mp3, LOW);
dw(mp2, HIGH);
dw(mp1, HIGH);
dm(motorSpeed);
break;
case 6:
dw(mp4, LOW);
dw(mp3, LOW);
dw(mp2, LOW);
dw(mp1, HIGH);
dm(motorSpeed);
break;
case 7:
dw(mp4, HIGH);
dw(mp3, LOW);
dw(mp2, LOW);
dw(mp1, HIGH);
dm(motorSpeed);
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.