Bird
Raised Fist0
Embedded Cprogramming~20 mins

Button debouncing in software in Embedded C - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Debounce Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of simple debounce logic
What is the output of this code snippet simulating a button press with software debounce?
Embedded C
#include <stdio.h>

int main() {
    int button_state = 0;
    int last_state = 0;
    int debounce_counter = 0;
    int stable_state = 0;

    int inputs[10] = {0, 1, 1, 0, 1, 1, 1, 0, 0, 1};

    for (int i = 0; i < 10; i++) {
        if (inputs[i] == last_state) {
            debounce_counter++;
        } else {
            debounce_counter = 0;
        }
        last_state = inputs[i];

        if (debounce_counter >= 2) {
            stable_state = last_state;
        }

        printf("%d", stable_state);
    }
    return 0;
}
A0000011111
B0000001111
C0000011100
D0000000000
Attempts:
2 left
💡 Hint
Look for when the input stays the same for at least 3 times (debounce_counter >= 2 means 3 stable reads).
🧠 Conceptual
intermediate
1:30remaining
Understanding debounce delay effect
In software button debouncing, what is the main purpose of introducing a delay or counter before accepting a button state change?
ATo speed up the button press detection for faster response
BTo ignore quick, unintended fluctuations caused by mechanical bounce
CTo reduce power consumption by delaying CPU cycles
DTo allow multiple button presses to be registered simultaneously
Attempts:
2 left
💡 Hint
Think about what happens physically when a button is pressed and released.
🔧 Debug
advanced
2:00remaining
Identify the bug in debounce implementation
What error does this debounce code cause when run?
Embedded C
#include <stdio.h>

int main() {
    int last_state = 0;
    int debounce_counter = 0;
    int stable_state = 0;
    int inputs[5] = {1, 1, 0, 0, 1};

    for (int i = 0; i < 5; i++) {
        if (inputs[i] != last_state) {
            debounce_counter++;
        } else {
            debounce_counter = 0;
        }
        last_state = inputs[i];

        if (debounce_counter >= 2) {
            stable_state = last_state;
        }

        printf("%d", stable_state);
    }
    return 0;
}
APrints 00000 (never updates stable_state)
BPrints 11111 (stable_state always 1)
CPrints 01010 (flips every input)
DCauses infinite loop
Attempts:
2 left
💡 Hint
Check the condition that increments debounce_counter and how stable_state is updated.
📝 Syntax
advanced
1:30remaining
Syntax error in debounce code snippet
Which option contains the correct syntax to implement a debounce check inside a loop?
Embedded C
for (int i = 0; i < 10; i++) {
    if (inputs[i] == last_state) {
        debounce_counter++
    } else {
        debounce_counter = 0;
    }
}
AReplace if with while to loop until stable: while (inputs[i] == last_state) { debounce_counter++; }
BChange for loop to while loop without initialization
CRemove else block entirely to avoid reset
DAdd a semicolon after debounce_counter++: debounce_counter++;
Attempts:
2 left
💡 Hint
Look carefully at the line with debounce_counter++ and check for missing punctuation.
🚀 Application
expert
2:30remaining
Calculate number of stable button presses detected
Given this debounce code and input sequence, how many times does the stable_state change from 0 to 1?
Embedded C
#include <stdio.h>

int main() {
    int last_state = 0;
    int debounce_counter = 0;
    int stable_state = 0;
    int count_presses = 0;
    int inputs[12] = {0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1};

    for (int i = 0; i < 12; i++) {
        if (inputs[i] == last_state) {
            debounce_counter++;
        } else {
            debounce_counter = 0;
        }
        last_state = inputs[i];

        if (debounce_counter >= 1 && stable_state != last_state) {
            stable_state = last_state;
            if (stable_state == 1) {
                count_presses++;
            }
        }
    }
    printf("%d", count_presses);
    return 0;
}
A4
B2
C3
D5
Attempts:
2 left
💡 Hint
Count how many times stable_state changes to 1 after 2 stable reads.

Practice

(1/5)
1. What is the main purpose of button debouncing in software?
easy
A. To ignore rapid, unwanted signals caused by mechanical button noise
B. To speed up the button press detection process
C. To increase the voltage of the button signal
D. To disable the button after first press

Solution

  1. Step 1: Understand button signal noise

    Mechanical buttons often create multiple quick on/off signals when pressed, called noise or bouncing.
  2. Step 2: Purpose of debouncing

    Debouncing waits for the signal to stabilize before confirming a press, ignoring these unwanted rapid signals.
  3. Final Answer:

    To ignore rapid, unwanted signals caused by mechanical button noise -> Option A
  4. Quick Check:

    Debouncing = Ignore noise [OK]
Hint: Debouncing filters noisy signals to detect one press [OK]
Common Mistakes:
  • Thinking debouncing speeds up detection
  • Confusing debouncing with hardware voltage changes
  • Assuming debouncing disables buttons
2. Which of the following code snippets correctly implements a simple software debounce delay in embedded C?
easy
A. if(button_pressed()) { delay_ms(0); if(button_pressed()) { /* valid press */ } }
B. if(button_pressed()) { delay_ms(50); if(button_pressed()) { /* valid press */ } }
C. if(button_pressed()) { delay_ms(-50); if(button_pressed()) { /* valid press */ } }
D. if(button_pressed()) { delay_ms(5000); if(button_pressed()) { /* valid press */ } }

Solution

  1. Step 1: Understand debounce delay

    A typical debounce delay is around 20-50 milliseconds to wait for signal stabilization.
  2. Step 2: Analyze code options

    if(button_pressed()) { delay_ms(50); if(button_pressed()) { /* valid press */ } } uses 50 ms delay, which is correct. if(button_pressed()) { delay_ms(0); if(button_pressed()) { /* valid press */ } } uses 0 ms (no delay), C uses negative delay (invalid), D uses 5000 ms (too long).
  3. Final Answer:

    if(button_pressed()) { delay_ms(50); if(button_pressed()) { /* valid press */ } } -> Option B
  4. Quick Check:

    Debounce delay ~50ms = if(button_pressed()) { delay_ms(50); if(button_pressed()) { /* valid press */ } } [OK]
Hint: Use ~50ms delay to confirm button press [OK]
Common Mistakes:
  • Using zero or negative delay
  • Using too long delay causing slow response
  • Not checking button state after delay
3. Consider this code snippet for debouncing a button press:
int debounce_button() {
  if (read_button_pin() == 0) {
    delay_ms(40);
    if (read_button_pin() == 0) {
      return 1;
    }
  }
  return 0;
}
What will debounce_button() return if the button is pressed and held steadily?
medium
A. 0
B. Random value
C. 1
D. Function will not return

Solution

  1. Step 1: Check initial button state

    The function checks if the button pin reads 0 (pressed).
  2. Step 2: Wait and re-check

    After 40 ms delay, it checks again. If still 0, it returns 1 indicating a valid press.
  3. Final Answer:

    1 -> Option C
  4. Quick Check:

    Stable press returns 1 [OK]
Hint: Stable press returns 1 after delay check [OK]
Common Mistakes:
  • Assuming immediate return without delay
  • Confusing 0 and 1 as pressed/released
  • Thinking function loops infinitely
4. This code is intended to debounce a button press but sometimes registers multiple presses. What is the likely problem?
if (read_button_pin() == 0) {
  delay_ms(10);
  if (read_button_pin() == 0) {
    button_pressed_flag = 1;
  }
}
medium
A. Delay of 10 ms is too short to filter bouncing
B. Button pin reading logic is inverted
C. Missing a delay after setting the flag
D. Using delay_ms instead of delay_us

Solution

  1. Step 1: Analyze debounce delay duration

    10 ms delay is often too short to filter mechanical bouncing which can last up to 50 ms.
  2. Step 2: Effect of short delay

    Short delay allows noise to pass, causing multiple press detections.
  3. Final Answer:

    Delay of 10 ms is too short to filter bouncing -> Option A
  4. Quick Check:

    Too short delay causes multiple presses [OK]
Hint: Use at least 20-50ms delay to debounce [OK]
Common Mistakes:
  • Assuming logic inversion causes multiple presses
  • Thinking delay after flag needed
  • Confusing delay units (ms vs us)
5. You want to implement a software debounce that counts how many times a button is pressed without counting bounces. Which approach below best achieves this?
hard
A. Increment count immediately on button press without delay
B. Increment count only when button is released
C. Use a 1ms delay and increment count on every read
D. Check button state, wait 50ms, check again; if still pressed, increment count and wait until release

Solution

  1. Step 1: Understand debounce counting logic

    To count presses without bounces, confirm stable press with delay, then count once.
  2. Step 2: Avoid multiple counts during one press

    Waiting until release before next count prevents multiple increments from one press.
  3. Final Answer:

    Check button state, wait 50ms, check again; if still pressed, increment count and wait until release -> Option D
  4. Quick Check:

    Stable press + wait release = correct count [OK]
Hint: Confirm press, count once, wait release before next count [OK]
Common Mistakes:
  • Counting immediately without debounce
  • Using too short delay causing multiple counts
  • Counting on release only misses presses
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard