Skip to content

ESP32-S3 Reasoning

Overview

The ESP32-S3 is well-suited for this application, offering the right balance of performance, I/O, and wireless capabilities. The specific part used is ESP32-S3-WROOM-1-N16R8 (LCSC C2913202) — 16 MB QSPI flash + 8 MB OPI (octal) PSRAM, integrated PCB antenna. The PCB footprint is the dual-compatible WROOM-1U outline (which accepts either the WROOM-1 PCB-antenna or WROOM-1U u.FL-connector variant); the V9 build assembles the PCB-antenna part. The -N16R8 suffix encodes the flash/PSRAM configuration.

Key Strengths

  • USB Native Support: Simplifies firmware upload and eliminates USB-serial converter requirements. Full-speed support with ESD protection and proper impedance control in the hardware.

  • Sufficient GPIO: Easily accommodates ADS1115, INA228, BMP388, LSM6DSOX IMU, opto-isolated UARTs, CAN transceiver, field driver PWM, and digital I/O without pin conflicts.

  • Ample RAM & Flash: 16 MB flash split across two app slots (factory + ota_0) and two web slots (factory_fs + prod_fs) plus a 3.8 MB userdata partition handles OTA updates, web file system, and buffered sensor data. The 8 MB PSRAM hosts every large buffer (sensor history ring, payload buffers, console queue, PID/CV/thermal logs, IMU ring, efficiency matrix). Internal RAM is reserved for FreeRTOS stacks and TLS handshakes.

  • WiFi Reliability: Supports AP and client mode with watchdog, reconnection logic, and captive portal setup. GPIO-pin overrides on GPIO45 (config), GPIO46 (AP), GPIO41 (factory partition) let users recover from a stuck/lost-password state without re-flashing.

  • Low Power Sleep Modes: When ignition is off and uploads are complete, the firmware drops the CPU from 240 MHz to 80 MHz and suspends TempTask, cutting idle current well below full-speed operation. By default WiFi is also turned off entirely; with the WiFi Standby (Keep Reachable) setting enabled (Client mode only) the radio instead stays associated in modem-sleep so the dashboard remains reachable at anchor for about 1 mA more than fully-off. Measured figures and the full state machine are in Operating Modes & Power.

  • Adequate Processing Power: Dual-core Xtensa LX7 @ 240 MHz handles:

    • Real-time control loop firing on every fresh CH1 ADC sample (~4.7 ms / 213 Hz)
    • 100 ms voltage CV loop
    • 5 s temperature PID
    • NMEA 2000 CAN parsing
    • Field PWM generation
    • Web server, SSE dispatch, real-time plots
    • Core 0 hosts a dedicated TempTask (DS18B20) and httpsTask (all TLS uploads, OTA, weather), leaving Core 1 free for the control loop. Watchdog timeout is 16 s on Core 1.

Hardware: Power Pins and Decoupling

Pin Net Notes
2 (3V3) 3V3 Single supply, 3.3 V from TLV62569 — see Switching Power Supply
1, 40, 41 (GND) GND Multiple ground pins all bonded to main GND plane
3 (EN) Net-(U19-EN) Pulled through R98 (330 Ω) to the RESET wire (RJ3 cable 4 pin 13) for manual reset

The S3 has only one external supply rail (3.3 V) and no separate analog supply. Module-level decoupling is handled inside the WROOM-1; the only external bypass caps are the standard 0.1 µF caps near the 3V3 pin.

Hardware: GPIO Allocation (V9 build)

GPIO Module pin Function Direction
IO1 39 IGNITION_ISO (engine ignition wake input via VO615A opto) IN
IO2 38 Status LED (GPIO2 net, drives an indicator LED) OUT
IO4 4 GPIO4 — uncommitted, broken out at connector
IO5 5 WakeFromDeepSleep (active-low to GND via switch panel) IN
IO6 6 UART_RX2_ISOL — NMEA0183 RX (via HCPL2531 ch 2) IN
IO7 7 UART_RX1_ISOL — Victron VE.Direct RX (via HCPL2531 ch 1) IN
IO8 12 EXTRA_OPTICAL_GPIO1_ISOL (spare opto input via VO615A) IN
IO9 17 I2C_SDA — shared bus to INA228, BMP388, LSM6DSOX bidir
IO10 18 I2C_SCL — same bus OUT
IO11 19 Unused — routed only to the unpopulated J3 debug header
IO13 21 TEMP_DQ — DS18B20 OneWire data (via 100 Ω series + 1 nF filter) bidir
IO14 22 OUT_PWM — alternator field PWM to LM5109A HI input OUT
IO16 9 GPIO16 — CAN RX from ISO1050 IN
IO17 10 GPIO17 — CAN TX to ISO1050 OUT
(USB D-) 13 ESP32_D- → USB-C via 22 Ω + USBLC6 bidir
(USB D+) 14 ESP32_D+ → USB-C via 22 Ω + USBLC6 bidir
IO21 23 BuzzerControl — to BC847 base via R38 OUT
IO39 32 HIGH/LOW_ISO (mode-select opto input) IN
IO40 33 FORCEFLOAT_ISO (mode-select opto input) IN
IO42 35 BMSLogic_ISO (BMS enable opto input) IN
IO3, IO12, IO15, IO18, IO38 15, 20, 8, 11, 31 EXTRA_3 / EXTRA_4 / EXTRA_5 / EXTRA_6 / EXTRA_7 (uncommitted, broken out via 330 Ω)
IO41 34 FactoryReset (active-low GND-style switch via 330 Ω) IN
IO45 26 WifiReset (active-low GND-style switch via 330 Ω) IN
IO46 16 AP/ClientMode (active-low GND-style switch via 330 Ω) IN
IO0 27 Boot mode select — broken out via 330 Ω to RJ3 cable 3 pin 8 for programming IN
RXD0 / TXD0 36 / 37 UART0 — Arduino serial monitor over USB-CDC bidir
IO35, IO36, IO37, IO47, IO48 28, 29, 30, 24, 25 Reserved by module — octal SPI PSRAM lines, must not be routed

Why every off-board GPIO has a 330 Ω series resistor: R56, R58, R71, R98, R100–R107 are all 330 Ω 0402 series resistors between the ESP32 pin and the connector. They limit fault current to ~10 mA if a user shorts an output to GND or applies 3.3 V to an unprotected input. This protects the ESP32 internal ESD clamps and is a routine practice for any GPIO exposed at a field connector.

Why IO35/36/37/47/48 are unconnected: On the N16R8 module these pins are bonded internally to the octal SPI interface that connects the ESP32 to the on-package PSRAM. They are not available for user use, even though some package diagrams show them. Attempting to use them will corrupt PSRAM access and crash the chip immediately.

Hardware: Reset and Boot

Function Mechanism
Power-on reset Internal POR — no external supervisor IC
Manual reset Ground the RJ3 cable 4 RESET wire, which pulls the EN pin through R98
Programming mode (DFU) Ground IO0 before reset (RJ3 cable 3 pin 8). Release IO0 after release of RESET.

In normal operation IO0 is left floating — the WROOM module pulls it high internally to select boot from SPI flash. The board does not auto-toggle IO0/RESET because the USB-CDC native programming path doesn't require it (the S3 enters DFU on host command). The manual override exists as a fallback for the rare case where firmware has locked up and can't enter DFU on USB request.

Hardware: RF Layout

  • Antenna is the integrated PCB trace on the WROOM-1 module substrate.
  • Module is placed at a board edge with the antenna pointing outward; the 5 mm copper-keep-out band on all sides of the antenna pattern is honored on the V9 layout.
  • WiFi performance through the wooden enclosure is excellent — wood is nearly transparent to 2.4 GHz, unlike a metal box. This was an explicit selection criterion.

See Also