0

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.

6
  • Edit your question and format the code. Select the code and click the {} button in the editor.
    – Mazaryk
    Apr 15 '17 at 16:17
  • First off, did you use pullup or pulldown resistors for your button?
    – jfpoilpret
    Apr 15 '17 at 16:31
  • Second, what's the purpose of ledon variable, in its current usage, it is just useless.
    – jfpoilpret
    Apr 15 '17 at 16:33
  • Nothing will happen as lastbuttonstate is never changed. Apr 15 '17 at 16:33
  • so i got to change the last buttonstate according to the led state ?? Apr 15 '17 at 16:35
1

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.

6
  • Can u plz explain me how u r using the variable waspressed here ? Apr 15 '17 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 of waspressed will always be true. At the time you release the button, the next loop will read buttonpin as false and will check if waspressed 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 set waspressed to false again so you go back to the initial state.
    – rvbarreto
    Apr 15 '17 at 17:30
  • I can explain it in a slower rhythm if necessary. Just ask me if you need it. :)
    – rvbarreto
    Apr 15 '17 at 17:41
  • I edited the answer to provide a more detailed explanation
    – rvbarreto
    Apr 15 '17 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. Apr 15 '17 at 18:11
0

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.

enter image description here

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.