Stepper control with buttons for both directions, loop for positioning

Hello,
I am now running the below sketch for my stepper motors to run back and forth. One switch to move CW, the other to move CCW. I want to limit the movement of the stepper now to 90° by a push of the switch. I have problems to identify where to add a loop and which one best. Can anybody help me modify below sketch ? Many thanks.

// 240905_2_stepper_2_buttons.ino
// 240905: currently running with ext. power supply 5V.
int Pin1 = 6;//IN1 is connected to 6
int Pin2 = 7;//IN2 is connected to 7
int Pin3 = 8;//IN3 is connected to 8
int Pin4 = 9;//IN4 is connected to 9
int switchCW =4;//define input pin for CW push button
int switchCCW =5;//define input pin for CCW push button
int ledCW = 2; // output pin for CW LED
int ledCCW = 3; // output pin for CCW LED

int pole1[] ={0,0,0,0, 0,1,1,1, 0};//pole1, 8 step values
int pole2[] ={0,0,0,1, 1,1,0,0, 0};//pole2, 8 step values
int pole3[] ={0,1,1,1, 0,0,0,0, 0};//pole3, 8 step values
int pole4[] ={1,1,0,0, 0,0,0,1, 0};//pole4, 8 step values
int poleStep = 0;
int dirStatus = 3;// stores direction status 3= stop (do not change)

void setup()
{
pinMode(Pin1, OUTPUT);//define pin for ULN2003 in1
pinMode(Pin2, OUTPUT);//define pin for ULN2003 in2
pinMode(Pin3, OUTPUT);//define pin for ULN2003 in3
pinMode(Pin4, OUTPUT);//define pin for ULN2003 in4
pinMode(switchCW,INPUT_PULLUP);
pinMode(switchCCW,INPUT_PULLUP);
pinMode(ledCW, OUTPUT);
pinMode(ledCCW, OUTPUT);
}
void loop()
{
if(digitalRead(switchCCW) == LOW)
{
dirStatus =1;
}else if(digitalRead(switchCW) == LOW)
{
dirStatus = 2;
}else
{
dirStatus =3;
}
if(dirStatus ==1){ // Forward
digitalWrite(ledCW, HIGH);
poleStep++;
driveStepper(poleStep);
}else if(dirStatus ==2){ // Reverse
digitalWrite(ledCCW, HIGH);
poleStep--;
driveStepper(poleStep);
}else{
driveStepper(8);
}
if(poleStep>7){
poleStep=0;
}
if(poleStep<0){
poleStep=7;
}
delay(3);
}// loop
/*

  • @brief sends signal to the motor
  • @param "c" is integer representing the pole of motor
  • @return does not return anything
    */
    void driveStepper(int c)
    {
    digitalWrite(Pin1, pole1[c]);
    digitalWrite(Pin2, pole2[c]);
    digitalWrite(Pin3, pole3[c]);
    digitalWrite(Pin4, pole4[c]);
    }//driveStepper end here

Which Arduino?

First, I modify your sketch to be readable per some forum guidelines:

// 240905_2_stepper_2_buttons.ino
// 240905: currently running with ext. power supply 5V.
int Pin1 = 6;//IN1 is connected to 6
int Pin2 = 7;//IN2 is connected to 7
int Pin3 = 8;//IN3 is connected to 8
int Pin4 = 9;//IN4 is connected to 9
int switchCW = 4; //define input pin for CW push button
int switchCCW = 5; //define input pin for CCW push button
int ledCW = 2; // output pin for CW LED
int ledCCW = 3; // output pin for CCW LED

int pole1[] = {0, 0, 0, 0, 0, 1, 1, 1, 0}; //pole1, 8 step values
int pole2[] = {0, 0, 0, 1, 1, 1, 0, 0, 0}; //pole2, 8 step values
int pole3[] = {0, 1, 1, 1, 0, 0, 0, 0, 0}; //pole3, 8 step values
int pole4[] = {1, 1, 0, 0, 0, 0, 0, 1, 0}; //pole4, 8 step values
int poleStep = 0;
int dirStatus = 3;// stores direction status 3= stop (do not change)

void setup()
{
  pinMode(Pin1, OUTPUT);//define pin for ULN2003 in1
  pinMode(Pin2, OUTPUT);//define pin for ULN2003 in2
  pinMode(Pin3, OUTPUT);//define pin for ULN2003 in3
  pinMode(Pin4, OUTPUT);//define pin for ULN2003 in4
  pinMode(switchCW, INPUT_PULLUP);
  pinMode(switchCCW, INPUT_PULLUP);
  pinMode(ledCW, OUTPUT);
  pinMode(ledCCW, OUTPUT);
}
void loop()
{
  if (digitalRead(switchCCW) == LOW)
  {
    dirStatus = 1;
  } else if (digitalRead(switchCW) == LOW)
  {
    dirStatus = 2;
  } else
  {
    dirStatus = 3;
  }
  if (dirStatus == 1) { // Forward
    digitalWrite(ledCW, HIGH);
    poleStep++;
    driveStepper(poleStep);
  } else if (dirStatus == 2) { // Reverse
    digitalWrite(ledCCW, HIGH);
    poleStep--;
    driveStepper(poleStep);
  } else {
    driveStepper(8);
  }
  if (poleStep > 7) {
    poleStep = 0;
  }
  if (poleStep < 0) {
    poleStep = 7;
  }
  delay(3);
}// loop
/*

  @brief sends signal to the motor
  @param "c" is integer representing the pole of motor
  @return does not return anything
*/
void driveStepper(int c)
{
  digitalWrite(Pin1, pole1[c]);
  digitalWrite(Pin2, pole2[c]);
  digitalWrite(Pin3, pole3[c]);
  digitalWrite(Pin4, pole4[c]);
}//driveStepper end here

What do you mean by this:

It sounds like you want something more complicated than just acting on the level of a variable. Maybe this would help:

https://docs.arduino.cc/built-in-examples/digital/StateChangeDetection/

As would these:

... for separarating the reading of the switch and planning the motion from executing the motion so you can do both things at the same time.

You will need to know your stepper motor "steps per revolution" and divide by 4. For example; if your stepper has 200 steps per revolution, that is equivalent to 360 degrees. To make your motor move 90 degrees, which is 360 divided by 4, you would move your motor 200/4 = 50 steps.

1 Like

I would guess that you mean that each press of a button increases/decreases the target position by +/-90°.

In that case I would use a couple state variables to remember the target and position of the stepper, (I'd declare them with long target = 0 , position=0;) and then use the stateChange/edgeDetection on the button presses to increment or decrement the target to plan the motion. Then separately I'd compare the position to the target to set dirStatus. Then I'd use dirStatus to set the LEDs and make the steps, and when I made the steps, I'd update position accordingly.

At any time during the run, the state variables target and position would be enough completely describe what the system needs to be doing.

If you are still there, that's how I would approach it.

Because this phase-table does half-steps, it needs twice the indexing as a full-step configuration.

Also, since the coils are updated from the table after the index is changed but before the limits are enforced, there is an all-off in the one direction when poleStep==8, and some undefined behavior when poleStep==-1 in the other direction.

1 Like

Nano

Thank you very much for all the information in your answers, I will work through it and hopefully find an appropriate way to get my program running as expected. This also explains why there are hickups in the program when running into undefined stages. Thanks again.

Is there a reason why you don't use a library to drive your stepper? It would be much more easy if you e.g. use the MoToStepper class of the MobaTools library.

1 Like

I did try the MobaTools library, but did not get the sketch to run properly. I will give it another try.

Please post your attempt.

Classic Nano?

Sorry, yes. Classic Nano.

The classic Nano is supported by MobaTools, how did you try?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.