- name
- flash
- description
- Build, upload, and monitor firmware on the ESP32-C3. TRIGGER when the user asks to flash the device, check serial output, build firmware, set up OTA, or debug a build/upload failure. DO NOT trigger for host-side test runs (use /tdd) or for hardware wiring questions (use /hardware).
# Flash & monitor — ESP32-C3
## Environments
`platformio.ini` defines two environments:
| Env | Target | Purpose |
|---|---|---|
| `esp32c3` | Seeed XIAO ESP32-C3 / DevKitM-1 | Real firmware |
| `native` | Host (Mac) | Unit tests only — see `/tdd` |
Always specify `-e` explicitly. Forgetting it builds both and confuses errors.
## Build
```bash
pio run -e esp32c3 # compile only
pio run -e esp32c3 -v # verbose — use when link errors are obscure
```
A clean rebuild:
```bash
pio run -e esp32c3 -t clean && pio run -e esp32c3
```
## Upload over USB
ESP32-C3 has built-in USB-serial-JTAG. No DTR/RTS reset dance; `esptool`
triggers via USB CDC. Plug into the Mac's USB-C port directly.
```bash
pio run -e esp32c3 -t upload
```
If upload fails with `Failed to connect`:
1. Check `ls /dev/tty.usbmodem*` — the port must appear
2. Try holding BOOT on the board while initiating upload (rare on C3)
3. Lower baud: add `upload_speed = 460800` to `platformio.ini`
## Serial monitor
```bash
pio device monitor -b 115200
```
Exit: `Ctrl-C` then `Ctrl-]`. Or use `pio device monitor --filter=esp32_exception_decoder`
to get readable crash backtraces.
## LittleFS (config / buffered batches)
```bash
pio run -e esp32c3 -t buildfs # build the FS image from data/
pio run -e esp32c3 -t uploadfs # flash the FS image (wipes existing FS)
```
**`uploadfs` is destructive** — it erases any buffered batches stored on the
device. Don't run it on a unit that's been collecting data in the field
without first pulling the ring buffer contents via `scripts/decode_capture.py`
over serial.
## OTA (once wifi is up)
After the device has been provisioned once, OTA is the preferred path — you
don't want to climb to the mast to re-flash.
```bash
pio run -e esp32c3 -t upload --upload-port imu4.local
```
OTA requires the device to be on `BigAir2.4` and reachable. If OTA is
unavailable (wifi down, firmware panicking in boot), fall back to USB.
## Reading a crash backtrace
ESP32-C3 panics print a register dump and a backtrace of PC addresses. The
monitor filter decodes them against the ELF:
```bash
pio device monitor --filter=esp32_exception_decoder
```
If the filter isn't showing symbols, confirm the build on the device
**matches** the ELF at `.pio/build/esp32c3/firmware.elf`. A mismatch after
OTA means you're decoding against the wrong binary.
## Known gotchas
- **ESP32-C3 is RISC-V**, not Xtensa — exception decoder output looks
different from ESP32 classic. Don't paste C3 backtraces into classic
decoders
- **USB CDC and Serial share the same peripheral** — if `Serial.begin()`
is missing or runs too late, you won't see early boot logs. Use
`CORE_DEBUG_LEVEL=5` in `platformio.ini` for verbose core logging
- **`monitor_filters = esp32_exception_decoder` in `platformio.ini`** is
preferred over the CLI flag — it persists across invocations
Ver no GitHub