Experiment 2:

With the Touch of a Button1

Introduction

Hopefully, you’ve gotten skilled with blinking an LED. That may sound simple, but you’ve learned how to

  • install the Arduino software on your laptop,
  • connect the Arduino Uno to your laptop so they communicate with either other.
  • construct circuits that use LEDs.
  • write code that can blink LEDs in different patterns.

That is no small feat.

We also learned about input and output devices. Output devices are things that perform an action liking blinking an LED light, and input devices are things that sense things about the world, like sensing that someone pressed a push button. When we combine both input and output devices in a single circuit, that circuit becomes truly interactive.

  • we press a key on a digital musical keyboard (input)and it produces a sound (output).
  • the Arduino senses freezing temperatures in a greenhouse (input) and sounds an alarm (output).
  • we press the letter ‘q’ on our laptop keyboard and see the ‘q’ appear on the screen.
  • we press the trackpad button on a web page link and it takes us to a new page.

Most of those examples, rely on a basic pushbutton which is what we will experiment with here.

Pushbuttons were invented over 100 years ago. One of their first uses was in pocket flashlights by the EverReady company

These look old and dirty because, well, they are old, and they were used. In 1905 these would have been the equivalent of getting an iPhone 12. (I have no clue if that is true but it sounds true!). And if you are completely fascinated by the history of the pushbutton check out Rachel Plotnick’s book Power Button: A history of pleasure, panic, and the politics of pushing, which focuses on the history of the pushbutton from 1880 to 1925

Now back to our current topic. In this circuit, we are going to combine the LED, which is used in almost everything, with a pushbutton, which is also used in everything and our computer code will use an if statement, which, as you can predict, is used in almost all computer programs.

The way a push button works with the Arduino Uno is that when the button is pushed, the voltage goes LOW. Your board reads this and reacts accordingly. When the button is not pushed it will read HIGH (there is a longer explanation that we will ignore). The Uno can read that the button is HIGH and will react appropriately.

Parts Needed

You will need the following parts:

  • 1x Push Button
  • 1x LED
  • 1x 330Ω Resistor
  • 4x Jumper Wires

Push Buttons

The button we used is called a momentary switch. As long as you press on the button it will read LOW, and as soon as you release the button it will read HIGH. So the switch is on as long as you press it and it turns off as soon as you release it. Most push buttons in the modern world are momentary switches. The other type of push button is called latching. In latching push buttons when you press a button and release it the button stays pushed in and activated and turns off when you press it again.

Hardware Hookup

We are going to add the push button to the same LED circuit from the first experiment following the Fritzing diagram below.

link to larger image

Legs

LED

The shorter leg of the LED should be connected to the resistor and then ground.

Buttons

Buttons have an orientation that is correct. The legs of the button protrude out of two sides of the button, while the other two side are bare. The sides with the legs should be on either side of the valley on the breadboard. Buttons have a tendency to fall out of the breadboard holes. To get a secure connect, you can use your finger nail tips to securely seat the button on the breadboard.

The code

In our first experiment when we connected an LED to a pin on the Arduino Uno, in our setup code we declared:

pinMode(redLed, OUTPUT);

What do you think the pinMode will be for a button?

If you think INPUT you would be 100% correct …. except there is a wrinkle. For buttons we will use a special kind of input called INPUT_PULLUP

pinMode(button, INPUT_PULLUP)

That line of code will go into our setup()

With LEDs to turn them on and off we used digitalWrite. What do you think we will use to see if a button is pressed?

If you think digitalRead again, you would be 100% correct.

digitalRead(pushButton);

In English (psuedocode)

It’s a good idea to sketch out what we want to do in English before we code (or use your favorite language - 私たちがやりたいことをスケッチするのは良い考えです)

And what better place to do it then your lab notebook:

Now we have a pretty good idea of what we want to do. And because we are beginners, let’s copy that idea into our code as comments. So we might have

    int led = 13;
    int pushButton = 3;

    void setup() {
      pinMode(led, OUTPUT);
      pinMode(pushButton, INPUT_PULLUP);
    }

    void loop() {

        // if button is pressed
        // turn on the LED
        // else
        // turn off the led


    }

We already know how to write the lines to turn the led on and off so let’s add them in:

    ...

    void loop() {

        // if button is pressed
        // turn on the LED
        digitalWrite(led, HIGH);
        // else
        // turn off the led
        digitalWrite(led, LOW);


    }

Ok. The state of the button will be LOW if the button is pressed and HIGH if it is not. We can get the current state of the button using

digitalRead(pushButton)

and we want to check if it is pressed (LOW):

if (digitalRead(pushButton) == LOW)

The complete code for the loop() would then be

    ...

    void loop() {

        // if button is pressed
        if (digitalRead(pushButton) == LOW){
            // turn on the LED
            digitalWrite(led, HIGH);
        } else {
            // else
            // turn off the led
            digitalWrite(led, LOW);
        }
    }

the general template for an if statement is

if (somecondition){
    statement1
    statement2
    statement3
} else {
    statement4
    statement5
}

So if some condition is true the computer executes statements 1, 2, and 3. If it is false it will execute 4 and 5. The braces {} delimit what statements to execute. In our case of the one LED, we execute just a single statement in the if (turning the LED on) and a single statement in the else (turning it off), but we could have as many statements as we need.

Let’s put this all together in our finished code:

    int led = 13;
    int pushButton = 3;

    void setup() {
      pinMode(led, OUTPUT);
      pinMode(pushButton, INPUT_PULLUP);
    }

    void loop() {

        // if button is pressed
        if (digitalRead(pushButton) == LOW){
            // turn on the LED
            digitalWrite(led, HIGH);
        } else {
            // else
            // turn off the led
            digitalWrite(led, LOW);
        }
    }

Work to Code

Recall that part of bullet 1, work to code, is that all lines within void setup and void loop need to be indented. A continuation of this practice is that all lines within an if block and an else block are indented as shown above. Again, if you come back to your code a week from now – or are seeking help now– it is easier to read the version above then this version:

    int led = 13;
    int pushButton = 3;
    void setup() {
    pinMode(led, OUTPUT);
    pinMode(pushButton, INPUT_PULLUP);}
    void loop() {
    if (digitalRead(button) == LOW){
    digitalWrite(led, HIGH);} else {
    digitalWrite(led, LOW);}
    }

Copy and paste the indented version of our code into the IDE. Then upload.

What You Should See

When you hold down the push button, those warm fuzzy feelings from the first experiment should happen again, and the LED should shine brightly. The LED will be off when the button is released.

More details

We have already been using digitalWrite to turn on an LED. When we see an expression containing parentheses like

    int redLed = 2;
    ...
    digitalWrite(redLed, HIGH);

we call the items within the parentheses arguments. In this digitalWrite example,

  • the first argument tells what pin we are writing to. In this case we are writing to redLed which equals pin 2.
  • the second argument tells what we are writing (or sending). HIGH means we are setting pin 2 to a positive voltage. LOW means we are setting it to ground.

Now let’s look at the argument for digitalRead.

    int button = 3;
    ...
    digitalRead(button);

If you look at the hardware you constructed you can see that when you press the button pin 3 is connected to ground (GND). If we do a digitalRead while pressing the button we will read LOW. If we do a digitalRead while not pressing the button we will read HIGH.

if statements

Imagine if your friend Clara said I’ll go to the party if Ann goes, else I’ll stay home. Now let me ask you a question. Barring unforeseen circumstances, if we see Ann at the party do we think Clara is there? And a second question. If we know Ann didn’t go, (and again barring unforeseen circumstances) do we think Clara went to the party? I imagine you have zero problems figuring this out.

Let’s now look at the psuedo code we wrote above:

Just looking at this we know, without any formal computer science training, what happens when we press the button.

Congratulations. You have fantastic intuitions about if-else statements. Now let’s look at this part of the loop part of our code:

    void loop() {

        // if button is pressed
        if (digitalRead(button) == LOW){
            // turn on the LED
            digitalWrite(led, HIGH);
        } else {
            // else
            // turn off the led
            digitalWrite(led, LOW);
        }
    }

The == means equal so we can read

  if (digitalRead(button) == LOW)

as meaning if the value when we read the button is LOW or even a more English-like description: if the button is pressed then

The braces ({}) delimited the block of code that should be executed if the if statement is true. In this case if the button is pressed we only execute one line:

  digitalWrite(led, HIGH);

If the button is not pressed we only perform the else block which turns off the led.

Again, the braces ({}) delimited the block of code that should be executed if the if statement is true. Suppose we want to turn on the redLED and blueLED and turn off the greenLED if the button is pressed. In that case we would put all three statements inside the braces {}:

  if (digitalRead(button) == LOW){
    //we pushed the button
    digitalWrite(redLED, HIGH);   //so turn on the redLED
    digitalWrite(blueLED, HIGH);  //so turn on the blueLED
    digitalWrite(greenLED, HIGH); //so turn off the greenLED
   }

question

What does the following do?

  if (pushButtonState == LOW) {}
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
  }
  else
  {
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
  }

and what about this one:

  int wait = 500;
  ...
  if (pushButtonState == LOW) {}
    digitalWrite(led, HIGH);
    delay(wait);
    digitalWrite(led, LOW);
    delay(wait);
  }
  else
  {
    digitalWrite(led, LOW);
  }

In the first case, if we press the button all three leds will be on and when we release the button the leds will be off. In the second example, if we press the button an led will blink.

Is it less or fewer?

Programming languages allow us to do the normal comparisons we might have seen in math classes:

expression name example meaning
== Equal age == 21 is age equal to 21?
!= Not Equal age != 21 Is the value of age not equal to 21?
< Less Than age < 21 Is age less than 21?
> Greater Than age > 21 Is age greater than 21?
<= Less Than or Equal to age <= 21 Is age less than or equal to 21?
>= Greater Than or Equal To age >= 21 Is age greater than or equal to 21?

So, for example, if the variable temperature represents the current temperature then


if (temperature < 90) {}
     digitalWrite(led, HIGH); //so turn on the LED
}
else
{
     digitalWrite(led, LOW);
}

would turn on the led if the temperature was less than 90.

A puzzler

Consider the following psuedocode

What happens in the following cases?

  1. only button1 is pressed
  2. only button2 is pressed
  3. both button1 and button2 are pressed
  4. no buttons are pressed

Take a moment to figure it out. When you are ready compare your intuitions to mine, highlight (select the region with your laptop trackpad) the following seemingly whitespace to reveal the answer.

Select the region right after this line.

I am hoping you are thinking that the led is turned on for case (3), only when both buttons are pressed. If only one of the buttons is pressed the led does not go on.

The code for this puzzler would be


    void loop() {

        // if button is pressed
        if ((digitalRead(button1) == LOW) &&
            (digitalRead(button2) == LOW)){
            // turn on the LED
            digitalWrite(led, HIGH);
        } else {
            // else
            // turn off the led
            digitalWrite(led, LOW);
        }
    }

As you can see the English and gets translated into computer code as && and the expressions that the && connects are bounded by parentheses.

Next, consider this version:

and let’s ask the same questions: What happens in the following cases?

  1. only button1 is pressed
  2. only button2 is pressed
  3. both button1 and button2 are pressed
  4. no buttons are pressed

Again, the answer can be revealed in the whitespace:

In this case in cases 1, 2, and 3 the led is on, and in case 4 it is off.

The English or is translated into computer code as || (we rarely type the vertical bar but it is there on the right of your laptop keyboard).

The code for this example would be


    void loop() {

        // if button is pressed
        if ((digitalRead(button1) == LOW) ||
            (digitalRead(button2) == LOW)){
            // turn on the LED
            digitalWrite(led, HIGH);
        } else {
            // else
            // turn off the led
            digitalWrite(led, LOW);
        }
    }

How to use Logic like a Vulcan:

With these building blocks the Arduino Uno can make complex decisions based on the input it is getting. Consider


    void loop() {

       if ((digitalRead(button1) == LOW) && (digitalRead(button2) == LOW)){
            // turn on the LED
            digitalWrite(redLed, HIGH);
            digitalWrite(blueLed, LOW);
            digitalWrite(greenLed, LOW);
        } else  if (digitalRead(button1) == LOW) {
            digitalWrite(redLed, LOW);
            digitalWrite(blueLed, HIGH);
            digitalWrite(greenLed, LOW);
         } else {
            digitalWrite(redLed, LOW);
            digitalWrite(blueLed, LOW);
            digitalWrite(greenLed, LOW);

         }
    }

And again, what happens in the following cases?

  1. only button1 is pressed
  2. only button2 is pressed
  3. both button1 and button2 are pressed
  4. no buttons are pressed

And the answer is ….

  1. 1. only the blue LED is on
  2. 2. no LEDs are on
  3. 3. only the red LED is on
  4. 4. no LEDs are on

Now if at this point, you are slightly confused, or just don’t care about all this, don’t fear throughout the course we are going to practice so we become a bit more fluent and are able to use Logic Like A Vulcan.

One of the things that makes the Arduino Uno (and any computer) so useful is that it can make complex decisions based on the input it’s getting. For example, you could make a thermostat that turns on a heater if it gets too cold, or a fan if it gets too hot, and it could even water your plants if they get too dry. As we have seen, in order to make such decisions, the programming language provides a set of logic operations that let you build complex “if” statements.

For example suppose we want to turn on an led only if the temperature is between 65 and 75 inclusive and the led should be off otherwise. We can do this using the AND operator &&:

  if ((temperature >= 65)  && (temperature) <=75){
    digitalWrite(led, HIGH); //so turn on the LED
  }
  else
  {
    digitalWrite(led, LOW);
  }

Using these logic operators, you can program your Arduino Uno to make intelligent decisions and take control of the world around it!

Remixes

Twosies

Add another LED and another button. Both LEDs should blink 200ms on and 200ms off only when both buttons are pressed. Otherwise both LEDs will be off.

Beyond Twosies

  • When both buttons are pressed both LEDs should blink 200ms on and 200ms off
  • When only button 1 is pressed, LED 1 should be on (steady – no blink)
  • When button 2 is pressed, LED 2 should be on (steady – no blink)

The Beats

We are going to use the patterns we constructed for experiment one: double tap, slow n fast, and Cylon. Here is the behavior of your circuit:

  1. when no buttons are pressed, no LEDs are on
  2. when button1 is pressed, the pattern is double tap
  3. when button2 is pressed, the pattern is slow n fast
  4. when button3 is pressed, the pattern is Cylon

1: Tutorials are CC BY-SA 4.0. Original page at Sparkfun Inventor’s Kit for Photon. This slight remix by Ron Zacharski.


Previous section:
Next section: