Using state of button to stop for loop

// Define stepper motor connections and steps per revolution:
#define dirPin 10
#define stepPin 9
#define zeroPin 8
const int theta_relative[] = {7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,0,0,0,-0,-0,-1,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,-2,-2,-3,-3,-3,-3,-3,-3,-4,-4,-4,-4,-4,-4,-4,-4,-5,-5,-5,-5,-5,-5,-5,-5,-5,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-5,-5,-5,-5,-5,-5,-5,-5,-5,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,-1,-1,-1,-1,-1,-1,-0,-0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7};
const long int frame[] = {571,571,571,571,571,571,571,571,571,571,667,667,667,667,667,667,667,667,667,667,667,667,667,667,800,800,800,800,800,800,800,800,800,1000,1000,1000,1000,1000,1000,1000,1000,1333,1333,1333,1333,1333,1333,2000,2000,2000,2000,2000,2000,2000,4000,4000,4000,4000,4000,4000,100000,100000,100000,100000,100000,4000,4000,4000,4000,4000,4000,2000,2000,2000,2000,2000,2000,2000,1333,1333,1333,1333,1333,1333,1000,1000,1000,1000,1000,1000,1000,1000,800,800,800,800,800,800,800,800,800,667,667,667,667,667,667,667,667,667,667,667,667,667,667,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,667,667,667,667,667,667,667,667,667,667,667,667,667,667,800,800,800,800,800,800,800,800,800,1000,1000,1000,1000,1000,1000,1000,1000,1333,1333,1333,1333,1333,1333,2000,2000,2000,2000,2000,2000,2000,4000,4000,4000,4000,4000,4000,100000,100000,100000,100000,100000,4000,4000,4000,4000,4000,4000,2000,2000,2000,2000,2000,2000,2000,1333,1333,1333,1333,1333,1333,1000,1000,1000,1000,1000,1000,1000,1000,800,800,800,800,800,800,800,800,800,667,667,667,667,667,667,667,667,667,667,667,667,667,667,571,571,571,571,571,571,571,571,571,571};
int no_of_steps;
bool buttonState;

void setup() {
  // Declare pins as output:
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
}

void loop() {
  
int x = 1;

  for(int i = 0; i < 250 ; i = i + x){

    if (theta_relative[i] > 0) {
      no_of_steps = theta_relative[i];
      digitalWrite(dirPin, LOW);
  
      while (no_of_steps > 0) {
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(0.75*frame[i]);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(0.25*frame[i]);
        no_of_steps = no_of_steps - 1;
      }
    }

    else {
      no_of_steps = abs(theta_relative[i]);
      digitalWrite(dirPin, HIGH);

      while (no_of_steps > 0) {
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(0.75*frame[i]);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(0.25*frame[i]);
        no_of_steps = no_of_steps - 1;
      }
    }
  }
}

Hello,

My experiment includes controlling a stepper motor to perform sinusoidal motion. I have achieved this but I would now like to wire a button to stop the execution of the for loop in my code seen above. When this button is pressed I would like the for loop to finish its current iteration and then stop while the button is supressed. Once released it would continue the for loop as normal. The reasoning for this is because I would like to finish the for loop so the motor can return back to its zero position so I dont have to recalibrate its position when I stop the motion. I am having trouble with what to do. I have tried while and if loops to check the state of the button and to stop the motion but achieved nothing. Would appreciate any help with this.

Thanks

Is the 'zeroPin' a input for the button ?
You could check the button in the while-loop, but there is a better way.
The AccelStepper is a stepper library compatible with the DIR + STEP signals and uses acceleration and deceleration. Is that good enough ? Or do need that sinusoidal motion ?

We try to avoid such for-loops and while-loops in the Arduino loop() function. If you do one step each time the loop() runs, then you can check buttons, blinks leds, and do others things all together.
To know what the stepper motor is doing, a global variable is needed. For example a variable called 'state' that indicates if the stepper motor is going forward or backward.

Can you make a start with such a sketch ?

This is your unchanged sketch in Wokwi simulation:

Click the start button to start the simulation. If you make changes to a Wokwi project and want to store that, then you need to log in (it is free).
Why is it going so fast ? Which stepper motor is it ? Wokwi uses the default of 200 steps per rotation. In the tab "diagram.json", it is possible to slow down the Uno to 1MHz. It is now 16MHz, look for "attrs": { "frequency":"16m"}

when you press the button to interrupt the cycle, wouldn't you know the position of the shaft in terms of the # of steps and can run the motor back to the zeroth position?

consider

#define MyHW
#ifdef MyHW
# define dirPin  12
# define stepPin 13
# define zeroPin 8
# define butPin  A1

#else
# define dirPin 10
# define stepPin 9
# define zeroPin 8
# define butPin  A1
#endif


const int theta_relative[] = {7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,0,0,0,-0,-0,-1,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,-2,-2,-3,-3,-3,-3,-3,-3,-4,-4,-4,-4,-4,-4,-4,-4,-5,-5,-5,-5,-5,-5,-5,-5,-5,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-5,-5,-5,-5,-5,-5,-5,-5,-5,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,-1,-1,-1,-1,-1,-1,-0,-0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7};
#define Ntheta (sizeof(theta_relative)/sizeof(int))

const long frame[] = {571,571,571,571,571,571,571,571,571,571,667,667,667,667,667,667,667,667,667,667,667,667,667,667,800,800,800,800,800,800,800,800,800,1000,1000,1000,1000,1000,1000,1000,1000,1333,1333,1333,1333,1333,1333,2000,2000,2000,2000,2000,2000,2000,4000,4000,4000,4000,4000,4000,100000,100000,100000,100000,100000,4000,4000,4000,4000,4000,4000,2000,2000,2000,2000,2000,2000,2000,1333,1333,1333,1333,1333,1333,1000,1000,1000,1000,1000,1000,1000,1000,800,800,800,800,800,800,800,800,800,667,667,667,667,667,667,667,667,667,667,667,667,667,667,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,667,667,667,667,667,667,667,667,667,667,667,667,667,667,800,800,800,800,800,800,800,800,800,1000,1000,1000,1000,1000,1000,1000,1000,1333,1333,1333,1333,1333,1333,2000,2000,2000,2000,2000,2000,2000,4000,4000,4000,4000,4000,4000,100000,100000,100000,100000,100000,4000,4000,4000,4000,4000,4000,2000,2000,2000,2000,2000,2000,2000,1333,1333,1333,1333,1333,1333,1000,1000,1000,1000,1000,1000,1000,1000,800,800,800,800,800,800,800,800,800,667,667,667,667,667,667,667,667,667,667,667,667,667,667,571,571,571,571,571,571,571,571,571,571};
#define Nframe (sizeof(frame)/sizeof(long))

// -----------------------------------------------------------------------------
int no_of_steps;
bool buttonState;

int stepCnt = 0;

void
step (
    unsigned usec )
{
    digitalWrite      (stepPin, HIGH);
    delayMicroseconds (0.75 * usec);
    digitalWrite      (stepPin, LOW);
    delayMicroseconds (0.25 * usec);

    if (LOW == digitalRead (dirPin))
        stepCnt++;
    else
        stepCnt--;

    Serial.print   (" stepCnt ");
    Serial.println (stepCnt);
}

// -----------------------------------------------------------------------------
enum { Reset, Run, Pause };
int mode = Reset;

void loop ()
{
    static unsigned i = 0;

    // -------------------------------------
    if (Run == mode)  {
        Serial.print   (" i ");
        Serial.print   (i);

        no_of_steps = theta_relative[i];
        if (no_of_steps  > 0) {
            digitalWrite (dirPin, LOW);
            while (no_of_steps-- > 0) {
                step (frame [i]);
            }
        }
        else {
            no_of_steps = abs (no_of_steps);
            digitalWrite (dirPin, HIGH);
            while (no_of_steps-- > 0) {
                step (frame [i]);
            }
        }

        if (Nframe <= ++i)
            i = 0;
    }

    // -------------------------------------
    else if (Reset == mode)  {
        if (0 < stepCnt)
            digitalWrite (dirPin, HIGH);
        else
            digitalWrite (dirPin, LOW);

        while (stepCnt)
            step (1000);
    }

    // -------------------------------------
    byte but = digitalRead (butPin);
    if (buttonState != but)  {
        buttonState = but;
        delay (10);         // debounce

        Serial.println ("button");
        if (LOW == but)  {
            if (Pause < ++mode)
                mode = Reset;
            Serial.print   ("press ");
            Serial.println (mode);
        }
    }
}

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (9600);

    pinMode (butPin, INPUT_PULLUP);
    buttonState = digitalRead (butPin);

    pinMode (stepPin, OUTPUT);
    pinMode (dirPin,  OUTPUT);
}

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