Add button to start stepper and servo

I have this program to move a stepper and servo and it works great. I want to add a button to start the program so it doesn't start automatically when I add power. What am I doing wrong here? Right now I'm getting an "unqualified id before { token" right above the delay(4000).

#include <Stepper.h>
#include <Servo.h>


int buttonPin;

const int stepsPerRevolution = 501;  // steps to make 13 inch paracord lanyard

Servo myservo;  // create servo object to control a servo

int pos = 20;    // starting position is not top dead center

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);

void setup() {
  buttonPin = 5;
  pinMode(buttonPin, INPUT_PULLUP);
  
  // set the speed at 60 rpm:
  myStepper.setSpeed(60);
  
   myservo.attach(7);  // attaches the servo on pin 7 to the servo object
 }

void loop() {
   static boolean running = false;
   int buttonState = digitalRead(buttonPin);

   if (buttonState == HIGH)
   running = true;
   else
   running = false;
}

{
    delay(4000); //delay to let melted paracord cool before moving
    myStepper.step(stepsPerRevolution);// step 2.5 revolutions  in one direction:
    delay(100);
 }

          
  for (pos = 120; pos <= 180; pos += 1) { // goes from 40 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(35);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 120; pos -= 1) { // goes from 180 degrees to 40 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(5);                       // waits 15ms for the servo to reach the position
    }
   }
  }

If you use Auto Format in the IDE the problem may be more obvious

A section of your code

void loop()
{
  static boolean running = false;
  int buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH)
    running = true;
  else
    running = false;
}

{
  delay(4000); //delay to let melted paracord cool before moving
  myStepper.step(stepsPerRevolution);// step 2.5 revolutions  in one direction:
  delay(100);
}

Note where the loop() function ends. Is that the correct place ?

Do you actually want to read the button and set the "running" flag each time through loop()? (Not that it matters, since afaics you don't do anything with the flag anyway.)

And I think the button logic's upside down: you have the pullup turned on, so the pin will be high normally, and then low when pressed.

But if this:

... is your objective, it would be easier just to read the button in a while in setup() as below:

while (digitalRead(buttonPin) == HIGH) {}

Then it will sit in that while() until the button is pressed, then drop through into loop().

Auto format helps you to see curly braces that are missing/in wrong place

I did the auto format and it showed me the same brackets. If I remove the brackets, now it shows the "delay(100);" as "expected constructor..".

void loop() {
  static boolean running = false;
  int buttonState = digitalRead(buttonPin);

  if (buttonState == LOW)
    running = true;
  else
    running = false;
}


  delay(4000); //delay to let melted paracord cool before moving
  myStepper.step(stepsPerRevolution);// step 2.5 revolutions  in one direction:
  delay(100);



for (pos = 120; pos <= 180; pos += 1) { // goes from 40 degrees to 180 degrees
  // in steps of 1 degree
  myservo.write(pos);              // tell servo to go to position in variable 'pos'
  delay(35);                       // waits 15ms for the servo to reach the position

I don't know, I can't get it to work to find out.

This works perfectly, but the button only stops the program. I want it to start the program also. Or add another button.

#include <Stepper.h>
#include <Servo.h>


int buttonPin;

const int stepsPerRevolution = 200;  // steps to make 13 inch paracord lanyard

Servo myservo;  // create servo object to control a servo

int pos = 20;    // starting position is not top dead center

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);

void setup() {
  buttonPin = 5;
  pinMode(buttonPin, INPUT_PULLUP);
  
  // set the speed at 60 rpm:
  myStepper.setSpeed(60);
  
   myservo.attach(7);  // attaches the servo on pin 7 to the servo object
 }

void loop() {
   if(digitalRead(buttonPin) == HIGH)// code runs runs until button is pressed
    exit(0); // code stops when button is pressed
   {
    delay(4000);//delay to let melted paracord cool before moving
  
  // step 2.5 revolutions  in one direction:
 
  myStepper.step(stepsPerRevolution);
  delay(100);

          
  for (pos = 120; pos <= 180; pos += 1) { // goes from 40 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(35);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 120; pos -= 1) { // goes from 180 degrees to 40 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(5);                       // waits 15ms for the servo to reach the position
    }
   }
  }

image

Blockquote

Sorry. I want the button to start and stop the program.

There is lots to find using the word toggle. Also you might want to look up state machines. Holding the state of something in a variable can be done in a simple way such as 0 for off and 1 for on.
Then you write a buttonPush function to detect button being pushed.

If state = 0
State =1

Ie if not running, run and vice versa

Here is an example code to show how to toggle the state of a flag (mode) with the state change detection method.

// by C Goulding aka groundFungus

const byte  buttonPin = 2;    // the pin to which the pushbutton is attached
const byte ledPin = 13;       // the pin to which the LED is attached

bool buttonState = 0;         // current state of the button
bool lastButtonState = 0;     // previous state of the button

bool mode = false;

void setup()
{
   // initialize the button pin as a input with internal pullup enabled
   pinMode(buttonPin, INPUT_PULLUP);
   // initialize the LED as an output:
   pinMode(ledPin, OUTPUT);
   // initialize serial communication:
   Serial.begin(115200);
   Serial.println("Select (toggle) mode with push button");
}

void loop()
{
   static unsigned long timer = 0;
   unsigned long interval = 50;  // check switch 20 times per second
   if (millis() - timer >= interval)
   {
      timer = millis();
      // read the pushbutton input pin:
      buttonState = digitalRead(buttonPin);
      // compare the new buttonState to its previous state
      if (buttonState != lastButtonState)
      {
         if (buttonState == LOW)
         {
            // if the current state is LOW then the button
            // went from off to on:
            digitalWrite(ledPin, !digitalRead(ledPin)); // toggle the output
            mode = !mode;  // toggle the state of the mode flag.
            if (mode == true)
            {
               Serial.println("Manual mode\n");
            }
            else
            {
               Serial.println("Scan mode\n");
            }
         }
      }
      // save the current state as the last state,
      //for next time through the loop
      lastButtonState = buttonState;
   }
}

Yes, this works as it is written just fine with one LED. I can't get this kind of thing to work with my program to run a stepper.

If you can dodge a wrench you can dodge a ball!! :wrench:

Create states for your stepper
If you can toggle the flag you can toggle the stepper state. Code the stepper motion in the stepper state function!

Look up classes or structs a if you want to be clever

Please post your latest code which reads a button press and toggles a state back and forth between run and stop and then gets the stepper to act according to the selected state.

What is your not doing correctly?

Motors work fine, but buttons do nothing.

#include <Stepper.h>
#include <Servo.h>


const byte  buttonPin = 5;    // the pin to which the pushbutton is attached


bool buttonState = 0;         // current state of the button
bool lastButtonState = 0;     // previous state of the button

bool mode = false;

const int stepsPerRevolution = 200;  // steps to make 13 inch paracord lanyard

Servo myservo;  // create servo object to control a servo

int pos = 20;    // starting position is not top dead center

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);

void setup() {

 
  pinMode(buttonPin, INPUT_PULLUP);

  // set the speed at 60 rpm:
  myStepper.setSpeed(60);

  myservo.attach(7);  // attaches the servo on pin 7 to the servo object
}

void loop() {
  static unsigned long timer = 0;
  unsigned long interval = 50;  // check switch 20 times per second
  if (millis() - timer >= interval)
  {
    timer = millis();
    // read the pushbutton input pin:
    buttonState = digitalRead(buttonPin);
    // compare the new buttonState to its previous state
    if (buttonState != lastButtonState)
    {
      if (buttonState == LOW)
      
    // save the current state as the last state,
    //for next time through the loop
    lastButtonState = buttonState;
  }
}
{
  delay(4000);//delay to let melted paracord cool before moving

  // step 2.5 revolutions  in one direction:

  myStepper.step(stepsPerRevolution);
  delay(100);


  for (pos = 120; pos <= 180; pos += 1) { // goes from 40 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(35);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 120; pos -= 1) { // goes from 180 degrees to 40 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(5);                       // waits 15ms for the servo to reach the position
  }
}
}

It looks like you are changing the value of buttonState when the button becomes pressed but you then do nothing with that value in the sketch

You need to do something like this

if (buttonState == HIGH)
{
  //code here to run motors
}
else
{
  //code here to stop motors
}

It often makes your code easier to understand if you group it into functions and name them well.

Eg
pollButton()
This function can check the state of the buttons every x ms (put all your button code here)

Do this for each thing and your code can read more like;

PollButton
If buttonOn
Run motors
Else
Stop motors

'else' without a previous 'if' error.

#include <Stepper.h>
#include <Servo.h>


int buttonPin;

const int stepsPerRevolution = 200;  // steps to make 13 inch paracord lanyard

Servo myservo;  // create servo object to control a servo

int pos = 20;    // starting position is not top dead center

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);

void setup() {

  buttonPin = 5;
  pinMode(buttonPin, INPUT_PULLUP);
  
  // set the speed at 60 rpm:
  myStepper.setSpeed(60);
  
   myservo.attach(7);  // attaches the servo on pin 7 to the servo object
 }

void loop() {
   if(digitalRead(buttonPin) == HIGH)// code runs runs until button is pressed
     // code stops when button is pressed
   delay(4000);//delay to let melted paracord cool before moving
              // step 2.5 revolutions  in one direction:
 
   myStepper.step(stepsPerRevolution);
   delay(100);

   for (pos = 120; pos <= 180; pos += 1) { // goes from 40 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(35);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 120; pos -= 1) { // goes from 180 degrees to 40 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(5);                       // waits 15ms for the servo to reach the position
    }
    else{
      exit(0);
    }
   }

I want to add a button to start the program so it doesn't start automatically when I add power.

I want the button to start and stop the program.

You have two different issues here.

Getting the program to start with a button press is very simple.

The stop routine is problematic given that you have blocking stepper and servo code which prevent the button from being read when the motors are running.

It's not clear how you want your process to proceed. Do you want to be able to stop only at the end of run after the servo has moved?

Yes. I want it to stop after the servo has done its job. My first code will do that with the exit(0); in the if statement.