Connect with us

Arduino stepper code for ULN2003

Discussion in 'Microcontrollers, Programming and IoT' started by BitHead, Nov 15, 2013.

Scroll to continue with content
  1. BitHead


    Mar 2, 2012
    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.
    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;} } }
        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.


    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: Nov 17, 2013
  2. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    Nov 28, 2011
    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.
  3. BitHead


    Mar 2, 2012
    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'. :)
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day