Maker Pro
Maker Pro

Arduino stepper code for ULN2003

BitHead

Mar 2, 2012
34
Joined
Mar 2, 2012
Messages
34
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.
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:

KrisBlueNZ

Sadly passed away in 2015
Nov 28, 2011
8,393
Joined
Nov 28, 2011
Messages
8,393
You can use the vBulletin CODE and /CODE tags (with square brackets around them which I can't show within this post, obviously) to delimit a block of code in your posts. This shows it in a monospaced font, in a box, without stripping the whitespace.
Code:
Here
     is
        some
             code
 

BitHead

Mar 2, 2012
34
Joined
Mar 2, 2012
Messages
34
Ah-ha! Fixed one quirk - made another!
The check for COIL1 and COIL2 = 0 because the program had not used this routine since it powered up - followed by their initialization as in...

if ((COILS1&COILS2)==0){ if (dir==0) {COILS1=0x01;COILS2=0x01;} else {COILS1=0x08; COILS2=0x08;} } //fix first-run quirks

seems to mess up single little half-steps.
It's the `AND' thing. It should be 'OR' - as in...

if ( (COILS1 | COILS2) ==0) { if (dir==0) {COILS1=0x01;COILS2=0x01;} else {COILS1=0x08; COILS2=0x08;} }

I probably meant to do "if ((COILS1==0) && (COILS2==0)) {.." but then thought I didn't have to - and left the AND in there.

Like my sailing buddy once said as we slid off the deck of his catamaran when he turned it so as to make the top of the mast head for the water - "I'm a sailor - doesn't mean I'm a good sailor."
I replace `sailor' with `programmer'. :)
 
Top