Stepper Motor control 'delay()' problem

I hooked my Arduino up to a duel H-Bridge (SN754410) which was connected to a bipolar stepper motor and then hooked up 3 buttons to the board and wrote some code to run everything (there is also some left over code from the LED button program so I know when my board is ready for input)

One button spins the motor forward, and another spins it backward. As you spin the motor with these buttons the program counts the steps. Whenever your ready you can press the third button which rewinds the motor to it's original position and resets the step counter (stepsTaken). The code works fine the way I have it written but there are some things I am not satisfied with.

But first here's the code:

//  Chris' Stepper Moter functions
//  June 22, 2007 

int theDelay = 5;
int inPinA = 7;
int inPinB = 8;
int inRWD = 9;
int ledPin = 13;
int buttonA = 0;
int buttonB = 0;
int buttonRWD = 0;
int stepsTaken = 0;

// Turns motor off
void motorOff(int pin1A, int pin1B, int pin2A, int pin2B) {
    digitalWrite(pin1A, LOW);
    digitalWrite(pin1B, LOW);
    digitalWrite(pin2A, LOW);
    digitalWrite(pin2B, LOW);
}
  
void pulse1(int pin1A, int pin1B, int pin2A, int pin2B) {
  digitalWrite(pin1B, LOW);
  digitalWrite(pin2A, LOW);
  digitalWrite(pin1A, HIGH);
  digitalWrite(pin2B, HIGH);
  delay(theDelay);
}
void pulse2(int pin1A, int pin1B, int pin2A, int pin2B) {
  digitalWrite(pin1B, LOW);
  digitalWrite(pin2B, LOW);
  digitalWrite(pin2A, HIGH);
  digitalWrite(pin1A, HIGH);
  delay(theDelay);
}
void pulse3(int pin1A, int pin1B, int pin2A, int pin2B) {
  digitalWrite(pin1A, LOW);
  digitalWrite(pin2B, LOW);
  digitalWrite(pin1B, HIGH);
  digitalWrite(pin2A, HIGH);
  delay(theDelay);
}
void pulse4(int pin1A, int pin1B, int pin2A, int pin2B) {
  digitalWrite(pin1A, LOW);
  digitalWrite(pin2A, LOW);
  digitalWrite(pin2B, HIGH);
  digitalWrite(pin1B, HIGH);
  delay(theDelay);
}

// This function spins a motor
// 'turns' is the number of steps to be taken
// and 'direction' controls the derection of the step
// 'pin1a' through 'pin2b' tell the function which motor to spin
void spin( int turns, boolean direction, int pin1A, int pin1B, int pin2A, int pin2B) {

  int counter = 0;    // used to count what pulse the step is on
  
  // stepping takes four pulses and if done turn counting function will end
  while(turns > 0) {
    while (counter < 4){
    
      if (direction){    // checks direction
        switch(counter){
          case 0:  pulse1(pin1A, pin1B, pin2A, pin2B);
          case 1:  pulse2(pin1A, pin1B, pin2A, pin2B);
          case 2:  pulse3(pin1A, pin1B, pin2A, pin2B);
          case 3:  pulse4(pin1A, pin1B, pin2A, pin2B);
        }
      }
      else{    // revers direction stepping
        switch(counter){
          case 0:  pulse4(pin1A, pin1B, pin2A, pin2B);
          case 1:  pulse3(pin1A, pin1B, pin2A, pin2B);
          case 2:  pulse2(pin1A, pin1B, pin2A, pin2B);
          case 3:  pulse1(pin1A, pin1B, pin2A, pin2B);
        }
      }
      ++counter;    // sets counter up for next part of the step
    }
     --turns;    // counts off one turn
    counter = 0;    // resets stepping pulse counter
  }
  motorOff(pin1A, pin1B, pin2A, pin2B);    // turns motor off
};

void setup()
{
  pinMode(inPinA, INPUT);
  pinMode(inPinB, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(inRWD, INPUT);
  
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
}



void loop()
{
  buttonA = digitalRead(inPinA);  // read input value
  buttonB = digitalRead(inPinB);
  
  if (buttonA == HIGH) {    // check if the input is HIGH (button released)
    digitalWrite(ledPin, LOW);    // turn LED OFF
    spin(1, 0, 2, 3, 4, 5);    // Moves Moter forward
    ++stepsTaken;
  } else {
    digitalWrite(ledPin, HIGH);    // turn LED ON
  }
  
  if (buttonB == HIGH && buttonA == LOW) {    // check if the input is HIGH (button released)
    digitalWrite(ledPin, LOW);    // turn LED OFF
    spin(1, 1, 2, 3, 4, 5);    // Moves motor backword
    --stepsTaken;
  } else {
    digitalWrite(ledPin, HIGH);    // turn LED ON
  }
  
  buttonRWD = digitalRead(inRWD);    // reads rewind switch
  
  
  // as you move the motor back and forth it records the number of steps you take
  // pressing rewind will move the motor in the opisate direction to the place you started
  if (buttonRWD == HIGH && stepsTaken != 0 ) {
    if(stepsTaken > 0) {
      digitalWrite(ledPin, LOW);    // turn LED OFF
      spin(stepsTaken, 1, 2, 3, 4, 5);
    } else {
      stepsTaken *= -1;
      spin(stepsTaken, 0, 2, 3, 4, 5);
    }
    delay(500);
    stepsTaken = 0;
  } else {
    digitalWrite(ledPin, HIGH);    // turn LED ON
  }
}

You will note that the functions pulse1, pulse2, pulse3, and pulse4 all have the line delay(theDelay); in them. This is fine when you are controlling one motor but if I wanted to control more then one motor it would pause the whole program while it sets up the current direction on one motor.

When I run the delay after

if (direction){    // checks direction
      bla bla bla...
}
else{    // revers direction stepping
      bla bla bla...
}

in the spin() function it does not run, why does the delay have to be in the same function, I don't really understand this

Yeah, what is the better way of doing this? Isn't there a tutorial somewhere that mentioned a non-delay solution?

Hello together,

you just need to modify the code a bit:

First set the pin of all motors, then delay. So that, all motors are running synchroneously.

Greetings
Nicolas

Does this help? Blink Without delay()