Skip to content

Instantly share code, notes, and snippets.

@Epsilon99
Created May 12, 2014 08:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Epsilon99/2757e52e06a7d2d50221 to your computer and use it in GitHub Desktop.
Save Epsilon99/2757e52e06a7d2d50221 to your computer and use it in GitHub Desktop.
Bipolar-stepper driver (coded for Velleman VMA03 - Arduino motor and power shield)
// Initializing pins
const int pwr_a = 3;
const int pwr_b = 9;
const int dir_a = 2;
const int dir_b = 8;
// Step delay, is used as delay between each half-step, in the motor driver.
// This delay is measured in microseconds.
int stepDelay = 600;
void setup(){
// Initialize the pins, in the correct type of mode.
pinMode(pwr_a,OUTPUT);
pinMode(pwr_b,OUTPUT);
pinMode(dir_a,OUTPUT);
pinMode(dir_b,OUTPUT);
}
void loop(){
// Test loop, should make your stepper go 40 steps forewards and backwards, with 1 second delay.
Step4FWD(10);
delay(1000);
Step4BWD(10);
delay(1000);
}
// This method, is called in order to make the stepper motor make 4 steps forwards (depending on your wiring).
void Step4FWD(int NumberOfTimes){
// The function will run for the amount of times called in the method.
// This is accomplished by a while loop, where it will subtract 1 from the amount, after every run.
while(NumberOfTimes!=0){
// Starting position (if repeated, ful step (4))
// EXPLINATION: in this case, both our power are high.
// Therefore both coils are activated, with their standard polarities for their magnetic fields.
digitalWrite(pwr_a,HIGH);
digitalWrite(pwr_b,HIGH);
digitalWrite(dir_a,HIGH);
digitalWrite(dir_b,HIGH);
delayMicroseconds(stepDelay);
//Half step (½)
// EXPLINATION: In this case, only out b-coil is active, still with it's stand polarity.
digitalWrite(pwr_a,HIGH);
digitalWrite(pwr_b,LOW);
digitalWrite(dir_a,HIGH);
digitalWrite(dir_b,LOW);
delayMicroseconds(stepDelay);
//Full step (1)
// EXPLINATION: In this case, the b-coil is activated as in previous cases.
// But the a-coil now has it's direction turned on. So now it's active, but with the reversered polarity.
// By continuing this pattern (for reference: http://www.8051projects.net/stepper-motor-interfacing/full-step.gif) , you'll get the axis to turn.
digitalWrite(pwr_a,HIGH);
digitalWrite(pwr_b,HIGH);
digitalWrite(dir_a,HIGH);
digitalWrite(dir_b,LOW);
delayMicroseconds(stepDelay);
// Half step (1½)
digitalWrite(pwr_a,LOW);
digitalWrite(pwr_b,HIGH);
digitalWrite(dir_a,LOW);
digitalWrite(dir_b,LOW);
delayMicroseconds(stepDelay);
// Full step (2)
digitalWrite(pwr_a,HIGH);
digitalWrite(pwr_b,HIGH);
digitalWrite(dir_a,LOW);
digitalWrite(dir_b,LOW);
delayMicroseconds(stepDelay);
// Half step (2½)
digitalWrite(pwr_a,HIGH);
digitalWrite(pwr_b,LOW);
digitalWrite(dir_a,LOW);
digitalWrite(dir_b,LOW);
delayMicroseconds(stepDelay);
// Full step (3)
digitalWrite(pwr_a,HIGH);
digitalWrite(pwr_b,HIGH);
digitalWrite(dir_a,LOW);
digitalWrite(dir_b,HIGH);
delayMicroseconds(stepDelay);
// Half step (3½)
digitalWrite(pwr_a,LOW);
digitalWrite(pwr_b,HIGH);
digitalWrite(dir_a,LOW);
digitalWrite(dir_b,HIGH);
NumberOfTimes--;
}
TurnOfMotors();
}
// This method, is called in order to make the stepper motor make 4 steps backwards (depending on your wiring).
void Step4BWD(int NumberOfTimes){
while(NumberOfTimes!=0){
// Starting position (if repeated, ful step (4))
digitalWrite(pwr_a,HIGH);
digitalWrite(pwr_b,HIGH);
digitalWrite(dir_a,LOW);
digitalWrite(dir_b,LOW);
delayMicroseconds(stepDelay);
// Half step (½)
digitalWrite(pwr_a,LOW);
digitalWrite(pwr_b,HIGH);
digitalWrite(dir_a,LOW);
digitalWrite(dir_b,LOW);
delayMicroseconds(stepDelay);
// Full step (1)
digitalWrite(pwr_a,HIGH);
digitalWrite(pwr_b,HIGH);
digitalWrite(dir_a,HIGH);
digitalWrite(dir_b,LOW);
delayMicroseconds(stepDelay);
// Half step (1½)
digitalWrite(pwr_a,HIGH);
digitalWrite(pwr_b,LOW);
digitalWrite(dir_a,HIGH);
digitalWrite(dir_b,LOW);
delayMicroseconds(stepDelay);
// Full step (2)
digitalWrite(pwr_a,HIGH);
digitalWrite(pwr_b,HIGH);
digitalWrite(dir_a,HIGH);
digitalWrite(dir_b,HIGH);
delayMicroseconds(stepDelay);
// Half step (2½)
digitalWrite(pwr_a,LOW);
digitalWrite(pwr_b,HIGH);
digitalWrite(dir_a,LOW);
digitalWrite(dir_b,HIGH);
delayMicroseconds(stepDelay);
// Full step (3)
digitalWrite(pwr_a,HIGH);
digitalWrite(pwr_b,HIGH);
digitalWrite(dir_a,LOW);
digitalWrite(dir_b,HIGH);
delayMicroseconds(stepDelay);
// Half step (3½)
digitalWrite(pwr_a,HIGH);
digitalWrite(pwr_b,LOW);
digitalWrite(dir_a,LOW);
digitalWrite(dir_b,LOW);
NumberOfTimes--;
}
TurnOfMotors();
}
// This method simply just turn of the motors, called when ever we don't need the motors anymore.
// In this way, we won't fray the circuit or coils.
void TurnOfMotors(){
digitalWrite(pwr_a,LOW);
digitalWrite(pwr_b,LOW);
digitalWrite(dir_a,LOW);
digitalWrite(dir_b,LOW);
}
@toby-sk
Copy link

toby-sk commented Oct 1, 2014

Hi, thank you for this code.
I modified it in such way that you can drive as many half-steps forwards and backwards as you want. The Driver will also know the position of the Motor.

// Initializing pins
const int pwr_a = 3;
const int pwr_b = 9;
const int dir_a = 2;
const int dir_b = 8;

const int STEPS = 2*200;      //total count of halfsteps per full rotation (*2 for half steps!)
                              // e.g. 1.8deg stepper => 200 steps => 400 halfsteps
int currStep = 0;             //current step, corresponds to angular position,  limits: 0...STEPS
int sub = 0;                  //current halfstep within repeating sequence (8 halfsteps), limits: 0...7

int stepdelay_fast = 600;     //Wait time between steps (microseconds) - fast drive
int stepdelay_slow = 4000;    //Wait time between steps (microseconds) - slow drive


void setup()
{
  // Initialize the pins, in the correct type of mode.
    pinMode(pwr_a,OUTPUT);
    pinMode(pwr_b,OUTPUT);
    pinMode(dir_a,OUTPUT);
    pinMode(dir_b,OUTPUT);
}


void loop()
{
    subStep(50, stepdelay_slow);        //50 halfsteps forward, slow
    delay(1000);                        //wait 1 second
    subStep(-50, stepdelay_slow);       //50 halfsteps backward, slow
    delay(1000);                        //wait 1 second
    subStep(400, stepdelay_fast);       //400 halfsteps forward, fast
    delay(1000);                        //wait 1 second
    subStep(-400, stepdelay_fast);      //400 halfsteps backward, slow
    TurnOfMotors();                     //turn off motor current
    delay(10000);                       //wait 10 seconds
}


// This method is called in order to make the stepper motor make a number of sub steps (depending on your wiring).
// Variable steps is for number of steps (forwards = positive, backwards = negative)
// stepDelay is for waiting time between steps in microseconds => bigger means lower speed, smaller means higher speed

void subStep(long steps, int stepDelay){

  // The function will run for the amount of times called in the method.
  // This is accomplished by a while loop, where it will subtract 1 from the amount after every run (forwards).
  // In case of backward rotation it will add 1 to the negative number of steps until 0 is reached.

    while(steps!=0)
        {

        if(steps>0){currStep++;}       //increment current halfstep (forward)
        if(steps<0){currStep--;}       //decrement current halfstep (backward)

        if(currStep>STEPS){currStep= currStep-STEPS;}         //position >360deg is reached => set position one turn back
        if(currStep<0){currStep= currStep+STEPS;}             //position <0deg   is reached => set position one turn forward

        sub = currStep%8;           //determine the next halfstep

        switch(sub)
        {
               case 0: 
        // Starting position (if repeated, ful step (4))
        // EXPLINATION: in this case, both our power are high.
        // Therefore both coils are activated, with their standard polarities for their magnetic fields.
        digitalWrite(pwr_a,HIGH);
        digitalWrite(pwr_b,HIGH);
        digitalWrite(dir_a,HIGH);
        digitalWrite(dir_b,HIGH);
                break;

                case 1:
        //Half step (½)
        // EXPLINATION: In this case, only out b-coil is active, still with it's stand polarity.
        digitalWrite(pwr_a,HIGH);
        digitalWrite(pwr_b,LOW);
        digitalWrite(dir_a,HIGH);
        digitalWrite(dir_b,LOW);
                break;

        case 2:
                //Full step (1)
        // EXPLINATION: In this case, the b-coil is activated as in previous cases.
        // But the a-coil now has it's direction turned on. So now it's active, but with the reversered polarity.
        // By continuing this pattern (for reference: http://www.8051projects.net/stepper-motor-interfacing/full-step.gif) , you'll get the axis to turn.
        digitalWrite(pwr_a,HIGH);
        digitalWrite(pwr_b,HIGH);
        digitalWrite(dir_a,HIGH);
        digitalWrite(dir_b,LOW);
                break;

        case 3:
        // Half step (1½)
        digitalWrite(pwr_a,LOW);
        digitalWrite(pwr_b,HIGH);
        digitalWrite(dir_a,LOW);
        digitalWrite(dir_b,LOW);
                break;

        case 4:
        // Full step (2)
        digitalWrite(pwr_a,HIGH);
        digitalWrite(pwr_b,HIGH);
        digitalWrite(dir_a,LOW);
        digitalWrite(dir_b,LOW);
                break;

        case 5:
        // Half step (2½)
        digitalWrite(pwr_a,HIGH);
        digitalWrite(pwr_b,LOW);
        digitalWrite(dir_a,LOW);
        digitalWrite(dir_b,LOW);
                break;

        case 6:
        // Full step (3)
        digitalWrite(pwr_a,HIGH);
        digitalWrite(pwr_b,HIGH);
        digitalWrite(dir_a,LOW);
        digitalWrite(dir_b,HIGH);
                break;

        case 7:
        // Half step (3½)
        digitalWrite(pwr_a,LOW);
        digitalWrite(pwr_b,HIGH);
        digitalWrite(dir_a,LOW);
        digitalWrite(dir_b,HIGH);
                break;
         }

        delayMicroseconds(stepDelay);        //Waiting time to next halfstep

        if(steps>0){steps--;}      //decrement of remaining halfsteps of forward rotation
    if(steps<0){steps++;}      //increment of remaining halfsteps of backward rotation
    }
}


// This method simply just turn of the motors, called when ever we don't need the motors anymore.
// In this way, we won't fray the circuit or coils.
// Note 1: Motor has no torque anymore
// Note 2: If current position is between full steps, motor will move for a half step!
void TurnOfMotors(){
    digitalWrite(pwr_a,LOW);
    digitalWrite(pwr_b,LOW);
    digitalWrite(dir_a,LOW);
    digitalWrite(dir_b,LOW);
}

@hoefeler
Copy link

great work ... thanks a lot ... I made a arduino library based on your code.

Pls. try or/and review at https://github.com/hoefeler/VMA03

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment