Toggle on and off

Having an LED turn on or off when a button is pressed is quite impressive, but it would be pretty odd if you had to press a button constantly to keep the TV on. What we want is an alternating action switch, where the press-and-release of a button does something, not just press-and-hold. Basically we want to test whether the button was just released, or just pressed.

To do this, we need to keep track of the button input value, to see if its changed. This is called the state of a button. When the state changes (an action occurs), that's when we want to perform an action.

Upload it to your Arduino and try it out, watching the serial monitor as you press and release the button.

Lets go through the new lines of code:

int buttonState;

This line isn't too unusual, its just a variable that is going to hold the state of the button. Since we don't know the state of the button when the Arduino is first turned on, we will leave it as unknown (uninitialized).

  buttonState = digitalRead(switchPin);

In the setup() procedure, we initialize (set the initial/starting value) of the button state variable by reading the button value once we've started up and set the pin to an input.

void loop(){
  val = digitalRead(switchPin);

OK now to the interesting part. In the loop procedure, we begin by first checking the button pin state and storing it an temporary variable val.

  if (val != buttonState) {          
    if (val == HIGH) {    

Now we see 2 if statements that are nested, this means that we perform one test and if that test comes out true we go on to perform another test. This is more complex than a simple if statement but not much more different than the kinds of decisions we make all the time.

For example:

 if ( it is raining ) {                
    if ( I have an umbrella ) {        

Of course, we can't open the umbrella if we don't have one. And there's no point in checking if we have one if its not raining!

In the first if statement, we check if the current button state (HIGH or LOW) is different than the last time we looked at the button. If it is different (tested by the != inequality operator ) then we execute the next group of statements, enclosed by the {} braces.

    if (val == HIGH) {                // check if the button is pressed
      Serial.println("Button just pressed");
    } else {                         // the button is -not- pressed...
      Serial.println("Button just released");

This statement is easy to understand: before, we would run a test and if that test passed, we would perform the statements in the {} braces. Now we also have an alternative, which is what we should do if the test fails! Now we used to perform two tests, one for (val == LOW) and one for (val == HIGH). This code is equivalent but its a little more straightforward. If its not LOW it must be HIGH.

In the if-else statement, we simply examine val to determine if the last digitalRead() procedure informed us that the button is currently pressed or not pressed.

  buttonState = val;                 // save the new state in our variable
Finally, we make sure that we've updated the button state variable with the current state.

Time to Play

    • Add in an LED and modify the program to turn it on and off.
    • Remove or comment out the "buttonState = val;" line. What happens? Why?

The text and code examples above were copied and slightly modified from Arduino tutorials by Limor Fried at under as such, this page is subject to the same license.