The Debounced Switch Guard
Change the slider level and observe the 5x5 LED display.
- Web browser (Chrome, Edge, Firefox)
- Internet connection
- MakeCode (micro:bit) online editor
🔧 Build Your Debounced Switch Guard
const int BUTTON_PIN = 2;
const int LED_PIN = 13;
int buttonState = HIGH;
int lastButtonState = HIGH;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50; // 50ms cooldown deadband
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
Serial.println("Debounced Switch Guard Ready.");
}
void loop() {
int reading = digitalRead(BUTTON_PIN);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == LOW) {
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Toggle LED
Serial.println("Stable press confirmed - clean trigger!");
}
}
}
lastButtonState = reading;
}
millis() timestamp comparison filters out sub-millisecond mechanical chatter without blocking execution.
⚗️ Test your model
| Test Condition / Action | Expected Result |
|---|---|
| Rapid Button Tap | LED toggles cleanly exactly once per press; no double-clicks |
| Hold Button Down | LED remains stable; does not flicker or oscillate |
| Electrical Noise | Mechanical contacts settle within 50ms; false transients ignored |
Change debounceDelay to 2ms to observe how mechanical noise causes double-counting, then set it to 40ms for optimal tactile response!
📖 Our Story & Concepts
When you press a physical push button, two flexible metal contacts touch inside. To human eyes, this looks instant. But at the microscopic level, the metal leaves bounce against each other violently dozens of times within 5 milliseconds before making stable contact.
Because microcontrollers execute millions of instructions per second, an undebounced input pin registers every microscopic bounce as an individual user click! In an automated voting booth or ATM keyboard, an undebounced switch would dispense 5 times the requested money or cast 10 duplicate votes. Software debouncing guarantees that only genuine, stable transitions trigger actions.
</> Full Annotated Code Walkthrough
// Complete Debounce Engine with Real-Time Event Counter
const int BUTTON_PIN = 2;
const int LED_PIN = 13;
int buttonState = HIGH;
int lastButtonState = HIGH;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;
unsigned int validPressCount = 0;
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
Serial.println("--- Switch Debounce Diagnostic System ---");
}
void loop() {
int reading = digitalRead(BUTTON_PIN);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == LOW) {
validPressCount++;
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
Serial.print("Clean Press #");
Serial.print(validPressCount);
Serial.print(" at Timestamp: ");
Serial.print(millis());
Serial.println(" ms");
}
}
}
lastButtonState = reading;
}
millis() timestamp comparison filters out sub-millisecond mechanical chatter without blocking execution.
▷ Expected Results & Troubleshooting
| Test Condition / Action | Expected Result |
|---|---|
| Rapid Button Tap | LED toggles cleanly exactly once per press; no double-clicks |
| Hold Button Down | LED remains stable; does not flicker or oscillate |
| Electrical Noise | Mechanical contacts settle within 50ms; false transients ignored |
⚑ Extension Challenges & Blueprints
- Level 1: Log the raw un-debounced transitions alongside clean debounced presses to measure bounce count.
- Level 2: Implement hardware debouncing using a 100nF ceramic capacitor in parallel with the switch.
- Level 3: Add long-press detection: holding for 2 seconds triggers a secondary action.