ESP32-based Honda OBD live dashboard for B16 / P30-class ECUs (pre-2002 Honda 3-pin DLC K-line). The ESP32 reads the K-line directly, runs a WiFi hotspot, serves a PWA dashboard from flash, and streams live gauges + error codes over WebSocket.
Built on the Honda K-line core from ArduinoHondaOBD
(hobd_uni), with the single-board ESP32 + PWA direction developed on
softr8/ArduinoHondaOBD. This repo is
ESP-only — no ATmega, LCD, Bluetooth, or Torque path.
Honda ECU --K-line 9600 8N1--> L9637D --UART2--> ESP32 (firmware/)
| WiFi Access Point "P30OBD"
| + HTTP :80 (LittleFS PWA)
| + WebSocket :81 (~4 Hz JSON)
v
phone / tablet / laptop
http://192.168.4.1
- K-line reader: FreeRTOS task on core 1, ~250 ms poll of ECU memory rows
- Dashboard: plain HTML/CSS/JS PWA (installable “Add to Home Screen”)
- Stream is read-only (inbound WebSocket messages are ignored)
| Path | Role |
|---|---|
firmware/ |
Arduino sketch: K-line + WiFi AP + HTTP + WebSocket |
dashboard/ |
PWA UI + mock WebSocket server for bench dev |
tools/deploy.sh |
Compile, flash firmware, flash LittleFS dashboard |
Do not connect the Honda DLC K-line or raw +12V to the ESP32. GPIO is 3.3 V and not 5 V-tolerant. Route K-line through an ST L9637D with logic VCC = 3.3 V. Power the ESP32 from a 12 V → 5 V buck with reverse-polarity and load-dump protection.
flowchart TB
V12["DLC +12V"]:::pwr
DI["SS54 diode<br/>(reverse-polarity)"]:::prot
TV["SMBJ24A TVS<br/>+ 100µF + 100nF"]:::prot
BK["LM2596 buck<br/>12V → 5V"]:::prot
VIN["ESP32 5V/VIN"]:::mcu
KL["DLC K-line ~12V"]:::sig
LX["L9637D<br/>K-line transceiver<br/>VCC=3V3"]:::prot
RX["ESP32 GPIO16 (RX2)"]:::mcu
TX["ESP32 GPIO17 (TX2)"]:::mcu
ESP["ESP32<br/>WiFi AP + WebSocket :81"]:::mcu
PH["Phone / PWA"]:::ext
V12 -->|"fuse 2A"| DI
DI --> TV
TV --> BK
BK -->|"+5V"| VIN
VIN --> ESP
TV -->|"+12V protected"| LX
KL -->|"510Ω"| LX
LX -->|"RX(8)"| RX
TX -->|"TX(1)"| LX
RX --> ESP
ESP -.->|"ws://192.168.4.1:81"| PH
classDef pwr fill:#3a1010,stroke:#ff5555,color:#fff;
classDef sig fill:#10243a,stroke:#55aaff,color:#fff;
classDef prot fill:#3a2a10,stroke:#ffaa33,color:#fff;
classDef mcu fill:#14241a,stroke:#55cc88,color:#fff;
classDef ext fill:#241024,stroke:#cc66cc,color:#fff;
HONDA 3-PIN DLC PROTECTION / L9637D ESP32-WROOM
--------------- ------------------ -----------
+12V o--[FUSE 2A]--+--|>|--+-----------+-----------+--> LM2596 IN
| SS54 | | | LM2596 OUT = 5.0V --> 5V/VIN
|(revpol)| 100uF/50V _|_
| | + 100nF /_\ SMBJ24A TVS (to GND)
| +--> +12V_prot --------+--> L9637D VS(6)
GND o-------------+------------------ common GND --+--> LM2596 GND, ESP32 GND,
L9637D GND(4), LI(5)
K-line o--[510R]--> L9637D K(2) [12V bus, single-wire half-duplex]
L9637D VCC(7) <---------------------------- ESP32 3V3 (+100nF to GND)
L9637D TX(1) <---------------------------- ESP32 GPIO17 (UART2 TX)
L9637D RX(8) ----------------------------> ESP32 GPIO16 (UART2 RX)
L9637D LO(3) = open · LI(5) = GND
| Part | Value / spec | Role |
|---|---|---|
| ST L9637D (SO-8) | VCC tied to 3V3 | K-line transceiver, 12V ↔ logic |
| Resistor | 510 Ω 1/4 W | K-line series (K pin ↔ DLC) |
| Schottky SS54 | 40 V / 5 A | reverse-polarity |
| TVS SMBJ24A | 24 V standoff, 600 W | load-dump / transient clamp |
| Cap | 100 µF / 50 V | bulk input |
| Cap ×2 | 100 nF ceramic | input + VCC decoupling |
| Buck LM2596 module | set 5.0 V, 40 V max in | 12 V → 5 V for the ESP32 |
| Fuse | 2 A | DLC +12V feed |
| ESP32-WROOM dev | — | WiFi AP + WebSocket |
Notes:
- Echo: through the transceiver the ESP32’s own 5 request bytes echo on RX;
dlcCommand()discards them (#define KLINE_ECHO 1). - obd_select is hardcoded to
1(OBD1 / B16/P30). Change theconstand reflash for OBD2 — the RPM formula is the only difference. - Pins: UART2 on GPIO16/17. Avoid strapping pins GPIO0/2/5/12/15 and flash pins GPIO6–11.
- WebSockets by Markus Sattler
- ESP Async WebServer by ESP32Async
- Async TCP by ESP32Async
tools/deploy.sh [PORT]Compiles + uploads firmware and builds + flashes the dashboard to LittleFS. PORT is auto-detected if omitted.
Then join WiFi P30OBD (password honda1234 — change in firmware/firmware.ino)
and open http://192.168.4.1. Use “Add to Home Screen” for full-screen PWA.
Assumes default 4 MB partition scheme (LittleFS at 0x290000, size 0x160000).
Override with FS_OFFSET=… FS_SIZE=… tools/deploy.sh.
arduino-cli compile --fqbn esp32:esp32:esp32 firmwarecd dashboard
npm install
npm run mock # ws://localhost:81
# open index.html?ws=ws://localhost:81See dashboard/README.md for the JSON schema (integer fields; volt / ign are ×10).
Honda pre-2002 datalogger over K-line @ 9600 8N1:
- Wake / init sequence (
dlcInit) - Read-memory commands with Honda checksum:
0xFF - (sum - 1) - Live data as 16-byte rows at addresses
0x00,0x10,0x20,0x30 - DTCs at row
0x40→ Honda MIL numbers → P-codes indashboard/dtc-codes.js
The Honda K-line protocol core comes from
ArduinoHondaOBD by
Philip Bordado (kerpz), especially hobd_uni
(Arduino UNO: K-line datalogger, LCD, ELM327-over-Bluetooth for Torque).
That work reverse-engineered and documented the pre-2002 Honda DLC path used here: wake/init sequence, read-memory commands, checksum, ECU memory row layout, sensor scaling formulas, and DTC (MIL) decoding. p30obd stands on that core.
p30obd is a focused ESP32-only product for B16 / P30-class ECUs: firmware,
dashboard PWA, deploy script, and hardware docs. It does not replace
ArduinoHondaOBD; it continues the ESP path from the fork above on top of kerpz’s
hobd_uni protocol core.