Stepper Motor Control Help Please

Hi all. I’m new to this forum and the world of Arduino and coding.

I’m trying to write a code that will control a stepper motor, clockwise when 1 input is low and anticlockwise when another input goes low.

I can get it to work in either direction but when i put the code in for both directions they conflict and the motor just vibrates.

I’m sure there will be an easy answer to this but it eludes me. Please someone help.

This the code I have

int myCounter = 0;
int mySwitchPin =4; 
int mySwitchPin1 =0;
int motorPin1 = 14;
int motorPin2 = 12;
int motorPin3 = 13;
int motorPin4 = 15;
int delayTime = 2;



void setup() {
 Serial.begin(115200);

 pinMode(mySwitchPin, INPUT_PULLUP);
 pinMode(mySwitchPin1, INPUT_PULLUP);
 pinMode(motorPin1, OUTPUT);
 pinMode(motorPin2, OUTPUT);
 pinMode(motorPin3, OUTPUT);
 pinMode(motorPin4, OUTPUT);
}

void loop(){
clockwise();
anticlockwise(); 
 
 }

void clockwise(){

    if(myCounter<510){   //PIN 4 PIN1 0
  digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, HIGH);
 delay(delayTime);
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, HIGH);
 digitalWrite(motorPin4, LOW);
 delay(delayTime);
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, HIGH);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
 delay(delayTime);
 digitalWrite(motorPin1, HIGH);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
 delay(delayTime);
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
 delay(1);
 
   myCounter = myCounter + 1;
 }
  else if(digitalRead(mySwitchPin ) == LOW) {   //PIN 4 PIN1 0
   myCounter = 0;
 }
}


void anticlockwise(){

    if(myCounter<510){   //PIN 4 PIN1 0
   digitalWrite(motorPin1, HIGH);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
 delay(delayTime);
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, HIGH);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
 delay(delayTime);
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, HIGH);
 digitalWrite(motorPin4, LOW);
 delay(delayTime);
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, HIGH);
 delay(delayTime);
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
 delay(1);
 
   myCounter = myCounter + 1;
 }
  else if(digitalRead(mySwitchPin1 ) == LOW) {   //PIN 4 PIN1 0
   myCounter = 0;
 }
}

Thanks.

Pin 0 is used by Serial. Pick a different pin for mySwitchPin1.

Are you using an Arduino UNO (or equivalent)? You should use the name (A0) instead of the number (14) for the A0 pin.

Your clockwise() and anticlockwise() functions always take four steps and only check the buttons if the counter has reached 510 or higher. If you call them both each time through loop() the motor will take four steps forward and four steps back. You should probably have a variable to keep track of which direction you want to go and only call the function for that direction.

What is supposed to happen if both buttons are pressed or if the other button is pressed before the 510 calls?

You must not power down a stepper or it will lose position - you are writing all low to the stepper
phases for a millisecond which seems pointless.

There are several libraries to make driving steppers easier, Stepper, AccelStepper, and others.

Thanks guys.

I will change the pins as you have instructed John. Only calling one function at a time was what I was trying to achieve but seemingly have failed at.

I want the motor to rotate clockwise 1 turn (510 count) when the button 'mySwitchPin' is pressed, pressing the button again during this rotation or pressing 'mySwitchPin1' should have no affect on the motor. then turn anticlockwise when 'mySwitchPin1' is pressed, again during the rotation pressing either button should have no effect on the motor.

using a rocker will not allow both switches to be pressed together.

A variable is probably the answer but beyond my capabilities at present.

Mark, I put the all low at the end of the sequence as the 2 of the leds on the driver board was staying constantly lit when the sequence was finished. I didn't know if this affected the motor in any way. This can be removed if it's not needed.

Thanks again.

Since you don’t want anything to interrupt the motion you can use a simple ‘for’ loop to count off 510 steps:

void clockwise()
{
  for (int i = 0; i < 510; i++)
  {
    digitalWrite(motorPin1, LOW);
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, LOW);
    digitalWrite(motorPin4, HIGH);
    delay(delayTime);
    digitalWrite(motorPin1, LOW);
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, HIGH);
    digitalWrite(motorPin4, LOW);
    delay(delayTime);
    digitalWrite(motorPin1, LOW);
    digitalWrite(motorPin2, HIGH);
    digitalWrite(motorPin3, LOW);
    digitalWrite(motorPin4, LOW);
    delay(delayTime);
    digitalWrite(motorPin1, HIGH);
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, LOW);
    digitalWrite(motorPin4, LOW);
    delay(delayTime);
  }
}

Then just call the function when the input is LOW:

void loop()
{
  if (digitalRead(mySwitchPin) == LOW)
    clockwise();
    
  if (digitalRead(mySwitchPin1) == LOW)
    anticlockwise();
}

Thanks John, that was exactly what I was looking for.

just to push my look if I wanted to introduce either a limit switch or even a potentiometer to stop the motor when it reaches a certain position would that be possible with this code.

Thanks again

just to push my look if I wanted to introduce either a limit switch or even a potentiometer to stop the motor when it reaches a certain position would that be possible with this code.

Yes. Each time you step, check to make sure that it is OK to step again. If not, break out of the loop.

D4vew5577:
Just to push my luck: if I wanted to introduce either a limit switch or even a potentiometer to stop the motor when it reaches a certain position would that be possible with this code?

If you don’t mind taking four steps before checking the limit switch you can do that at the bottom of the ‘for’ loop:

void clockwise()
{
  for (int i = 0; i < 510; i++)
  {
    digitalWrite(motorPin1, LOW);
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, LOW);
    digitalWrite(motorPin4, HIGH);
    delay(delayTime);
    digitalWrite(motorPin1, LOW);
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, HIGH);
    digitalWrite(motorPin4, LOW);
    delay(delayTime);
    digitalWrite(motorPin1, LOW);
    digitalWrite(motorPin2, HIGH);
    digitalWrite(motorPin3, LOW);
    digitalWrite(motorPin4, LOW);
    delay(delayTime);
    digitalWrite(motorPin1, HIGH);
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, LOW);
    digitalWrite(motorPin4, LOW);
    delay(delayTime);
    // Exit from the loop if the limit switch has been pressed
    if (digitalRead(CWLimitSwitchPin) == LOW)
      break;
  }
}

Would it be possible to have the motor stop when the limit switch is pressed the turn back slightly using something like the code below.

void clockwise()
{
  for (int i = 0; i < 510; i++)
  {
    digitalWrite(motorPin1, LOW);
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, LOW);
    digitalWrite(motorPin4, HIGH);
    delay(delayTime);
    digitalWrite(motorPin1, LOW);
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, HIGH);
    digitalWrite(motorPin4, LOW);
    delay(delayTime);
    digitalWrite(motorPin1, LOW);
    digitalWrite(motorPin2, HIGH);
    digitalWrite(motorPin3, LOW);
    digitalWrite(motorPin4, LOW);
    delay(delayTime);
    digitalWrite(motorPin1, HIGH);
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, LOW);
    digitalWrite(motorPin4, LOW);
    delay(delayTime);
    // Exit from the loop if the limit switch has been pressed
    if (digitalRead(CWLimitSwitchPin) == LOW)
  
{
  for (int i = 0; i < 10; i++)
  {
    digitalWrite(motorPin1, HIGH);
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, LOW);
    digitalWrite(motorPin4, LOW);
    delay(delayTime);
    digitalWrite(motorPin1, LOW);
    digitalWrite(motorPin2, HIGH);
    digitalWrite(motorPin3, LOW);
    digitalWrite(motorPin4, LOW);
    delay(delayTime);
    digitalWrite(motorPin1, LOW);
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, HIGH);
    digitalWrite(motorPin4, LOW);
    delay(delayTime);
    digitalWrite(motorPin1, LOW);
    digitalWrite(motorPin2, LOW);
    digitalWrite(motorPin3, LOW);
    digitalWrite(motorPin4, HIGH);
    delay(delayTime);
   }
 }
 }
}

Thanks.

D4vew557:
Would it be possible to have the motor stop when the limit switch is pressed the turn back slightly using something like the code below.

Yes, except you forgot to put a ‘break’ statement after you move back ten steps.
Note: When you are going to post code, please use Tools → Auto Format first to make the code easier to read.
Note: When you have big blocks of code that appear more than once in your sketch it is a good idea to move the block into a function. That way, if you need to make a change in that block you only need to make the change in one place.

void clockwise()
{
  for (int i = 0; i < 510; i++)
  {
    CW();
    // Exit from the loop if the limit switch has been pressed
    if (digitalRead(CWLimitSwitchPin) == LOW)
    {
      // Hit clockwise limit so move anticlockwise ten steps and end the clockwise motion
      for (int i = 0; i < 10; i++)
      {
        ACW();
      }
      break;
    }
  }
}
void CW()
{
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
}
void ACW()
{
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
}