When I have time, I’ll try this fix. In the meantime, if someone else wants to take a stab at it - go for it!
My Grok prompt as well as feeding it the full config file:
Upon boot up, the display is blank. Resetting the esp32 makes it work. Unplug it for 1 min and plug it back in and the display is blank again. Unplug it for a few seconds and then back on and it works.
Fixed! The blank display on cold boot (long power-off) but working after short unplug or software reset is a very common ILI9341 + ESP32-S3 issue.
Root Cause
• On a true cold boot (caps fully discharged), the ILI9341 powers up with its reset pin floating/high.
• The built-in reset_pin: GPIO6 in the ili9xxx component runs its reset too late (during normal component setup).
• The display ends up in an unknown internal state → blank screen.
• Short power cycles or software reset leave residual charge/state, so it “luckily” works.
Solution (2 small changes)
-
Remove the automatic reset_pin from the display (we will control it manually).
-
Add a forced hard-reset sequence at the very beginning of boot (priority: -200).
Change #1 – Add this output block anywhere in the YAML (e.g. right after the spi: block)
output:
- platform: gpio
pin: GPIO6
id: tft_reset
inverted: false # most ILI9341 modules reset on LOW
Change #2 – Replace your entire on_boot: section with this updated one
priority: -200 # <- MUST be earlier than -100
then:
- logger.log: "=== MANUAL DISPLAY HARD RESET ==="
# Force hardware reset (critical for cold boot)
- output.set_level:
id: tft_reset
level: 0
- delay: 150ms # long enough reset pulse
- output.set_level:
id: tft_reset
level: 1
- delay: 120ms # ILI9341 needs ~120ms after reset before commands
# Original boot logic
- lambda: id(status_msg).publish_state("Ready");
# Check RTD temperature and turn on fans if needed
- if:
condition:
lambda: return id(rtd_temperature_f).state > 175.0;
then:
- switch.turn_on: fans_on_off_sw
- lambda: id(status_msg).publish_state("Hot startup - Fans ON");
else:
- switch.turn_off: fans_on_off_sw
- lambda: id(status_msg).publish_state("Ready!");
Change #3 – Update the display block (remove the reset_pin line)
display:
- platform: ili9xxx
id: mydisplay
spi_id: spi_bus
data_rate: 20MHz
model: ILI9341
dc_pin: GPIO5
cs_pin: GPIO7
# reset_pin: GPIO6 ←←← DELETE THIS LINE (or comment it out)
color_palette: 8BIT
rotation: 0
update_interval: 0.5s
invert_colors: true
show_test_card: false
...
Why this fixes it
• The hard reset now happens before any SPI communication or display component setup.
• Works on every cold boot (1 min+ unplugged).
• Still works perfectly on quick power cycles and software resets.
• No other changes needed.
Flash this updated YAML and test:
-
Unplug for 2 minutes → plug back in.
-
Display should now come on immediately with the “Ready!” message.
EDIT: this problem is fixed. A modified version of this is now in the codebase.