🔬

Button Debouncing

Lesson Objectives:

  1. Understand the behavior of a push button as an input device.
  1. Learn how to connect a button to Arduino and read its state.
  1. Explore the concept of signal noise and why debouncing is necessary.
  1. Learn both software and hardware debouncing techniques.
  1. Use Red Pitaya to visualize the noisy signal and analyze the effects of debouncing

Theory

Push Button Behavior

Push buttons are mechanical switches that temporarily connect two contacts when pressed. They're commonly used in embedded systems to trigger actions or change states.

Contact Bounce

When a button is pressed or released, its contacts don’t transition cleanly. Mechanical vibrations cause the signal to rapidly toggle between HIGH and LOW for a few milliseconds—this is called contact bounce.

Why Debouncing Is Needed

Without debouncing, a microcontroller may interpret these rapid transitions as multiple presses, leading to erratic behavior. Debouncing ensures only one clean press or release is registered.

Debouncing Techniques

  • Software Debouncing: Adds a delay (e.g., 50 ms) after detecting a state change to confirm stability.
  • Hardware Debouncing: Uses an RC circuit (resistor + capacitor) to smooth out the signal before it reaches the microcontroller.

Signal Visualization

Using Red Pitaya’s oscilloscope, you can observe:
  • Without Debouncing: Rapid spikes and unstable transitions (circled in red).
  • With Debouncing: Smooth, clean transitions.
    • notion image

Fall Time

Fall time is the duration for a signal to drop from 90% to 10% of its amplitude. Larger capacitors increase fall time and in turn improve stability, but be careful because they can delay signal recognition and introduce timing errors.

Hardware Setup

A. Materials Required:

  • Push button (Tactile Switch)
  • 10 kΩ resistor (Pull-down)
  • 0.1 µF capacitor (for hardware debouncing)
  • Arduino Uno (or similar)
  • Breadboard and jumper wires
  • Red Pitaya STEMlab 125-14 (for later visualization)

B. Circuit Assembly:

Connecting the Push Button (Without Hardware Debouncing):

  • Insert the push button on the breadboard.
  • Connect one terminal of the button to Arduino digital pin 2.
  • Connect the same terminal to ground through a 10 kΩ resistor (acting as a pull-down).
  • Connect the other terminal of the button to Arduino 5V.
notion image
notion image
 

Oscilloscope Connection:

  • Connect the probe tip of the Red Pitaya to the node at digital pin 2 (or at the junction before the pull-down resistor) and the ground clip to Arduino GND to visualize the signal.
notion image
 

C. Circuit Diagram:

notion image
 

Procedure

 
First, let’s install an IDE from:Done? Okay, let’s continue.

A. Without Debouncing:

Code:

Write a simple sketch that reads the raw button state and prints it to the Serial Monitor.
const int buttonPin = 2; // Button connected to pin 2 void setup() { pinMode(buttonPin, INPUT); // Configure pin 2 as an input Serial.begin(9600); // Start serial communication } void loop() { int buttonState = digitalRead(buttonPin); // Read the raw button state Serial.println(buttonState); // Print the state (HIGH or LOW) delay(10); // Small delay for readability }

Observation:

  • Observe fluctuations on the oscilloscope and rapidly fluctuating 1s and 0s on the Serial Monitor when pressing or releasing the button.
  • Discuss how these fluctuations are caused by contact bounce.

B. Software Debouncing:

Code:

Modify the sketch to include a simple software debounce.
const int buttonPin = 2; // Button connected to pin 2 int stableState = HIGH; // Initial stable state (using INPUT_PULLUP, HIGH means not pressed) int lastReading = HIGH; // Last raw reading unsigned long lastDebounceTime = 0; const unsigned long debounceDelay = 50; // 50 ms debounce delay void setup() { pinMode(buttonPin, INPUT_PULLUP); // Use internal pull-up resistor Serial.begin(9600); } void loop() { int currentReading = digitalRead(buttonPin); // If the reading changes, reset the debounce timer. if (currentReading != lastReading) { lastDebounceTime = millis(); } // If the reading has been stable for longer than debounceDelay, consider it the new stable state. if ((millis() - lastDebounceTime) > debounceDelay) { if (currentReading != stableState) { stableState = currentReading; // Print the debounced state (HIGH when not pressed, LOW when pressed) Serial.println(stableState); } } lastReading = currentReading; delay(10); // Short delay for readability }

How This Code Works:

  1. Initial Setup:
      • The button is connected with INPUT_PULLUP so that it reads HIGH by default and LOW when pressed.
  1. Reading and Debouncing:
      • The code reads the current state of the button (currentReading).
      • If this reading differs from the previous reading (lastReading), the debounce timer is reset.
      • Only if the reading remains stable for more than 50 ms (the debounceDelay), the new state is accepted and stored as stableState.
      • The debounced state is then printed to the Serial Monitor.
  1. Delay:
      • A short delay of 10 ms is included for readability and to avoid overwhelming the serial output.
This debouncing implementation filters out the rapid transitions caused by contact bounce, ensuring that each physical button press is registered as a single, clean transition.
 

Why Use millis() Instead of delay()?

Non-Blocking Timing:

  • delay():
    • When you use delay(), the program halts execution for the specified number of milliseconds. This makes it impossible to perform any other tasks during that period. In applications requiring multitasking (e.g., reading sensor data, updating displays, handling multiple inputs), using delay() can cause the system to become unresponsive.
  • millis():
    • The millis() function returns the number of milliseconds since the Arduino started running the current program. By using millis(), you can check how much time has passed without stopping program execution. This allows you to write non-blocking code that can handle multiple tasks concurrently.

Example in Debouncing:

  • In the debouncing code above, millis() is used to determine if the button state has remained stable for at least 50 ms before updating the stable state.
  • This approach ensures that while the program waits for the bounce to settle, it can continue to monitor the button and perform other tasks if necessary.

Flexibility and Responsiveness:

  • With millis(), you can implement multiple timers in the same program. This is essential for projects where you need to manage several time-dependent operations simultaneously.
  • Using millis() helps keep your program responsive to new inputs, as it doesn't halt the entire program flow.
 

C. Hardware Debouncing:

a. 0.1 µF Capacitor

  1. Setup:
      • Place the 0.1 µF capacitor between the button pin (Arduino pin 2) and ground.
      • Run the same raw reading code (no software debounce) to see the hardware effect.
  1. Oscilloscope Analysis:
      • The bouncing transitions should be shorter or less pronounced.
      • Fall Time: The signal will drop more slowly than without a capacitor, but not excessively.
        • notion image
      *remember: fall and rise times are measured from 90% to 10% of maximum signal amplitude.
      notion image
 

b. 1 µF Capacitor

  1. Setup:
      • Replace the 0.1 µF capacitor with a 1 µF capacitor.
      • Keep the same circuit and code.
  1. Oscilloscope Analysis:
      • Notice a longer fall time (and rise time) due to the larger capacitor.
      • The bouncing may be even more filtered, but the signal transitions are slower, leading to a noticeable “tail” on the oscilloscope.
        • notion image
  1. Trade-Off:
      • While a larger capacitor reduces bounce more effectively, it also extends the time it takes for the signal to change from HIGH to LOW (and vice versa). This can delay button recognition in fast applications.

Conclusion

Comparing Signals:

  • Discuss how the bouncing is visible in the raw reading.
  • Show how debouncing (both software and hardware) smooths out the signal.
  • Ask students which method they think is more suitable for their application and why.
notion image
notion image

Key Takeaways:

  1. Button Behavior:
      • Mechanical push buttons exhibit bouncing, causing multiple rapid transitions.
  1. Debouncing Importance:
      • Debouncing—whether implemented in software or hardware—is essential for reliable button readings in embedded systems.
  1. Visualization:
      • Tools like the Red Pitaya can help visualize and analyze the noisy signals, reinforcing the need for proper signal conditioning.

Real-World Application:

  • Discuss how accurate button detection is critical in applications such as keypads, industrial control panels, and consumer electronics.
  • Highlight that both software and hardware debouncing can be used, often together, to improve reliability.

Questions and Answers

Q1: What is contact bounce and why does it occur in push buttons?
A1: Contact bounce is the rapid, unintended toggling of the button state due to mechanical vibrations when a button is pressed or released. The contacts make and break the connection multiple times before settling, causing noisy signals.
Q2: How does software debouncing work?
A2: Software debouncing involves waiting a fixed amount of time (e.g., 50ms) after detecting a state change. The code then checks if the button state remains stable for that period before accepting the change, filtering out the rapid transitions caused by bouncing.
Q3: How does hardware debouncing using a capacitor help stabilize the button signal?
A3: A capacitor in parallel with the push button forms an RC circuit with the resistor, which smooths out rapid voltage fluctuations. When the button is pressed or released, the capacitor charges or discharges gradually, effectively filtering out the high-frequency bouncing and resulting in a smoother, more stable signal.
Q4: Why might you choose hardware debouncing over software debouncing, or vice versa?
A4: Hardware debouncing reduces the burden on the microcontroller and provides immediate signal smoothing, which can be more reliable in noisy environments. However, it requires additional components. Software debouncing is more flexible and easier to implement but consumes processing time and may not be as effective in extremely noisy conditions. Often, a combination of both methods yields the best results.
Q5: How does using an oscilloscope like the Red Pitaya help in understanding button behavior?
A5: The oscilloscope provides a visual representation of the button’s voltage signal. It shows the rapid spikes caused by bouncing and how the signal becomes smoother when debouncing is applied. This visualization helps in understanding the timing and magnitude of noise in the system, reinforcing the importance of debouncing.