Most OpenMenuOS problems fall into four categories: display issues caused by TFT_eSPI misconfiguration, input issues from incorrect pin setup, memory issues that appear on ESP8266, and performance issues from blocking code or unoptimized rendering. Use the debug snippet at the bottom of this page as a first step with any new hardware setup.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/The-Young-Maker/OpenMenuOS/llms.txt
Use this file to discover all available pages before exploring further.
Display issues
Display issues
Blank screen on startupThe most common cause is a mismatch between your hardware wiring and the pin definitions in your TFT_eSPI
Wrong colors / inverted colorsColor inversion or channel swapping is a TFT_eSPI color-order setting. In
Flickering displayFlickering usually means the canvas is being pushed to the display on every frame, including frames where nothing changed. Enable frame comparison to skip redundant transfers:If flickering persists, check for conflicting SPI devices sharing the bus without proper CS management.
User_Setup.h file.- Open
libraries/TFT_eSPI/User_Setup.hand verify thatTFT_MOSI,TFT_SCLK,TFT_CS,TFT_DC, andTFT_RSTmatch your actual wiring. - Make sure you have selected the correct driver (e.g.
ILI9341_DRIVER,ST7789_DRIVER) for your display model. - Confirm the display is receiving the correct supply voltage (3.3 V for most SPI TFT modules when driven by ESP32/ESP8266).
Wrong colors / inverted colorsColor inversion or channel swapping is a TFT_eSPI color-order setting. In
User_Setup.h, try toggling:Flickering displayFlickering usually means the canvas is being pushed to the display on every frame, including frames where nothing changed. Enable frame comparison to skip redundant transfers:
Input issues
Input issues
Buttons not responding
Rotary encoder not workingEncoder support requires both CLK and DT pins to be registered beforeCheck that your encoder’s CLK and DT are not swapped — swapped wires reverse the direction but otherwise work. If the encoder is connected to pins that also have a boot-mode function on ESP32 (GPIO 0, 2, 15), move it to a different pin pair.
Multiple triggers per press (debounce)If a single button press registers two or more actions, the cause is usually electrical noise or a button without hardware debouncing. Software options:
- Verify the pin numbers passed to the
OpenMenuOSconstructor or configured withsetUpPin()/setDownPin()/setSelectPin()match the physical GPIO you wired. - Check the active voltage level. By default the library expects buttons to pull the pin low when pressed. If your buttons pull high, call:
- Confirm
INPUT_PULLUPis appropriate for your circuit. External pull-down resistors require the"High"mode.
Rotary encoder not workingEncoder support requires both CLK and DT pins to be registered before
menu.begin():Multiple triggers per press (debounce)If a single button press registers two or more actions, the cause is usually electrical noise or a button without hardware debouncing. Software options:
- Add a small capacitor (100 nF) between the button pin and GND.
- Use
INPUT_PULLUPmode with an internal pull-up, which helps reject noise on floating lines. - Avoid running long wires to buttons without shielding.
Memory issues
Memory issues
Crashes or watchdog resets on ESP8266The most common ESP8266 crash pattern is caused by enabling Monitor free heap to catch other memory pressure early:
Heap overflow / stack overflow
EEPROM / Preferences corruptionIf settings values read back as garbage after a firmware update or power loss, reset all stored settings to their defaults:EEPROM IDs are generated from a hash of each setting’s name and type. Renaming a setting or changing its type invalidates the stored value for that entry. Call
setOptimizeDisplayUpdates(true) on a large display. Frame comparison buffers the entire previous frame in heap RAM. A 320×240 16-bit display requires ~150 KB of heap — more than ESP8266 has available. Disable it:Heap overflow / stack overflow
- Keep
SettingsScreeninstances to 10 settings or fewer (MAX_ITEMS = 10). Exceeding this limit corrupts memory. - Avoid allocating
Stringobjects inside menu callbacks on every call. Usestaticlocal variables orconst char*literals. - Reduce the number of simultaneously active screens in the navigation stack.
EEPROM / Preferences corruptionIf settings values read back as garbage after a firmware update or power loss, reset all stored settings to their defaults:
resetSettings() whenever you change setting names in your sketch.Performance issues
Performance issues
Slow menu responseStart with the two most effective settings:
High CPU / SPI bus saturationIf the CPU usage is high even when the display is idle, enable frame comparison so unchanged frames are not pushed over SPI:
Jerky or stuttering animationsAnimations stutter whenAlso ensure
High CPU / SPI bus saturationIf the CPU usage is high even when the display is idle, enable frame comparison so unchanged frames are not pushed over SPI:
Jerky or stuttering animationsAnimations stutter when
loop() takes too long on individual iterations. The usual cause is blocking code — delay(), slow I2C reads, or heavy computation — that prevents the menu from updating smoothly. Audit your callbacks and loop() body for any blocking calls and replace them with non-blocking millis() patterns.PopupManager::update() is called before menu.loop() on every iteration. Calling them out of order can cause missed frames.Debug code snippet
Print key system information to Serial at startup to rule out configuration issues quickly:getSettingValue(int index) returns a uint8_t. For BOOLEAN settings, 0 = off and 1 = on. For RANGE and OPTION settings, the raw numeric value is returned.