So my effort is not completely wasted ( See "!WARNING! Cheap stepper motor on eBay" in the General Electronics Chat. ) , allow me to share my compact little stepper motor 1/2 step driver routine.
There IS one remaining quirk - if you can call it that. The very first time it's run after boot-up it will begin by energizing two coils - which is OK by me 'cause it gets it moving better. Play with the COILS1,COILS2 init values if it bugs you.
Enjoy!
PS. Feel free to reply with cudos or your improvments.
PSS. Three speed steps not really needed to avoid losing steps - so I made the first one REALLY slow - so you can watch the LEDs move - then go fast.
Code:
First, init a global array...
MOTOR[]={4,5,6,7}; //with your favorite pin numbers.
//------------------------------------------------------------------------------------------------------------------------------
//This function uses two `chasing' ring counters OR'd to make the coil on/off bits
//and achieve 1/2 step resolution AND it does a pretty good job of not losing steps.
// It also has a psuedo ramp up/down speed feature
// ----------------------- Written by Marlyn Anderson aka BitHead -----------------------------------
void stepit(byte dir, unsigned long steps) { byte COIL4; //The four coil ON/OFF bits0-3
static byte COILS1; static byte COILS2; static byte laststep; static byte lastdir;
// steps5,10 variables are for comparing near the end of the steps (quicker than math. )
unsigned long steps5; if (steps>5) {steps5=steps-5;} else {steps5=1;} //first/last 5 go slowest
unsigned long steps10; if (steps>10) {steps10=steps-10;} else {steps10=1;}//5->10 and end-5->10 go slower
if ((dir^lastdir)==1) {laststep++;} lastdir=dir; //account for direction changes
if ((COILS1&COILS2)==0){ if (dir==0) {COILS1=0x01;COILS2=0x01;} else {COILS1=0x08; COILS2=0x08;} } //fix first-run quirks
for (unsigned long i=0;i<steps;i++) {
if (bitRead(laststep,0)==0) { //even numbered laststeps
if (dir==0) {COILS1=COILS1 << 1;} else {COILS1=COILS1 >> 1;}
if ((COILS1&0x0F)==0){ if (dir==0) {COILS1=0x01;} else {COILS1=0x08;} } }
else { //odd numbered 1/2 steps
if (dir==0) {COILS2=COILS2 << 1;} else {COILS2=COILS2 >> 1;}
if ((COILS2&0x0F)==0){ if (dir==0) {COILS2=0x01;} else {COILS2=0x08;} } }
laststep++;
COIL4=( COILS1 | COILS2 );
for (byte k=0;k<4;k++) {digitalWrite(MOTOR[k],bitRead(COIL4,k));} //update coil states
if ((i<5) || (i>steps5)) {delay(100);}
else if ((i<10) || (i>steps10)) {delay(3);}
else {delay(1);}
} //for (byte k=0;k<4;k++) {digitalWrite(MOTOR[k],0);} //turn them off ?
} // EO_ stepit ----------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------
There IS one remaining quirk - if you can call it that. The very first time it's run after boot-up it will begin by energizing two coils - which is OK by me 'cause it gets it moving better. Play with the COILS1,COILS2 init values if it bugs you.
Enjoy!
PS. Feel free to reply with cudos or your improvments.
PSS. Three speed steps not really needed to avoid losing steps - so I made the first one REALLY slow - so you can watch the LEDs move - then go fast.
Last edited: