Touchscreen DCC-EX Throttle controller running on ESP32-S3 with LVGL UI.
Use this map to find where network connections, discovered devices, and hardware devices are implemented.
main/main.cpp- App startup (
app_main), NVS init, LVGL init, touch input callback, display sleep/wake logic. - Starts Wi-Fi init task and shows initial screens.
- App startup (
main/utilities/WifiHandler.h- Defines
WithrottleDeviceand Wi-Fi manager APIs.
- Defines
main/utilities/WifiHandler.cpp- Connects to saved/manual SSID.
- Handles Wi-Fi events (
WIFI_EVENT,IP_EVENT). - mDNS search loop for
_withrottle._tcpdevices. - Stores discovered devices in
withrottle_devices.
main/connection/wifi_control.hWifiControlsingleton that owns DCC TCP connection state.
main/connection/wifi_control.cpp- Creates lwIP TCP connection to DCC server.
- Owns
DCCEXProtocollifecycle and polling loop task. - Handles disconnect/failure and publishes LVGL messages.
main/connection/wifi_connection.hTCPSocketStreamimplementation over lwIP TCP.- Heartbeat timeout checks and error callback handling.
main/connection/dcc_delegate.h- Delegate callbacks for roster, turnout, route, turntable, power, and loco updates.
main/connection/dcc_delegate.cpp- Converts incoming DCC-EX protocol events into app/UI updates.
main/display/WifiConnectScreen.*- Manual Wi-Fi connect UI.
main/display/WifiListScreen.*- Shows discovered Wi-Fi / mDNS DCC devices.
main/display/ConnectDCC.*- DCC connection screen and flow.
main/display/RosterList.*- Locomotive roster list UI.
main/display/TurnoutList.*- Turnout list and state changes.
main/display/RouteList.*- Route controls.
main/display/TurntableList.*- Turntable controls.
main/definitions.h- LVGL message IDs (
MSG_WIFI_*,MSG_DCC_*). - NVS namespaces/keys for calibration, Wi-Fi credentials, and saved DCC host/port.
- LVGL message IDs (
Display and touch pins are defined in main/LGFX_ILI9488_S3.hpp:
| Device | Signal | ESP32-S3 GPIO |
|---|---|---|
| ILI9488 LCD | SCLK | 12 |
| ILI9488 LCD | MOSI | 11 |
| ILI9488 LCD / XPT2046 touch | MISO | 13 |
| ILI9488 LCD | DC | 8 |
| ILI9488 LCD | CS | 10 |
| ILI9488 LCD | RST | 16 |
| LCD backlight (PWM) | BL | 4 |
| XPT2046 touch | CS | 9 |
Rotary encoder is enabled in this project sdkconfig and currently set to:
- A: GPIO 5
- B: GPIO 6
- SW: GPIO 7
Rotary defaults/options are configured via main/Kconfig.projbuild and idf.py menuconfig.
Diagram source: docs/wiring-diagram.dot (regenerate with dot -Tpng docs/wiring-diagram.dot -o docs/wiring-diagram.png).
flowchart LR
ESP[ESP32-S3]
LCD[ILI9488 LCD]
TOUCH[XPT2046 Touch]
ENC[Rotary Encoder]
ESP -->|GPIO12 SCLK| LCD
ESP -->|GPIO11 MOSI| LCD
ESP -->|GPIO13 MISO| LCD
ESP -->|GPIO8 DC| LCD
ESP -->|GPIO10 CS| LCD
ESP -->|GPIO16 RST| LCD
ESP -->|GPIO4 BL PWM| LCD
ESP -->|GPIO12 SCLK| TOUCH
ESP -->|GPIO11 MOSI| TOUCH
ESP -->|GPIO13 MISO| TOUCH
ESP -->|GPIO9 T_CS| TOUCH
ESP -->|GPIO5 A| ENC
ESP -->|GPIO6 B| ENC
ESP -->|GPIO7 SW| ENC
Pin source files:
main/LGFX_ILI9488_S3.hpp(LCD + touch)sdkconfig(current rotary encoder GPIO values)
This photo shows the assembled setup with:
- 3.5 inch SPI TFT display module
- ESP32-S3 development board
- Rotary encoder module with
CLK,DT,SW,+, and-pins
The rear silkscreen on the display board confirms these interface labels:
- Touch:
T_IRQ,T_DO,T_DIN,T_CS,T_CLK - TFT / SPI:
SDO(MISO),LED,SCK,SDI(MOSI),DC/RS,RESET,CS,GND,VCC - SD card header:
SD_SCK,SD_MISO,SD_MOSI,SD_CS
These photos are useful as the as-built hardware reference, while the pin table above remains the software pin mapping taken from the current source tree.
This project uses ESP-IDF and targets esp32s3.
- ESP-IDF v5.5.1 installed.
- USB connected ESP32-S3 board.
- Serial permissions (Linux user in
dialoutgroup, if required).
From project root:
cd /home/mathew/src/esp32-dcc-controller
source /home/mathew/.esp/v5.5.1/esp-idf/export.sh
idf.py set-target esp32s3
idf.py build
idf.py -p /dev/ttyUSB0 flash monitorNotes:
- Replace
/dev/ttyUSB0with your board port (for example/dev/ttyACM0). - Exit monitor with
Ctrl+].
- Open this folder in VS Code.
- Select the ESP-IDF target:
esp32s3. - Run
ESP-IDF: Build your project. - Run
ESP-IDF: Flash your project. - Run
ESP-IDF: Monitor your device.
If you are using a DCC turntable, you currently need these upstream pull requests until they are merged, if that happens:
DCC-EX/EX-TurntablePR 111:https://github.com/DCC-EX/EX-Turntable/pull/111DCC-EX/CommandStation-EXPR 517:https://github.com/DCC-EX/CommandStation-EX/pull/517
If you don't use those PR's then doing a 180 degree rotation will not work.
sdkconfig- active build configuration.partitions.csv- partition layout.main/idf_component.yml- external dependencies (LVGL, LovyanGFX, DCCEXProtocol, mdns, button).


