Sourced from
docs/hardware/build-tft.mdin the firmware repo.
Build Guide - Touch TFT
How to construct the touch-screen Nimbus configuration from parts: a 2.8" ILI9341 240×320 color TFT with an XPT2046 resistive touch controller on the Solide S3 board (ESP32-S3-DevKitC-1 N16R8). The display and touch controller share the board's SPI3 pads, and the touch layer is the only input.

This page is the assembly walk-through. The companion pages:
- Touch TFT reference - the pinout drawing, touch calibration, screenshots, and the white-screen investigation.
- Hardware reference - everything common across the boards: first flash, shared peripherals, power, battery sensing.
Bill of materials
All commodity parts; any listing matching the Module / chip column works. Prices are approximate street prices in USD, excluding shipping. The consolidated parts list for all configurations, with the shared-parts breakdown and safety notes, is the bill of materials.
| Qty | Part | Module / chip | Notes | Purchase | ~Price |
|---|---|---|---|---|---|
| 1 | Dev board | ESP32-S3-DevKitC-1 N16R8 | 16 MB QIO flash, 8 MB octal PSRAM. The N16R8 variant specifically - octal PSRAM occupies GPIO 33–37. | AliExpress · Mouser | $12 |
| 1 | Display | 2.8" ILI9341 SPI TFT, 240×320, with XPT2046 resistive touch | The common SPI module with display pads (SCK/SDI/SDO/DC/RESET/CS/LED) plus a touch header (T_CLK/T_DIN/T_DO/T_CS/T_IRQ). Three on-module solder bridges are required - see below. | AliExpress | $8 |
| 1 | LED ring | WS2812B ring, 45 pixels | Addressable RGB; 5 V power, 3.3 V logic. | AliExpress | $6 |
| 1 | Amp | MAX98357A I²S amplifier breakout | Class-D, built-in thermal and over-current protection. | Adafruit 3006 · AliExpress | $2–6 |
| 1 | Speaker | 4 Ω · 3 W · ~40 mm full-range | The standard MAX98357A pairing; any small 4 Ω 3 W driver (28–45 mm) works. | AliExpress | $2 |
| 1 | Mic | INMP441 or ICS-43434 I²S MEMS mic breakout | Separate breakout from the amp. 3.3 V only - 5 V damages the S3. | AliExpress | $2 |
| 1 | Storage | microSD module (SPI) + microSD card | Card must be formatted FAT32 - see the trap below. | AliExpress + any 16–32 GB card | $6 |
| 2 | Cells | 18650 Li-ion | Wired in series (2S). Brand-name cells from a reputable vendor only. Reference pack: owner-measured 3500 mAh, 8.40 V full. | 18650batterystore.com | $12 |
| 1 | Charger/protection | 2S BMS with USB-C charging | Protection + balance + charging in one module. | AliExpress | $3 |
| 1 | Regulator | DC-DC converter → 5 V | From the 2S pack (~6.0–8.4 V) to a clean 5 V bus, ≥2 A. | AliExpress | $2 |
| 1 each | Battery sense | 220 kΩ + 100 kΩ resistors | Optional but recommended - the pack-voltage divider on GPIO 4. | any electronics supplier | $1 |
| - | Misc | wire, protoboard/PCB, JST connectors; optional 330 Ω resistor (LED DIN) and 1000 µF capacitor (ring 5 V/GND) | The resistor and capacitor improve LED reliability on long runs. | AliExpress | $5 |
Total: ≈ $59–63 (AliExpress-class sourcing; US distributors add ~$15–25).
The panel's touch layer is the only input.
Power architecture
- On battery: the DC-DC 5 V bus feeds the ESP32's VIN; the DevKit's on-board regulator makes the 3.3 V rail. USB-C on the BMS charges the pack.
- On USB alone (development): the DevKit runs from USB - the MCU, TFT, touch, SD, and mic all work. The LED ring will not light and the speaker will not drive audibly without the 5 V bus, which is the pack path.
- Every ground is common - tie all GNDs together: cells, BMS, DC-DC, ESP32, and every module.
- ⚠ The mic VCC is 3.3 V only. Its VDD and data lines follow VCC, and 5 V damages the S3's input. Never put the mic on the 5 V bus.
- ⚠ The TFT backlight is a continuous draw whenever it is lit. It sits on a PWM pin so the firmware's idle path blanks it rather than drawing a screensaver.
The three on-module solder bridges (do this first)
The XPT2046 touch header is not wired to three additional ESP32 GPIOs. Before wiring the module to the board, solder three short jumpers on the TFT module itself so touch and display share one SPI bus:
| Touch pad | Jumper to display pad | Shared ESP32 net |
|---|---|---|
T_CLK | SCK | GPIO 42 - SPI clock |
T_DIN | SDI | GPIO 41 - SPI MOSI |
T_DO | SDO | GPIO 1 - SPI MISO |
These are physical pad-to-pad connections on the module, not three more wires
to the DevKit. Connect T_CS separately to GPIO 48. Leave T_IRQ
unconnected; Nimbus polls the touch controller.
⚠ Continuity-check all three pairs with power disconnected. The ESP32 bus
wire may land on either pad of a pair, but both pads must be electrically
common. Missing bridges can leave the display completely blank (bus wires on
the touch-side pads) or leave the display working while touch is dead (bus
wires on the display-side pads). Also verify T_CS → GPIO 48 and confirm
T_IRQ has not accidentally been connected to GPIO 48.
Wiring
The whole build at block level - each peripheral with its bus and rail, and the battery chain along the bottom (the pin-by-pin tables follow):
Copied from the Touch TFT reference - the display and touch table first, then the shared peripherals from the solide-drivers build guide.
TFT + touch (SPI3)
| ESP32 GPIO | Net | Module pins |
|---|---|---|
| 42 | SPI clock | SCK + T_CLK |
| 41 | SPI MOSI | SDI + T_DIN |
| 1 | SPI MISO | SDO + T_DO |
| 40 | display D/C | DC |
| 39 | display reset | RESET |
| 38 | display CS | CS |
| 48 | touch CS | T_CS |
| 2 | backlight (PWM) | LED |
| - | not connected | T_IRQ |
| 3V3 / GND | power | VCC / GND |
The three on-module bridges make display and touch one SPI bus with two chip selects, which is what fits the whole panel into seven GPIOs.
microSD module (SPI2 - a separate bus)
| Module pin | → | ESP32 |
|---|---|---|
| VCC (3V3) | → | 3V3 |
| GND | → | GND |
| CS | → | GPIO 10 |
| MOSI (DI) | → | GPIO 11 |
| SCK (CLK) | → | GPIO 12 |
| MISO (DO) | → | GPIO 13 |
The SD is not on the TFT's SPI bus - they share only 3.3 V and ground.
WS2812B LED ring
| Module pin | → | ESP32 / rail |
|---|---|---|
| +5V | → | 5 V bus |
| GND | → | GND (common) |
| DIN | → | GPIO 21 (a 330 Ω series resistor on DIN is good practice) |
Audio - MAX98357A amp + I²S mic
Two separate breakouts. The amp runs at reduced volume on 3.3 V (fine as a status speaker); use the 5 V bus for more volume - but never share that VCC with the mic.
| Module | Pin | Role | → | ESP32 / rail |
|---|---|---|---|---|
| amp | VCC | power | → | 3V3 (5 V bus for louder) |
| amp | GND | ground | → | GND |
| amp | BCLK | bit clock |