Project showcase

Arduino Button Troubleshooting © MIT

Using an Arduino to toggle something like an LED light is simple in theory, but buttons don't always behave the way we think.

  • 58 views
  • 0 comments
  • 0 respects

Components and supplies

Apps and online services

About this project

Introduction

I am making an Arduino Uno project that requires a push-button to be used as a toggle. To check that my Arduino code could tell when a button was being pressed, I wired up an LED with a push-button. When I tested it, I noticed that the LED didn't always behave as expected. If I pressed the button once, sometimes it would toggle (turn on or turn off) several times.

Project Details

I set one of the Arduino digital I/O pins as an input. Whenever the push-button is pressed, it sends a signal to that input pin. The code controls a digital output pin connected to a transistor, which supplies current to the LED. Every times the Arduino notices a signal from the button, it switches the output either on or off. So each click should result in the LED turning on or off. See the schematic and breadboard layouts below for how to implement this design.

Bouncy Buttons

After making certain that the circuit was properly designed, I knew this must be an issue with the button "bouncing". In a nutshell, bounce is when signals oscillate for a short period after a button press, and which causes the Arduino to see several button presses. In order to fix this, buttons need to be "debounced". For more details on this topic check out this projectI published about what bounce is and how to characterize it for a specific button or switch.

Using an OpenScope and WaveForms LiveI was able to see this in action. In the image below, the yellow line is the button signal, and the blue line is the LED signal. As you can see, the press (green vertical line) is followed by a moment when the button signal rises and falls again. The LED is initially turned on as it should, but then the button bounce causes the LED to be shut off again (the blue line being low means the LED is off).

I took a slow motion video of this happening, so you can see the LED light up briefly before it turns back off:

The second case, where the LED doesn't seem to turn off, is visible in the image below.

A video of the LED seemingly not turning off:

Solution

If the Arduino is instructed to wait a short period of time after the signal goes low before checking for the signal again, it'll probably miss any of the bounces caused by pressing the button. However, this only takes care of half the problem, since the Arduino will be triggered by bounce caused by releasing the button.

To debounce my button, I instructed the Arduino to toggle the LED when it sees the signal go low, delay 1ms to wait out any noise following the initial press, and then to do nothing until the signal goes high. Once it does, another 1ms delay accounts for any noise when the button is released.

I wanted to add one more layer of protection from signal noise by having the Arduino check if the signal is still low after a short period of time. This way, if the signal goes low, the Arduino waits 1ms, and then checks again to see if the signal is still low. If it is, the toggle operation described above is executed. If there's a random momentary drop in the signal, it'll be ignored by the Arduino.

The two images above show the behavior of the system after I changed the code. As you can see, the Arduino waits until after the noise is gone before turning on or off the LED.

See the code section for the debounced button code, as well as what I started off with. Below are two videos, showing the difference debouncing can make.

The LED doesn't always toggle with the button.

Every press is followed by a single toggling of the LED, as desired.

Code

Button Toggle DebouncedArduino
Arduino code to perform a toggle operation when it sees a button press, with the added feature of ignoring switching noise.
//set up I/O pins
//pin 2 will connect to the base of the NPN transistor and trigger the LED on/off
int LED = 2;

//pin 4 will be used to monitor the button
int SWTCH = 4;

//a boolean to keep track of the current state of the LED
bool LED_on;


void setup() {
  //set the respective pins as inputs and outputs
  pinMode(LED, OUTPUT);
  pinMode(SWTCH, INPUT);

  //initially turn on the LED
  digitalWrite(LED, HIGH);
  LED_on = true;
  
}

void loop() {
  //monitor the switch pin for a drop in voltage
  if(digitalRead(SWTCH) == 0){
    //wait for the signal to stabilize
    delay(1);

    //make sure the inital drop wasn't random noise
    if(digitalRead(SWTCH) == 0){
      
      //toggle the boolean...
      LED_on = !LED_on;

      //...which will toggle the LED
      if(LED_on){
        digitalWrite(LED, HIGH);
      }
      else{
        digitalWrite(LED, LOW);
      }

      //wait for the signal to go high again before doing anything else
      while(digitalRead(SWTCH) == 0){
      
      }

      //wait for the signal to stabilize
      delay(1);
    }
  }
}
Button ToggleArduino
Arduino code that was initially used to perform a toggle operation when there is a button press. The toggling is very unreliable because of signal noise. Used as an example of where the code started.
//set up I/O pins
//pin 2 will connect to the base of the NPN transistor and trigger the LED on/off
int LED = 2;

//pin 4 will be used to monitor the button
int SWTCH = 4;

//a boolean to keep track of the current state of the LED
bool LED_on;


void setup() {
  //set the respective pins as inputs and outputs
  pinMode(LED, OUTPUT);
  pinMode(SWTCH, INPUT);

  //initially turn on the LED
  digitalWrite(LED, HIGH);
  LED_on = true;
  
}

void loop() {
  //monitor the switch pin for a drop in voltage
  if(digitalRead(SWT) == 0){
    
    //toggle the boolean...
    LED_on = !LED_on;

    //...which will toggle the LED
    if(LED_on){
      digitalWrite(LED, HIGH);
    }
    else{
      digitalWrite(LED, LOW);
    }
}

Comments

Similar projects you might like

CPU and RAM Usage Monitor (Windows & Linux)

Project showcase by thesahilsaluja

  • 4,915 views
  • 17 comments
  • 14 respects

TFT Graphing: Live History Graphs

Project tutorial by Andrei Florian

  • 988 views
  • 3 comments
  • 13 respects

AWS - Arduino Weather Station

Project tutorial by GilettaStefano

  • 7,409 views
  • 11 comments
  • 27 respects

Arduino Sunflower: An Electronic Sun-Dancer

Project tutorial by SURYATEJA

  • 3,857 views
  • 2 comments
  • 12 respects

Backpack Alarm

Project tutorial by Tomi Chen

  • 3,191 views
  • 12 comments
  • 31 respects

HUD Alarm Clock

Project in progress by Chukwuemeka Ike

  • 207 views
  • 0 comments
  • 1 respect
Add projectSign up / Login