I want to toggle the the LED on on my first complete click(i.e. pushing and even releasing the pushbutton) and i want to make my LED off at my second click.
This is the program :-
int led = 13;
int buttonpin = 8;
boolean lastbuttonstate = LOW;
boolean ledon = LOW;
void setup ()
{
digitalWrite(buttonpin,HIGH);
pinMode(buttonpin,INPUT);
pinMode(led,OUTPUT);
}
void loop ()
{
if( digitalRead(buttonpin) == HIGH && lastbuttonstate == LOW && ledon = !digitalRead(buttonpin))
{
digitalWrite(led,HIGH);
}
else if (digitalRead(buttonpin) == LOW && lastbuttonstate == HIGH && ledon =!digitalRead(buttonpin))
{
digitalWrite(led,HIGH);
}
if( digitalRead(buttonpin) == HIGH && lastbuttonstate == LOW && ledon =digitalRead(buttonpin))
{
digitalWrite(led,LOW);
}
else if (digitalRead(buttonpin) == LOW && lastbuttonstate == HIGH && ledon =digitalRead(buttonpin))
{
digitalWrite(led,LOW);
}
}
I have connected all the connections on my breadboard according to schematic but there is something wrong in the program itself.
2 Answers 2
I would use a different approach
int led = 13;
int buttonpin = 8;
boolean waspressed = false;
void setup (){
pinMode(buttonpin,INPUT);
pinMode(led,OUTPUT);
digitalWrite(led,LOW);
}
void loop(){
if(digitalRead(buttonpin) == HIGH){
waspressed = true;
}else{
if(waspressed == true){
digitalWrite(led, !digitalRead(led));
waspressed = false;
}
}
}
We can understand it better if we just take a step by step view. When the controller is started, it first executes the setup(), setting the led pin as output, buttonpin as input and setting the led pin value to low. The led pin is set to LOW because it needs to have an initial value once it is an output. The initial value can also be HIGH without changing the behavior of the circuit. Always remember to set an initial value to all your output pins. This prevent them to float, which may lead no unpredictable results.
The loop() can be a little more tricky.
State 1 - button not pressed
The first interaction tries the value of buttonpin:if(digitalRead(buttonpin) == HIGH)
. Once the button is not pressed (buttonpin is LOW), the interpreter moves to the else
element. At this element, there is another conditional - i.e, another if
. This conditional looks for the value of waspressed
. This is false, as set at the begging of the code. Because of this, the information inside the conditional is not executed and the loop() is executed over and over with no change until the button is pressed.
Stage 2 - button is pressed
When the button is pressed, the next iteraction of loop() will catch this action when trying the first conditional if(digitalRead(buttonpin) == HIGH)
. Once buttonpin is high if the button is pressed, waspressed
will be set to true. This will repeat as long as the button remain pressed.
Stage 3 - button is released
After being released, the first conditional will read buttonpin as LOW, and the interpretor will move the the else
element. At that element, it will try the second conditional if(waspressed == true)
. Until now, there is no difference from what was executed at the first stage, however this time, waspressed
is true because it was set true when the button was pressed. This leads the interpreter inside the conditional and execute the lines
digitalWrite(led, !digitalRead(led));
waspressed = false;
The first one set the led pin to the opposite value it has. I.e, if the led pin is HIGH, it becames LOW, if it is LOW, it becames HIGH. This happens because !digitalRead(led)
outputs the complement of the value of digitalRead(led)
- without the !.
The second one set waspressed to false again. With this, the next iteration will be back to stage one and wait for another press on the button.
-
Can u plz explain me how u r using the variable waspressed here ?MrDeepThought– MrDeepThought2017年04月15日 17:23:43 +00:00Commented Apr 15, 2017 at 17:23
-
At every loop, it reads the variable buttonpin for its value. In case it is HIGH, it sets
waspressed
to true. This means that by the time you are holding the button, the value ofwaspressed
will always be true. At the time you release the button, the next loop will read buttonpin as false and will check ifwaspressed
is true. In case it is true, this means that the button has just being released. In this case it changes the value of the led pin and setwaspressed
to false again so you go back to the initial state.rvbarreto– rvbarreto2017年04月15日 17:30:51 +00:00Commented Apr 15, 2017 at 17:30 -
I can explain it in a slower rhythm if necessary. Just ask me if you need it. :)rvbarreto– rvbarreto2017年04月15日 17:41:45 +00:00Commented Apr 15, 2017 at 17:41
-
I edited the answer to provide a more detailed explanationrvbarreto– rvbarreto2017年04月15日 18:10:05 +00:00Commented Apr 15, 2017 at 18:10
-
thanx for the elaboration.....now i'm completely able to understand this program.....it was easier than a complex program that i was unable to understand from youtube.MrDeepThought– MrDeepThought2017年04月15日 18:11:06 +00:00Commented Apr 15, 2017 at 18:11
This appears to be the classic "how to debounce a mechanical button" problem.
You can either denounce a button using external hardware. Or you can denounce a button using software.
Using Hardware:
Normally a Set Reset or SR Latch is used to debounce mechanical buttons. It is common to use a single poll double throw (break before make) type switch to accomplish this.
Using Software:
When solving this in software, one needs to create a state machine with 4 states. Two of which are the normally expected ON and OFF state. The other two are the state where we are not sure if the button is pressed or not. As the button is in motion or is "bouncing". These 2 extra states have a time component much longer then the expected time it takes the switch to stop "bouncing". But much shorter then to be noticeable to the operator of the button.
For a really good explanation of using state machines for debouncing switches specifically for an Arduino refer to the "denounce a button using software" link at the top of this answer.
ledon
variable, in its current usage, it is just useless.lastbuttonstate
is never changed.