Buttons can send many quick signals when pressed or released. Debouncing helps to clean these signals so the program reads just one press or release.
0
0
Button debouncing in software in Embedded C
Introduction
When reading a physical button press on a microcontroller.
To avoid multiple actions from a single button press.
When you want stable and reliable button input in your device.
To prevent errors caused by noisy button signals.
When building user interfaces with buttons on embedded systems.
Syntax
Embedded C
void debounce_button() {
static int button_state = 0;
static int last_button_state = 0;
static unsigned long last_debounce_time = 0;
unsigned long debounce_delay = 50; // milliseconds
int reading = read_button_pin();
if (reading != last_button_state) {
last_debounce_time = current_millis();
}
if ((current_millis() - last_debounce_time) > debounce_delay) {
if (reading != button_state) {
button_state = reading;
if (button_state == PRESSED) {
// Button pressed action
}
}
}
last_button_state = reading;
}This example uses a timer to check if the button state is stable for a set time.
Use static variables to remember states between function calls.
Examples
This function returns a stable button state after debouncing.
Embedded C
int debounce(int raw_button_state) { static int stable_state = 0; static int last_state = 0; static unsigned long last_time = 0; unsigned long delay = 50; if (raw_button_state != last_state) { last_time = current_millis(); } if ((current_millis() - last_time) > delay) { if (stable_state != raw_button_state) { stable_state = raw_button_state; } } last_state = raw_button_state; return stable_state; }
Use the debounce function to check button press safely.
Embedded C
if (debounce(read_button_pin()) == PRESSED) {
// Handle button press
}Sample Program
This program simulates noisy button presses and uses software debouncing to detect a clean press.
Embedded C
#include <stdio.h> #include <time.h> #define PRESSED 1 #define RELEASED 0 // Simulated button readings with noise int button_readings[] = {0, 1, 0, 1, 1, 1, 1, 1, 0, 0}; int index = 0; unsigned long current_millis() { return (unsigned long)(clock() * 1000 / CLOCKS_PER_SEC); } int read_button_pin() { if (index < sizeof(button_readings)/sizeof(button_readings[0])) { return button_readings[index++]; } return RELEASED; } int debounce() { static int button_state = RELEASED; static int last_button_state = RELEASED; static unsigned long last_debounce_time = 0; unsigned long debounce_delay = 50; // ms int reading = read_button_pin(); if (reading != last_button_state) { last_debounce_time = current_millis(); } if ((current_millis() - last_debounce_time) > debounce_delay) { if (reading != button_state) { button_state = reading; if (button_state == PRESSED) { return PRESSED; } } } last_button_state = reading; return RELEASED; } int main() { printf("Starting button debounce test...\n"); while (index < sizeof(button_readings)/sizeof(button_readings[0])) { if (debounce() == PRESSED) { printf("Button pressed detected!\n"); } } printf("Test finished.\n"); return 0; }
OutputSuccess
Important Notes
Debounce delay time (like 50 ms) can be adjusted depending on the button and hardware.
Using static variables inside the debounce function helps keep track of previous states.
Software debouncing is simple but may use CPU time; hardware debouncing is another option.
Summary
Button presses can be noisy and cause multiple signals.
Software debouncing waits for a stable signal before confirming a press.
This helps programs respond correctly to user button presses.