Using a single push button for two servos

Hello,

Just wondering if the code I wrote had some errors in it or if i should try something else with it. At first I tried to use true and false statements but thought that it would be to complicated for turning 2 servos. I deiced to use for statements instead but i cant test it out the code because I dont have my uno with me and it wont let me verify without it. Im not to confident in my "for" statements I feel like I might have problems with that part.

#include <Servo.h>

int servo1 = 11;
int button = 12;
Servo servo1;
int servo2 = 10;
Servo servo2;

int pos1 = 0;
int pos2 = 0;

//bool toggle =true;
int buttonState = 0;

int LEDg = 2;
int LEDr = 4;
int LEDy = 3;
int buzzer = 7;

void setup() {
Serial.begin(9600);
servo1.attach(servo1);
servo2.attach(servo2);
pinMode(button, INPUT);
pinMode(LEDg, OUTPUT);
pinMode(LEDr, OUTPUT);
pinMode(LEDy, OUTPUT);
pinMode(buzzer, 7);
}

void loop() {
buttonState = digitalRead(button);
if (buttonState == HIGH) {
for (pos1 = 0; pos1 <= 180; pos += 1) {
serov1.write(pos1);
serov2.write(pos1);
digitalWrite(LEDg, HIGH);
digitalWrite(LEDr, LOW);
digitalWrite(LEDy, LOW);
digitalWrite(buzzer, HIGH);
delay(15);
}
for (pos1 = 180; pos1 >= 0; pos -= 1) {
serov1.write(pos1);
serov2.write(pos1);
digitalWrite(LEDg, LOW);
digitalWrite(LEDr, LOW);
digitalWrite(LEDy, HIGH);
digitalWrite(buzzer, HIGH);
delay(15);
}
else if {
if (buttonState == LOW) {
serov1.write(0);
serov2.write(0);
digitalWrite(LEDg, LOW);
digitalWrite(LEDr, HIGH);
digitalWrite(LEDy, LOW);
digitalWrite(buzzer, LOW);
}
}
}
}

Please read the forum guidelines to see how to properly post code and some information on making a good post.

Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in a code block.

Here is your code formatted and posted in a code block. This makes the code easier to read and follow and easier for helpers to work with.

#include <Servo.h>

int servo1 = 11;
int button = 12;
Servo servo1;
int servo2 = 10;
Servo servo2;

int pos1 = 0;
int pos2 = 0;

//bool toggle =true;
int buttonState = 0;

int LEDg = 2;
int LEDr = 4;
int LEDy = 3;
int buzzer = 7;

void setup()
{
   Serial.begin(9600);
   servo1.attach(servo1);
   servo2.attach(servo2);
   pinMode(button, INPUT);
   pinMode(LEDg, OUTPUT);
   pinMode(LEDr, OUTPUT);
   pinMode(LEDy, OUTPUT);
   pinMode(buzzer, 7);
}

void loop()
{
   buttonState = digitalRead(button);
   if (buttonState == HIGH)
   {
      for (pos1 = 0; pos1 <= 180; pos += 1)
      {
         serov1.write(pos1);
         serov2.write(pos1);
         digitalWrite(LEDg, HIGH);
         digitalWrite(LEDr, LOW);
         digitalWrite(LEDy, LOW);
         digitalWrite(buzzer, HIGH);
         delay(15);
      }
      for (pos1 = 180; pos1 >= 0; pos -= 1)
      {
         serov1.write(pos1);
         serov2.write(pos1);
         digitalWrite(LEDg, LOW);
         digitalWrite(LEDr, LOW);
         digitalWrite(LEDy, HIGH);
         digitalWrite(buzzer, HIGH);
         delay(15);
      }
      else if
   {
      if (buttonState == LOW)
         {
            serov1.write(0);
            serov2.write(0);
            digitalWrite(LEDg, LOW);
            digitalWrite(LEDr, HIGH);
            digitalWrite(LEDy, LOW);
            digitalWrite(buzzer, LOW);
         }
      }
   }
}

You should really differentiate the servo pin from the instance. servo1.attach(servo1); does this compile, I would be surprised if it did.

I would imagine you would also want to debounce the button too.

What is the end goal, just to move two servos together?

int servo1 = 11;
Servo servo1;  // duplicate name

int servo2 = 10;
Servo servo2; // duplicate name

You cannot have a variable name and an object with the same name.

for (pos1 = 0; pos1 <= 180; pos += 1)

for (pos1 = 180; pos1 >= 0; pos -= 1)

pos1 for initializer and condition, but pos for increment = error.

 serov1.write(pos1);

serov1 != servo1 Same error in a bunch of places, Copy and pasting errors makes work harder.
serov2, also.

}
      else if
   }

else if what ???

Code fixed so that it will compile. Will it work the way you want? Dang if I know.

#include <Servo.h>

int servo1Pin = 11;
int button = 12;
Servo servo1;
int servo2Pin = 10;
Servo servo2;

int pos1 = 0;
int pos2 = 0;

//bool toggle =true;
int buttonState = 0;

int LEDg = 2;
int LEDr = 4;
int LEDy = 3;
int buzzer = 7;

void setup()
{
   Serial.begin(9600);
   servo1.attach(servo1Pin);
   servo2.attach(servo2Pin);
   pinMode(button, INPUT);
   pinMode(LEDg, OUTPUT);
   pinMode(LEDr, OUTPUT);
   pinMode(LEDy, OUTPUT);
   pinMode(buzzer, 7);
}

void loop()
{
   buttonState = digitalRead(button);
   if (buttonState == HIGH)
   {
      for (pos1 = 0; pos1 <= 180; pos1 += 1)
      {
         servo1.write(pos1);
         servo2.write(pos1);
         digitalWrite(LEDg, HIGH);
         digitalWrite(LEDr, LOW);
         digitalWrite(LEDy, LOW);
         digitalWrite(buzzer, HIGH);
         delay(15);
      }
      for (pos1 = 180; pos1 >= 0; pos1 -= 1)
      {
         servo1.write(pos1);
         servo2.write(pos1);
         digitalWrite(LEDg, LOW);
         digitalWrite(LEDr, LOW);
         digitalWrite(LEDy, HIGH);
         digitalWrite(buzzer, HIGH);
         delay(15);
      }
      //else if
      //}
      if (buttonState == LOW)
      {
         servo1.write(0);
         servo2.write(0);
         digitalWrite(LEDg, LOW);
         digitalWrite(LEDr, HIGH);
         digitalWrite(LEDy, LOW);
         digitalWrite(buzzer, LOW);
      }
      //}
   }
}

Here is a WOKWI simulation of groundfungu's code

best regards Stefan

Thanks for the link! Ive been playing around with the code and im stuck on how to make it a toggle switch.

#include <Servo.h>

int servo1Pin = 11;
int button = 12;
Servo servo1;
int servo2Pin = 10;
Servo servo2;

int servoPos1=20;
int servoPos2=20;
int buttonState = 0;
int LEDg = 2;
int LEDr = 4;
int LEDy = 3;
int buzzer = 7;

void setup()
{
   Serial.begin(9600);
   servo1.attach(servo1Pin);
   servo2.attach(servo2Pin);
   pinMode(button, INPUT_PULLUP);
   pinMode(LEDg, OUTPUT);
   pinMode(LEDr, OUTPUT);
   pinMode(LEDy, OUTPUT);
   pinMode(buzzer, OUTPUT);
}


void loop() {

buttonState=digitalRead(button);

if(buttonState == HIGH){
  if(servoPos1<180){
    servoPos1 +=20;
    servo1.write(servoPos1);
      digitalWrite(LEDg, HIGH);
      digitalWrite(LEDr, LOW);
      digitalWrite(LEDy, LOW);
      digitalWrite(buzzer, HIGH);
  }
  if (servoPos2< 180){
    servoPos2+=20;
    servo2.write(servoPos2);
       digitalWrite(LEDg, HIGH);
      digitalWrite(LEDr, LOW);
      digitalWrite(LEDy, LOW);
      digitalWrite(buzzer, HIGH);
  }
  else
  {
servoPos1=20;
servo1.write(servoPos1);
servoPos2=20;
servo2.write(servoPos2);
   digitalWrite(LEDg, LOW);
      digitalWrite(LEDr, HIGH);
      digitalWrite(LEDy, LOW);
      digitalWrite(buzzer, LOW);
  }
  delay(1000);
}
}

I tried to put another if statement for when I press the button again only the red led is on and the servos go back to 20. It was something like "if (buttonState == LOW)" then the servos go back to 20 and only the red LED is on. However, I havent had success with that so should I add some kind of button counter to it??

Here is an example that shows how to toggle the state of an LED and a mode flag using 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 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;
            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;
   }
}

Describe what you mean.

Like a button press shou,d make it start wiping, and another should make it stop when it gets back to the starting position?

a7

@montrealfan0
there are a few things to learn.

  1. you have to become aware of that using delay() is blocking.
    as long as the delay() is executed nothing else can be done.
    Absolutely nothing else !

Your code with the delay() can be described as

void loop() {

buttonState=digitalRead(button);
// execute all the commands in 0.001 seconds

delay(1000); // do absolutely nothing for 1 second
}

with time-stamps
0:0.00000 buttonState=digitalRead(button);
0:0.00001 if(buttonState == HIGH)
0:0.00002 if (seroPos1 < 180) {
0:0.00003 servoPos += 20;
0:0.00004 servoWrite(servoPos1);
.....
....
0:0.0001 digitalWrite(buzzer, HIGH);
0:0.00011 delay()

1:0.00000 buttonState = digitalRead(button);

once everey second there is a super-short timeslot of 0.0001 seconds where the code reads in a single time digitalRead(button);
1 second unconscious waiting

0.0001 seconds digitalRead(button);
1 second unconscious waiting
0.0001 seconds digitalRead(button);
1 second unconscious waiting
0.0001 seconds digitalRead(button);
1 second unconscious waiting

This means you have to keep the button pressed down for a whole second if the button-press shall be detected.

If you want responsive code that reacts immiditiately on a button-press you have to avoid each and every delay().

Timing has to be coded WITHOUT delay().
Timing must to be coded with non-blocking waiting.

You have to be aware of that.

@groundFungus :

this single line of code does already confuse a lot.
This line of code does NO "check switch 20 times per second`"

Checking 20 times per second is HIDDEN inside ALL these lines:

And it would require much more explanation than this comment to make it understandable for a newcomer.

The probability that user @montrealfan0 does not even know what to ask about this code is pretty high.

If you want to be helpful you should present code that is easier to understand or posting links to tutorials that explain it in detail

best regards Stefan

I may no longer post code examples. I leave that to you since you are the only sensable educator on the forum. In fact I may stop participation in the forum all together as my help seems no longer needed. All yours.

The OP could ask questions if there were something that they did not understand.

1 Like

I have also been thinking about this topic for a long time. I have the impression that we are accused of bad faith when we publish learning examples.

It seems that they must meet rigorous standards.

@groundFungus and @paulpaulson

No, I am not accusing anyone of malicious intent or bad faith. The maximum is a partially ignorance to a certain aspect.

If you put my words and the formatting on a scale my words are for sure not the most pollite words. If I compare it with pure mathematics on the left: negative in the middle: zero on the right: positive. My words are left from zero for sure.

Partially the impact of my words depends on the receivers interpretation. I'm sure you are aware of this effect. And of course this effect is always there. It is there the same way for each and every user including newcomers / beginners.

The text and the code of user @montrealfan0 has multiple signs that user @montrealfan0 is a newcomer. Especially having posted code not as a code-section indicates it very obviously. It might be carelessness but I think it is very unikely that in this case non-code-section-code was caused by beeing carelessly
.
Totally OK to be a newcomer.
So if there are signs that a user is a newcomer you should twink twice or three times about the questions:

Is what I write easy to understand or not ?
How much knowledge must the reader already have to understand what I'm writing?

If I see a big discrepancy between what the most likely knowledge-level of a user is and what the answer is
and / or
if I recognise that this discrepancy is repeated many times I POINT on it.

Each single word of the non-code text might be exceptional pollitely. In combination with a code that is likely to be way above the head of the thread-opener the impact of such a post is no longer super-pollite and helpful.
There is a danger that such a code is discouraging and / or confusing.

best regards Stefan

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