Exercise 3

Button Trigger

Add a button trigger to the binary counter.

Learning Goals

  • Understand digital input
  • State change detection
  • Counting logic
  • FOR loops

So far, we have explored the basics of digital output (LEDs) and analog input (potentiometer) and some other necessary principles and techniques.

Keep in mind that those are only one example each of inputs and outputs. There are other digital outputs besides LEDs, and other analog sensors (temperature, light, etc.). The methods for controlling them are similar to what you have developed already.

The next topic is that of digital input. This includes things like switches or buttons, which are either open or closed. Now we want to explore how sensing these digital input devices will allow us to create more interactive behaviors.

We’re going to return to the binary counter of Exercise 1 and use that as a base to interactive input to the system. We’ll add a button to the circuit, and code to detect when the button is pressed. Then we can take action based on when the user signals something by pressing the button, triggering an event.

Your task is make the binary counter step up one number each time the button is pressed, and control the LEDs as before in a counting pattern. For “extra credit,” you could add a second button that steps the counter down (or backwards) each time it is pressed.

click to view larger

Here is a picture of how to wire the circuit on your breadboard for the button to be connected to pin 2 on the Arduino. Use a 10K (10,000) ohm resistor for this circuit. This picture was made with an open-source circuit editing program known as Fritzing that was specifically designed for Arduino applications.

The code to detect button presses requires using a technique known as state change detection. Because the basic Arduino language doesn’t provide high-level constructs like event-handling that exist in other languages, we have to do this ourselves in our code. It’s a bit painful.

I suggest you look at the example sketch below to get started with this. This program simply handles detecting a button press and then flashes one LED to indicate the number of times the button has been pressed. You will have to modify it to do the logic of counting as described above, and to display the numbers in binary. You can copy and paste this code into a new Arduino sketch, and then save it.

/* ButtonTrigger
 ahdavidson
 4/25/11

 This program detects when the button has been pressed and uses that to trigger
 some action.

 Based on the StateChangeDetection example, by Tom Igoe

 */

// constants to make the code more readable
const int buttonPin = 2;    // the pin that the pushbutton is attached to
const int ledPin = 13;       // the pin that the LED is attached to

// variables that are changed by the program
int buttonPushCounter = 0;   // counter for the number of button presses

int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

// configure the pins to the right mode
void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

// the main loop will constantly check to see if the button has been pressed
// if it has, a counter is incremented, and then some action can be taken
void loop() {

  // read the state of the button
  buttonState = digitalRead(buttonPin);

  // check to see if it different than the last time we checked
  if (buttonState != lastButtonState) {
    // either the button was just pressed or just released

    if (buttonState == HIGH) {

      // it was just pressed
      buttonPushCounter = buttonPushCounter + 1;

      // anything you put in here will be happen each time the button is pushed
      // this example flashes the LED the number of times the button has been pushed so far
      for (int i = 0; i < buttonPushCounter; i++) {
        digitalWrite(ledPin, HIGH);
        delay(250);
        digitalWrite(ledPin, LOW);
        delay(250);
      }

    }
  }

  // this is necessary to be able to detect the triggering
  lastButtonState = buttonState;
}

click to view larger

Here is some pseudo-code for the algorithm you will have to construct to have the button presses trigger the binary counting. Pseudo-code is not a literal script for the Arduino code. It is a sketch for how to think about developing an algorithm, which you can then translate into code. This approach is often useful for working out complex problems before starting to get bogged down in how to express the solution in code.

And speaking of solutions, here is mine for this exercise: ButtonTriggerBinary.

This exercise, while seemingly simple conceptually, is actually devilishly complicated if you haven’t seen this kind of logic before. So don’t worry if it seems hard.

If you have seen it before, here is an advanced topic to explore: debouncing. You may notice that detecting when the button is up or down is not 100% accurate. That is because a device like a digital switch has a lot of noise in its operation. This means that because of the cheap electrical contacts in such a small device, the connection when the button is being pressed tends to bounce between open and closed quite a lot even in a short time interval. And your main loop in an Arduino program is checking that button state many thousands of time each second.

So the button state needs to be “debounced,” or filtered so that we only get a high or low signal reliably when the button is really all the way up or all the way down. This exercise can be down without debouncing and it works mostly OK, but if you do anything more complex or demanding, you have to debounce your buttons. There is a Debounce tutorial on the Arduino website, and another one on the Adafruit site.