Skip to content

T-HMI MUI loses stable connection after light sleep — endless “Client wants config” reconnect loop #352

Description

@Goatmunch777

Category: Serial / Power Management
Hardware: LilyGo T-HMI (ESP32-S3, connected via UART to RAK4631 WisBlock)
Is this bug report about any UI component firmware like InkHUD or Meshtastic UI (MUI)? Meshtastic UI aka MUI colorTFT
Firmware Version: standalone-ui 2.7.20 (t-hmi-mui build)

Description:

After the T-HMI successfully connects to a RAK4631 over UART (Serial module, PROTO mode, 38400 baud, rxd=15/txd=16) and receives full config from the radio, it enters powersave/light sleep after a period of inactivity. After waking from this sleep state, the serial connection to the RAK4631 no longer completes a stable session. Instead, the T-HMI repeatedly re-sends "Client wants config" requests (nonce incrementing each time) and the RAK4631 correctly responds each time with full config, node list, and file manifest -- but the T-HMI never settles into a connected state. After 5 failed packet send attempts, the T-HMI gives up and re-enters powersave/sleep, repeating the cycle.

This matches the known open item on the device-ui roadmap: "Fix/Workaround serial light sleep UART reading issue (-> firmware)".

Steps to reproduce:

  1. Flash T-HMI with standalone-ui (t-hmi-mui environment)
  2. Wire T-HMI Grove port (GND/TX/RX) to RAK4631 UART1 header (GND/RXD1=15/TXD1=16), crossed
  3. Configure RAK4631 Serial module: enabled=true, rxd=15, txd=16, baud=38400, mode=PROTO
  4. Power on both devices, confirm initial connection succeeds
  5. Let the T-HMI sit idle until it enters powersave and sleeps (around 30 seconds of inactivity based on default timeout)
  6. Wake the T-HMI (button press)
  7. Observe: T-HMI re-requests config repeatedly (nonce increments each time) but never reaches a stable connected UI state

Expected behavior:
T-HMI should reconnect cleanly to the already-configured RAK4631 after waking from sleep, without needing to endlessly re-request full config.

Actual behavior:
T-HMI loops indefinitely between "request config / receive config / fail to stabilize / sleep" without ever reaching the normal connected home screen.

Additional notes:

  • Confirmed via multimeter continuity testing that physical wiring (GND/TX/RX) is correct and not the cause
  • Confirmed RAK4631 Serial module settings are correct and unchanged throughout testing (reconfirmed via Meshtastic Android app)
  • Full flash erase (esptool erase_flash) followed by clean reflash of t-hmi-mui did not resolve the issue -- behavior is identical on a completely wiped/reflashed device, ruling out corrupted flash/filesystem state as the cause
  • RAK-side debug log below shows the RAK correctly receiving "Client wants config" and successfully sending full config/nodeinfo/file manifest on every attempt -- the RAK is not at fault
  • T-HMI-side debug log below shows repeated "SerialClient::send() push packet N to server" attempts (1 through 5) followed by "enter powersave" / "going to sleep, wake up on GPIO00"

==================================================
LOG 1: T-HMI SIDE

Disconnected (device reports readiness to read but returned no data (device disconnected or multiple access on port?))
Reconnecting to /dev/ttyACM0 .. Connected!
[ 433][I][esp32-hal-psram.c:96] psramInit(): PSRAM enabled
INFO | 00:00:02 2 [TFT]
//\ E S H T /\ S T / C U I - 2.7.20

[ 2456][I][esp32-hal-i2c.c:75] i2cInit(): Initialising I2C Master: sda=17 scl=18 freq=400000
DEBUG | 00:00:02 2 [TFT] I2C-1 not configured
DEBUG | 00:00:02 2 [TFT] ESP32 Chip ID = 081A F604A7AC
DEBUG | 00:00:02 2 [TFT] Flash size: 16777216 bytes
DEBUG | 00:00:02 2 [TFT] Heap size : 316704 bytes
DEBUG | 00:00:02 2 [TFT] Free heap : 290524 bytes
DEBUG | 00:00:02 2 [TFT] PSRAM : 8386295 bytes
DEBUG | 00:00:02 2 [TFT] PSRAM max : 8257524 bytes
DEBUG | 00:00:02 2 [TFT] DeviceScreen::init()...
DEBUG | 00:00:02 2 [TFT] TFTView_320x240 init...
DEBUG | 00:00:02 2 [TFT] Display driver init...
DEBUG | 00:00:02 2 [TFT] LGFXDriver::init...
DEBUG | 00:00:02 2 [TFT] LGFX init...
DEBUG | 00:00:02 3 [TFT] DisplayDriver init...
DEBUG | 00:00:02 3 [TFT] LV init...
DEBUG | 00:00:02 3 [TFT] LVGL display driver init...
DEBUG | 00:00:02 3 [TFT] LVGL: allocating 57600 bytes PSRAM for draw buffer (max free PSRAM: 3080180)
DEBUG | 00:00:02 3 [TFT] Input driver init...
DEBUG | 00:00:02 3 [TFT] I2CKeyboardScanner scanning...
DEBUG | 00:00:02 3 [TFT] No I2C keyboards found
DEBUG | 00:00:02 3 [TFT] Panel id=0x00000000 (320x240): rst:-1, busy:-1, offX:0, offY:0 invert:0, RGB:0, rotation:0, offR:1, read:1, readP:8, readB:1, dlen:0, colordepth:16
DEBUG | 00:00:02 3 [TFT] Bus_Parallel8
DEBUG | 00:00:02 3 [TFT] Touch int:9, rst:-1, rotation:0, (300/400)-(3900/3900)
DEBUG | 00:00:02 3 [TFT] Touch SPI(2): cs:2, clk:1, mosi:3, miso:4
DEBUG | 00:00:02 3 [TFT] BL pin assigned
INFO | 00:00:02 3 [TFT] UARTClient::init SERIAL1 baud=38400
[ 3267][V][esp32-hal-uart.c:330] uartBegin(): UART1 baud(38400) Mode(800001c) rxPin(15) txPin(16)
[ 3287][V][esp32-hal-uart.c:416] uartBegin(): UART1 not installed. Starting installation
[ 3296][V][esp32-hal-uart.c:467] uartBegin(): UART1 initialization done.
INFO | 00:00:02 3 [TFT] UARTClient::setPins rx=15, tx=16 with 38400 baud
DEBUG | 00:00:02 3 [TFT] serial client connecting...
DEBUG | 00:00:02 3 [TFT] scanning log folder /messages
DEBUG | 00:00:02 3 [TFT] log_000001.log(584 bytes)
INFO | 00:00:02 3 [TFT] LogRotate: found 1 log files using 584 bytes (0%).
INFO | 00:00:02 3 [TFT] Logging to /messages/log_000001.log
[ 3347][E][vfs_api.cpp:105] open(): /littlefs/boot/logo.png does not exist, no permits for creation
DEBUG | 00:00:02 3 [TFT] DeviceScreen::init() done.
DEBUG | 00:00:02 3 [TFT] Free heap : 268480 bytes
DEBUG | 00:00:02 3 [TFT] PSRAM : 3085339 bytes
DEBUG | 00:00:02 3 [TFT] Setup done.
DEBUG | 00:00:05 6 [TFT] SerialClient::send() push packet 1 to server
DEBUG | 00:00:12 12 [TFT] SerialClient::send() push packet 2 to server
DEBUG | 00:00:22 22 [TFT] SerialClient::send() push packet 3 to server
DEBUG | 00:00:22 22 [TFT] SerialClient::send() push packet 4 to server
DEBUG | 00:00:32 32 [TFT] SerialClient::send() push packet 5 to server
INFO | 00:00:33 33 [TFT] enter powersave
DEBUG | 00:00:33 33 [TFT] disable touch, enable button input
INFO | 00:00:33 33 [TFT] going to sleep, wake up on GPIO00

==================================================
LOG 2: RAK4631 SIDE

Reconnecting to /dev/ttyACM0 ....................................... Connected!
WARN | ??:??:?? 23 [GPS] No GNSS Module (baudrate 38400)
DEBUG | ??:??:?? 25 [GPS] Trying $PDTINFO (Unicore Family)...
DEBUG | ??:??:?? 26 [GPS] Trying $PCAS06,11A (ATGM33xx Family)...
DEBUG | ??:??:?? 26 [GPS] Trying $PAIR021
39 (Airoha Family)...
DEBUG | ??:??:?? 27 [GPS] Trying $PQTMVERNO58 (LC86)...
DEBUG | ??:??:?? 28 [GPS] Trying $PCAS06,0
1B (L76K)...
DEBUG | ??:??:?? 28 [GPS] Trying $PMTK605*31 (MTK Family)...
INFO | ??:??:?? 29 [Serial] Client wants config, nonce=1
DEBUG | ??:??:?? 29 [Serial] State: SERIAL
INFO | ??:??:?? 29 [Serial] Disable NRF52 bluetooth
DEBUG | ??:??:?? 29 [Serial] Got 7 files in manifest
INFO | ??:??:?? 29 [Serial] Start API client config millis=29481
DEBUG | ??:??:?? 29 [Serial] FromRadio=STATE_SEND_MY_INFO
INFO | ??:??:?? 29 [Serial] getFromRadio=STATE_SEND_UIDATA
DEBUG | ??:??:?? 29 [Serial] Send My NodeInfo
DEBUG | ??:??:?? 29 [Serial] Send device metadata
DEBUG | ??:??:?? 29 [Serial] Send channels 8
DEBUG | ??:??:?? 29 [Serial] Send config: device / position / power / network / display / lora / bluetooth / security / sessionkey
DEBUG | ??:??:?? 29 [Serial] Send module config: mqtt / serial / ext notification / store forward / range test / telemetry / canned message / audio / remote hardware / neighbor info / ambient lighting / detection sensor / paxcounter
DEBUG | ??:??:?? 30 [Serial] nodeinfo: 20/60
DEBUG | ??:??:?? 31 [Serial] nodeinfo: 40/60
DEBUG | ??:??:?? 31 [Serial] nodeinfo: 60/60
DEBUG | ??:??:?? 31 [Serial] Done sending 60 of 60 nodeinfos millis=31810
DEBUG | ??:??:?? 31 [Serial] FromRadio=STATE_SEND_FILEMANIFEST
DEBUG | ??:??:?? 31 [Serial] File: channels.proto (105) bytes / device.proto (124) bytes / module.proto (134) bytes / ringtone.proto (9) bytes / uiconfig.proto (31) bytes / nodes.proto (6804) bytes / config.proto (241) bytes
INFO | ??:??:?? 31 [Serial] Config Send Complete millis=31875
DEBUG | ??:??:?? 31 [Serial] FromRadio=STATE_SEND_PACKETS
WARN | ??:??:?? 32 [GPS] No GNSS Module (baudrate 9600)

[... sequence repeats: "Client wants config, nonce=2" at millis=35333, full config resend, complete at millis=37726 ...]
[... sequence repeats again: "Client wants config, nonce=3" at millis=45887, full config resend, complete at millis=48287 ...]
[... sequence repeats again: "Client wants config, nonce=4" at millis=55678, full config resend, complete at millis=58071 ...]

(Meanwhile the RAK is functioning completely normally as a mesh node throughout -- receiving/relaying LoRa packets from other nodes, sending its own telemetry. This confirms the RAK's LoRa radio and general firmware are healthy; only the serial handshake with the T-HMI client fails to stabilize.)

Example of normal RAK mesh activity occurring in parallel with the failed nonce loop:

DEBUG | ??:??:?? 53 [RadioIf] Corrected frequency offset: 320.656250
DEBUG | ??:??:?? 53 [RadioIf] Lora RX (id=0x7d879fa4 fr=0x5e34ebef to=0xffffffff, ... rxSNR=6.75 rxRSSI=-2 ...)
DEBUG | ??:??:?? 65 [DeviceTelemetry] Send: air_util_tx=0.026889, channel_utilization=3.226666, battery_level=101, voltage=4.148000, uptime=65
DEBUG | ??:??:?? 65 [Power] Battery: usbPower=1, isCharging=1, batMv=4182, batPct=99

==================================================
END OF LOGS

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions