Hi! I want to control a servo with one push button...when I press it once it turns 180 deg. When I push it again, it swings back to 0 deg. Here is my code I was tampering with:
#include <Servo.h>
int button1 = 7;
Servo servo1;
boolean servoflag = LOW;
void setup(){
Serial.begin(9600);
pinMode(button1, INPUT);
servo1.attach(9);
}
void loop(){
int button1_pressed = digitalRead(button1);
////////////////////////////////////////////////////////////
if (button1_pressed == LOW && servoflag == LOW)
{
Serial.print("Button Flag ");
Serial.println(button1_pressed);
delay(3000);
servo1.write(180);
delay(20);
Serial.print("Servo Flag ");
Serial.println(servoflag);
servoflag = HIGH;
Serial.print("Servo Flag ");
Serial.println(servoflag);
}
if (button1_pressed == LOW && servoflag == HIGH)
{
Serial.print("Button Flag with servoflag HIGH ");
Serial.println(button1_pressed);
delay(3000);
servo1.write(90);
delay(20);
Serial.print("Servo Flag ");
Serial.println(servoflag);
servoflag = LOW;
Serial.print("Servo Flag ");
Serial.println(servoflag);
}
}
I was trying to watch when I pressed the button and how the program responded. I made a boolean called "servoflag" that would switch back and forth between the states every time a button was pressed. When I view the serial monitor, this is displayed:
Button Flag 0
Servo Flag 0
Servo Flag 1
Button Flag with servoflag HIGH 0 <--- this is the problem. This line goes off before I pressed the button.
Servo Flag 1
Servo Flag 0
I push the button, wait 3 seconds, and the servo moves and the appropriate flags are raised. Then, IMMEDIATELY the next button flag is raised. I never pushed the button a second time yet. So what ends up happening is the servo moves when I press the button 180 deg, then it goes back to 0 deg right after that before I push the button a second time.
I do now! I was debugging and playing around with it for a few hours this morning and realized that I had 2 if statements (if button1 == LOW) that were triggering at the same time. The first time through, the servoflag was low so the program waited for 3 seconds then the servo moved. Then it switched my boolean (which should have been as true/false) and then IMMEDIATELY went to the next part of my if statement because I pressed the button from before! Only this time, the servoflag was HIGH, and the conditions were met to continue with the statement so the servo moved back to its original position.
I see that I can't have 2 if statements calling on the same input. So, zoomkat's code makes 1 if-statement regarding the button. Then the system looks to the state of the toggle variable, or servoflag in my code.
It took me a few hours to see that difference...I'm still learning
I see that I can't have 2 if statements calling on the same input.
Yes, you can. But, most likely the second one should have been an else if, so that only one of the if blocks was executed.
The obvious difference between your code and zoomkat's that I saw was his code enabled the pullup resistor and yours did not. Therefore, his accurately read the state of the switch while yours did not.
I don't have 37,000+ posts so I will respectfully defer on the issue (and I feel I am drifting toward the pendantic in any event), but to me it would be more accurate to say Zoomcat's code employed a delay to try and debounce or smooth out the switch reading. I would assert the resistor is unaffected by code- it is always there, code doesn't enable it by turning it on or off. I would think what is at issue is how often the microprocessor detects the voltage level on the input pin. Adding the delay means the input will be read a little less frequently and therefore have a lower likelihood of sampling a moment when the voltage level is changing due to the switch changing physical position. The delay by itself does not provide a structure (like in the arduino.cc/en/Tutorial/Debounce example) where if one state is detected some time is allowed to pass and an additional reading made to confirm or dispel the initial reading.
pinMode(button, INPUT); //arduino monitor pin state
digitalWrite(5, HIGH);
Yes, the code enabled a pullup resistor (it would have been better written " digitalWrite(button, HIGH)", but the sentiment is there)
It doesn't take anything like 37k posts.
First off, thanks for all the support from everyone. After some testing here's what I've found:
I've commented out the pullup resistor section from zoomkat's code and didn't notice any change in the servo behavior.
I've updated my code (albeit it's much more messy) here:
#include <Servo.h>
int button1 = 6;
Servo servo1;
boolean servoflag = true;
void setup(){
Serial.begin(9600);
pinMode(button1, INPUT);
servo1.attach(7);
//digitalWrite(6, HIGH);
}
void loop(){
int button1_pressed = digitalRead(button1);
////////////////////////////////////////////////////////////
if (button1_pressed == LOW)
{
Serial.print("Button Flag ");
Serial.println(button1_pressed);
Serial.print("Servo Flag ");
Serial.println(servoflag);
//delay(3000);
if (servoflag)
{
servo1.write(180);
delay(20);
servoflag = false;
Serial.print("Servo Flag ");
Serial.println(servoflag);
}
else
{
Serial.print("Button Flag with servoflag HIGH ");
Serial.println(button1_pressed);
Serial.print("Servo Flag ");
Serial.println(servoflag);
//delay(3000);
servo1.write(30);
delay(20);
servoflag = true;
Serial.print("Servo Flag ");
Serial.println(servoflag);
}
}
delay(100);
}
and this code works just as expected...I push the button and the servo swings one way and when I press again it swings the other.
I think the delay has something to do with it. Notice I used a delay(100) at the end of mine and zoomkat used delay(500). Oh, and I can add the section of the code for the pullup resistor and still, nothing changes with the behavior of the servo. Now, if I use a delay(500) in my code, I have to hold the button down just a bit longer to get the servo to move.
So now I'm still trying to figure what is actually causing the issue...is it the delay or resistor; or some combination of the two? I have working code but I want to know what's really going on.
So now I'm still trying to figure what is actually causing the issue...is it the delay or resistor; or some combination of the two? I have working code but I want to know what's really going on.
What issue are you having? Hard to filter thru all the churn.
The issue was fixed...the main problem with my code. I have it fixed now, but I was curious what was happening with my original 'bad' code. Why was the code 'automatically' seeing my button as being pressed? I pressed the button, and the servo moved. Then it moved again without me pressing the button. I had been playing with the pull-up resistor but I don't think that's the issue since I can comment out that line in the code and the program still works fine.
This is more of a "ok I have it fixed, but why was it broken in the first place?" kinda thing.
Dear Zoomkat;
Your code is working for one servo. I would like to extend it to at least 5 servos. In other words, I have 5 servos, 5 buttons and 5 different angles. So what kind of code I can use?