A two-MCU telemetry dash for a track car: trunk-side sensing and SD logging, a driver-facing 7″ display in the cabin, and a cloud service that takes every session from the car to lap charts, GPS maps, overlays and an AI coach.
racecar-35 is the data system for the car, not just a gauge. The trunk box senses the engine and chassis, logs everything to SD at full rate and ships each session to the cloud. The cabin screen (CrowPanel, ESP32-S3, 7″ 800×480) shows the driver what matters live — speed, RPM band, shift flash, best/last/delta timing, GPS heading and sensor warnings — and is the WiFi/OTA path for the whole car.
+--------------+ Serial2 (UART) +---------------+ Serial3 (UART) +---------------------+
| u-blox GNSS | <--------------> | Teensy 4.1 | <------------> | CrowPanel S3 7" |
| | 38400/9600 baud | trunk logger | 115200 8N1 | cabin display |
+--------------+ +-------+-------+ +----------+----------+
| |
SD logging / sensors WiFi |
SD chunks (Rev C) |
v v
+--------------------------+ +------------------------+
| ESP32-S3 NET module | | OTA + upload |
| (Rev C, SPI0, planned) | | fallback (working) |
+-----------+--------------+ +-----------+------------+
| HTTPS |
+------------+--------------------+
v
https://racecar.api.blueuc.com
FastAPI cloud receiver -- sessions, laps,
maps, overlays, AI coach, firmware OTA
Teensy 4.1 — GNSS, MPU-6050 IMU, tach, oil pressure, coolant (NTC) and AEM AFR inputs, microSD session logging, CAN capture.
CrowPanel Advance 7.0 (ESP32-S3) running the LovyanGFX dash UI. RGB332 framebuffer, delta bar, shift flash, sensor warnings, REC handshake watchdog.
Session upload and archive, automatic lap detection, line view, video overlay export, GPS basemap, CAN capture tools, AI race coach, firmware/OTA hosting and share links.
The current board is Rev C — a real, routed electrical design that has passed ERC/DRC and netlist checks. It is an unbuilt engineering prototype: it is not independently reviewed, not fabricated, and the new WiFi/RTC features it carries are not implemented in firmware yet.
| Revision | State | Notes |
|---|---|---|
| Rev A / Rev B | Retired | Archived under hardware/_archive/. Sources still supply render assets; not orderable designs. |
| Rev C | Current prototype | 130 × 140 mm, 136 PCB parts, 76 nets, 392 connected pads, 427 pin/geometry assertions, zero ERC/DRC and zero unconnected. All six screw terminals on one left edge. Gerbers, BOM and assembly docs exist in engineering-prototype (unapproved first-build) mode. |
| Rev D | In layout | Four-layer integrated trunk logger. BOM revision 1 fixed six unprocurable/mis-specified parts. |
| Ref | Function |
|---|---|
| J1 | POWER |
| J2 | SCREEN |
| J3 | TACH |
| J4 | OIL pressure |
| J5 | NTC coolant |
| J6 | AEM (AFR / lambda gauge output) |
Two PlatformIO projects in one repository, each with its own build environment.
| Project | Target | Path |
|---|---|---|
| Teensy firmware | Teensy 4.1 | platformio.ini, src/main.cpp |
| Dash UI | CrowPanel ESP32-S3 Advance 7.0 | crowpanel-ui/ (DASH_BOARD=71) |
| Version | What it brought |
|---|---|
| v0.1.149 | Opt-in AFR/lambda logging from the external AEM 30-0300 gauge output (white signal / brown reference) on a protected, clamped ADC input — not a direct oxygen sensor. |
| v0.1.148 | WiFi-only: Ethernet/W5500 support and the Internet-route setting removed; WiFi credentials and status always visible. |
| v0.1.147 | New dash layout (delta bar, BEST, GPS 3D, TIME), band-only shift flash, sensor-warning block, REC handshake watchdog, screen-side test simulator, RGB332 framebuffer (kills the shake). |
| v0.1.146 | CrowPanel Advance 7.0 board support; touch-debug UART0 prints stripped. |
| v0.1.144 | Speed up uploads; SD session history. |
$ pio run -t upload # Teensy 4.1 (tap the program button on first boot) $ cd crowpanel-ui && pio run -t upload # Dash UI
Important: disconnect the two UART jumpers between the Teensy and the CrowPanel before flashing the screen. UART0 (GPIO 43/44) is shared with the CH340 USB-serial chip, so with the Teensy connected both devices drive the same wire and the upload fails or corrupts. After a verified upload, unplug USB-C, reconnect the Teensy, then power the panel again.
Remote firmware is published from the same server: the dash downloads its own update and can push the matching Teensy image over UART.
Everything the car records lands here. Sign in with your team account to browse sessions, compare laps and read the coach notes.
Every uploaded run, sorted by car, track and date, with the raw NDJSON, sidecars and debug logs kept alongside the processed result.
Laps are found from the GPS line, timed, and can be excluded or renamed. Session histories roll up per driver and per car.
Two laps on one map, one drawn in red, with interpolated reference dots so a stepped sample never hides the real line.
Keyless basemap of the session line, with corner numbering from start/finish going LEFT/RIGHT, and named tracks you can edit.
Burns speed, RPM, lap delta and sensor readouts onto your camera footage for the same session file.
Corner-by-corner analysis with per-session history, so you can reopen a corner after a change and see whether it actually helped.
Upload and inspect raw CAN logs straight from the car's bus, decoded from the same server.
The server publishes build manifests; the dash pulls its own update over WiFi and can hand the Teensy image across UART.
Revocable read-only links for a single session, so a driver or a tuner can look without an account.
Google sign-in for people, per-device API keys for the cars, with visibility controls over who sees which driver's data.
The cloud receiver is a FastAPI service. Interactive API docs and the OpenAPI schema are available on the same host as the login.
| Endpoint | Purpose |
|---|---|
GET /health | Liveness probe for the service and its storage. |
GET /login | Browser sign-in (team account). |
POST /sessions | Car-side session upload (resumable), authenticated by device API key. |
GET /sessions | List the sessions you are allowed to see. |
GET /sessions/{user}/{file}/data | Processed channels for one session. |
GET /sessions/{user}/{file}/laps | Detected laps and timings, with exclusions. |
GET /sessions/{user}/{file}/lines | Line geometries for the map and comparisons. |
GET /sessions/{user}/{file}/ai | AI coach output history for the session. |
GET /coach/{user} | Coach queue and per-corner notes for a driver. |
GET /tracks | Known tracks and their start/finish definitions. |
GET /firmware/manifest.json | Published firmware builds for OTA updates. |
GET /account/apikey | Issue or rotate a device API key. |
GET /shared/{token} | Read-only shared session view. |
Base URL: https://racecar.api.blueuc.com. The legacy hostname stays live for
dash uploads; api.racecar35.com is the reserved replacement.
api.racecar35.com; dash uploads continue on the legacy address so nothing on the car has to change.