LOGBOOK

HELP

Quiz Entry - updated: 2026.10.20

"The LED is on while the button is held" and "each press toggles the LED" sound alike. Why is the second one harder to implement?

Following the button only copies the current level to the LED. Toggling has to detect the moment of a press (a 1 → 0 edge), remember the LED state between presses, and debounce. Otherwise one bouncing press toggles the LED several times.

Following is stateless. Each loop iteration reads the button and writes the same value to the LED. If the contacts bounce, the LED flickers for a few milliseconds, which nobody can see, and then matches the button again. Nothing goes wrong.

Toggling needs three things the follower does not:

  1. Edge detection. React to the change from released to pressed, not to the level. Holding the button must not keep toggling. The program has to remember the previous reading and compare.
  2. State. The LED's on/off value has to persist between presses, in a variable that survives loop iterations.
  3. Debouncing. Every bounce is an edge. Without debouncing, one press produces an even or odd number of toggles more or less at random.
int last = 1, led = 0;                         /* released, LED off */
while (1) {
    int now = gpio_get_level(BUTTON_GPIO);
    if (last == 1 && now == 0) {               /* falling edge = press */
        led = !led;
        gpio_set_level(LED_GPIO, led);
    }
    last = now;
    vTaskDelay(pdMS_TO_TICKS(20));             /* sample slower than the bounce */
}

Sampling every 20 ms acts as the debounce here: bounces of a few milliseconds fit between two samples and are never seen as separate edges.

Go deeper:

From Quiz: SIOT / GPIO Input and I2C Sensor Wiring on the ESP32 | Updated: Oct 20, 2026