FAQ
TL;DR: If your ESP32+LCD button still "does nothing," stop 1‑second polling and debounce; "These are intervals that are too long." Use EasyButton and correct pin wiring to avoid ghost toggles. [Elektroda, khoam, post #18286885]
Why it matters: This FAQ helps ESP32 DevKit builders fix flaky button-to-LCD behavior by addressing wiring, pin choices, debouncing, and blocking code.
Quick facts:
- Safe ESP32 DevKit V1 GPIOs for buttons: 26, 27, 32, 33; avoid boot‑strapping pins 0, 2, 12, 15; 34–39 are input‑only. [ESP32 Pinout Reference]
- Mechanical switch bounce typically lasts about 1–20 ms, so software debouncing is essential. [Ganssle, 2014]
- Using INPUT_PULLUP: connect one switch leg to GPIO and the other to GND; idle reads HIGH, press reads LOW. [pinMode()]
- delay(1000) makes the loop sample every 1 s, so quick presses are missed or flicker. [Elektroda, khoam, post #18286885]
- Most I2C LCD backpacks use address 0x27; confirm with an I2C scanner before coding. [I2C LCD with Arduino]
Quick Facts
- Safe ESP32 DevKit V1 GPIOs for buttons: 26, 27, 32, 33; avoid boot‑strapping pins 0, 2, 12, 15; 34–39 are input‑only. [*ESP32 Pinout Reference*]
- Mechanical switch bounce typically lasts about 1–20 ms, so software debouncing is essential. [Ganssle, 2014]
- Using INPUT_PULLUP: connect one switch leg to GPIO and the other to GND; idle reads HIGH, press reads LOW. [*pinMode()*]
- delay(1000) makes the loop sample every 1 s, so quick presses are missed or flicker. [Elektroda, khoam, post #18286885]
- Most I2C LCD backpacks use address 0x27; confirm with an I2C scanner before coding. [*I2C LCD with Arduino*]
How do I reliably toggle two messages on an ESP32 I2C LCD with a button?
Use debounced events and avoid blocking. 1) Create EasyButton on a safe GPIO and call button.begin(). 2) In loop(), call button.read() often and flip a boolean in onPressed(). 3) Update the LCD only when state changes; remove long delay() calls. This prevents missed presses and flicker while keeping the interface responsive. EasyButton abstracts debouncing and press/release detection so your loop stays simple and non‑blocking. [EasyButton]
Which ESP32 GPIO should I use for a button, and which should I avoid?
Use GPIO 26, 27, 32, or 33 for general buttons. Avoid boot‑strapping pins 0, 2, 12, and 15 because holding them in the wrong state can block boot. GPIOs 34–39 are input‑only and lack internal pull‑ups/downs, so plan external resistors if you use them for buttons. Selecting safe GPIOs prevents unexplained resets and non‑responsive inputs. [ESP32 Pinout Reference]
Should I use INPUT or INPUT_PULLUP for my button on ESP32?
Use INPUT_PULLUP when wiring the switch to GND. The pin idles HIGH and goes LOW when pressed. Use INPUT with an external pull‑down if wiring the switch to 3.3 V instead. Do not leave inputs floating, or you will get random toggles. This choice defines the logic levels your code should expect. [pinMode()]
Why does the LCD text alternate even when I don’t press the button?
That behavior is typical contact bounce or a floating input. When the switch vibrates, rapid on/off transitions look like multiple presses. Debounce in software with EasyButton and ensure the input has a defined idle level using INPUT_PULLUP or a proper external resistor. This stops phantom toggles. [Elektroda, khoam, post #18288467]
What is debouncing, and how long does button bounce last?
Debouncing filters the rapid open/close chatter that happens when a mechanical switch changes state. Typical bounce lasts about 1–20 milliseconds. Code that samples or processes every second will misinterpret that chatter. Use a debouncing library or a simple state machine with timing to ignore transitions during the bounce window. [Ganssle, 2014]
Why does digitalRead with delay(1000) miss my button presses?
You only sample the pin once per second, so short presses disappear between reads. As one expert noted, “These are intervals that are too long.” Replace delay() with non‑blocking timing and call the button’s read method frequently to capture events reliably. [Elektroda, khoam, post #18286885]
How should I use EasyButton’s isPressed() and isReleased() correctly?
Call button.read() on each loop iteration, then query isPressed() or isReleased(). Do not cache those results globally. As advised, “You should use the isPressed() and isReleased() functions in the loop().” Prefer the onPressed() callback to flip a state variable and update the LCD when it changes. [Elektroda, khoam, post #18290347]
My Serial Monitor reports a press every few seconds with no touch. What causes that?
Blocking code prevents frequent button.read() calls, so the library cannot debounce correctly. delay(), long LCD operations, or heavy I2C traffic starve the input scan and create phantom events. Keep loop() responsive and call button.read() often for stable behavior with callbacks. [EasyButton]
Can I use GPIO15 or GPIO12 for a button without breaking boot?
Be careful. GPIO12 and GPIO15 are boot‑strapping pins. Pulling them to the wrong level at reset can change boot mode or block startup. Prefer non‑strap pins like 26, 27, 32, or 33 for buttons, especially when using pull‑ups to GND. [ESP32 Pinout Reference]
Do GPIO34–39 need external resistors for buttons?
Yes. GPIO34–39 are input‑only and lack internal pull‑ups and pull‑downs. If you use them for a button, add an external resistor to define the idle level. Otherwise, the input will float and generate false triggers. [ESP32 Pinout Reference]
How do I confirm my I2C LCD address (0x27) is correct on ESP32?
Run an I2C scanner sketch first. It prints discovered addresses to Serial, so you can set the LCD constructor accordingly (e.g., 0x27 or 0x3F). Confirming the address avoids “no display” errors that look like logic issues but are wiring or address mismatches. [I2C LCD with Arduino]
Why does my button read LOW all the time?
You may be mixing pull‑ups and pull‑downs. If your hardware already pulls the pin to GND, do not also set INPUT_PULLUP. Use INPUT in that case, or rewire for INPUT_PULLUP with the switch to GND. A mismatched configuration forces a constant LOW. [Elektroda, khoam, post #18286393]