Skip to the content
PCBKitNew board
2 layers130 × 115 mmObd2-simulator, the printed circuit board in 3D

Open-source OBD-II simulator board: emulates a vehicle ECU per SAE J1979 and ISO 15031-5 over CAN. ESP32-S3 + MCP2515, 21 simulated parameters, DTC bank with MIL.

Size
130 × 115 mm
Copper layers
2
Thickness
1.6 mm
Parts
107
Nets
64
Pads
411
Tracks, vias
892, 73
Pours
2
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
30 Aug 2026
Updated
31 Aug 2026

Overview

Obd2-simulator is an open-source printed circuit board by FilipRaic, from the FilipRaic/obd2-simulator repository on GitHub, published under the MIT licence. It is a 2-layer board of 130 × 115 mm with 107 parts on 64 nets, routed with 892 tracks and 73 vias.

It is built around the ESP32-S3-WROOM-1-N8, SN65HVD230DR and CH224K, with the S25FL128LAGMFM010, MCP2515-I/SO and SY6280AAC among its other parts. Its parts include 33 resistors, 32 capacitors, 9 ICs, 6 switches and 5 diodes. It belongs with the interfaces and adapters boards and the ESP32 boards of this library.

Main components

12

README

README.md

OBD-II Simulator

Open-source OBD-II simulator board that answers a diagnostic tool over CAN exactly as a vehicle ECU does. The repository has three parts:

  • the protocol core (include/, src/, tests/) - portable, host-testable protocol and simulation layers with no external dependencies, described below,
  • the firmware (firmware/) - PlatformIO project for the device itself (FreeRTOS tasks, MCP2515 SPI driver, TFT_eSPI user interface, 16 MB SPI NOR flash storage with USB-C MSC / USB-A stick transfer), which compiles the core unchanged and plugs into it through the small set of extern platform hooks listed below. See firmware/README.md,
  • the board (hardware/) - the KiCad project, gerbers, bill of materials and the scripts that generate the board, at revision v0.7 (130 x 115 mm, two-layer FR4, ESP32-S3-WROOM-1). See hardware/README.md.

Block diagram of the OBD-II simulator, five functional blocks

The simulator answers a diagnostic tool over CAN and, like a real vehicle, powers it from pin 16 of the J1962 connector. The protocol core described below is what runs inside the "Microcontroller" block, and everything around it is documented in hardware/README.md, which walks through the same schematics one design decision at a time.

Everything in the repository is in English. The project also keeps a set of Croatian working documents, which live outside it.

The v0.7 board has been fabricated and assembled in one unit. A commercial ELM327 adapter connects to it, reads all 21 parameters and the fault codes, and draws its own 12 V from pin 16 while doing so.

The website

The project has a landing page at https://filipraic.github.io/obd2-simulator/, which is the short version of everything below: what the device does, what it is built from and where to get the files. Two things on it are worth opening even if the page itself is skipped, because neither can be shown in a README:

PageWhat it is
The user interface demothe screens firmware/src/ui/screens/ draws on the display, redrawn in a browser and walked with the same encoder and joystick controls the device has, so the interface can be tried before anything is built
The interactive board viewthe v0.7 board drawn in the browser, with the tracks, the ground pour, the vias, the pads and the components as five layers that switch on and off, and a tooltip on every part. Generated from obd2-simulator.kicad_pcb by hardware/kicad/scripts/generate_pcb_html.py

Where to read what

The wiki is written for someone using or rebuilding the device. The files in this repository are the record of how it was built and why. The wiki is in English, which is the language of the project. A Croatian translation of the same pages exists but is not published yet, and if it goes up it will take an -HR suffix, leaving the page names below unchanged.

QuestionWiki pageIn this repository
What is this and what can it doHomethis file
How do I build oneBuilding the devicehardware/README.md, and hardware/gerber/README.md before ordering
How do I compile and flash itFirmwarefirmware/README.md, and firmware/tools/README.md when the ordinary upload path is unavailable
How do I drive itUsagescenarios/README.md for the JSON format
How do I contributeContributingthe conventions below
How is the board generated-hardware/kicad/scripts/README.md

Two internal documents govern changes to this project, and neither is published here: docs/MAPA-POVEZANIH-DATOTEKA.md is an "if you change X, check Y" table, because the same fact is written down in up to six places, and docs/combined/DNEVNIK-IZMJENA.md is the chronological record of every decision. Both are in Croatian and are working notes rather than product documentation, so docs/ is deliberately left out of the repository.

Modules

FilePurpose
include/obd2_pids.hMode/PID constants per SAE J1979 / ISO 15031-5
include/sensor_table.h21 simulated parameters with ranges and noise
src/pid_encoder.cppValue → raw bytes codec + supported-PID bitmasks
include/dtc_bank.hDTC bank (pending/confirmed, MIL, freeze frame)
src/iso_tp.cppISO 15765-2 transmit path (SF, FF/FC/CF)
src/can_handler.cppRequest dispatcher, modes 0x01-0x09
src/simulator_core.cppSimulation profiles (Manual / Idle / Drive)
tests/test_simulator.cppHost-side unit tests

Implemented services: 0x01 (current data, 21 PIDs), 0x02 (freeze frame), 0x03/0x07 (stored/pending DTCs), 0x04 (clear DTCs), 0x09 (VIN). Unsupported services receive the negative response 7F <mode> 11. Requests are accepted on 0x7DF (functional) and 0x7E0 (physical), while responses are sent on 0x7E8. Frames are padded to 8 bytes with 0x55 per ISO 15765-4.

Platform hooks (implement on target, stubbed in tests)

cpp
uint32_t millis();                                // ms since boot
void     can_send_frame(const CanFrame& frame);   // MCP2515 transmit
bool     iso_tp_wait_flow_control(FlowControl&);  // wait for FC frame
void     iso_tp_delay_us(uint32_t us);            // STmin pacing

Building and running the tests

sh
cmake -B build
cmake --build build
ctest --test-dir build --output-on-failure

The same tests also run through PlatformIO (pio test -e native inside firmware/). Firmware build: pio run -e custom-board (the dedicated ESP32-S3 board, also used on the breadboard adapter during development).

Regenerating the board

The board is generated rather than drawn: there is no .kicad_sch, and the .kicad_pcb is an output. Two entry points, and picking the wrong one costs work:

powershell
# a part, a net or the placement changed - rebuilds and re-routes from nothing
powershell -ExecutionPolicy Bypass -File hardware\kicad\scripts\route_board.ps1

# the board file is already right, only the derived files are stale
powershell -ExecutionPolicy Bypass -File hardware\kicad\scripts\regen_outputs.ps1

route_board.ps1 ends by recomputing all 103 reference designator positions and so discards the hand-tuned silkscreen. If no copper moved, run only regen_outputs.ps1. Every step of the chain, what it writes and where, is in hardware/kicad/scripts/README.md.

Parts

107
QtyValueFootprintReferences
1610kR_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR9, R10, R11, R12, R13, R14, R15, R22, R28, R29, R32, R33, R34, R35, R36, R37
12100nFC_Disc_D5.0mm_W2.5mm_P5.00mmC10, C11, C12, C13, C14, C15, C16, C20, C21, C23, C24, C29
510uFCP_Radial_D5.0mm_P2.00mmC5, C18, C19, C25, C37
422uF LowESRCP_Radial_D6.3mm_P2.50mmC3, C4, C27, C28
4M3MountingHole_3.2mm_M3H1, H2, H3, H4
3100RR_Axial_DIN0207_L6.3mm_D2.5mm_P5.08mm_VerticalR38, R39, R40
31nFC_Disc_D4.3mm_W1.9mm_P5.00mmC34, C35, C36
333RR_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR8, R30, R31
347nFC_Disc_D5.0mm_W2.5mm_P5.00mmC31, C32, C33
36k8R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR19, R26, R27
21uFC_Disc_D6.0mm_W2.5mm_P5.00mmC22, C26
222pFC_Disc_D4.3mm_W1.9mm_P5.00mmC6, C7
24u7HL_Radial_D8.7mm_P5.00mm_Fastron_07HCPL2, L3
251kR_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR16, R24
2SMAJ16AD_SMAD2, D3
2TPS562201DDCRSOT-23-6U2, U11
2USBLC6-2SC6SOT-23-6D4, D5
1100uF/25VCP_Radial_D6.3mm_P2.50mmC1
1120RR_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR7
115kR_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR17A
11kR_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR21
124kR_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR23
13V3TestPoint_THTPad_2.0x2.0mm_Drill1.0mmTP1
1470RR_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR17B
18MHzCrystal_HC49-U_VerticalY1
19k31R_Axial_DIN0207_L6.3mm_D2.5mm_P10.16mm_HorizontalR25
1BOOTSW_PUSH_6mmSW4
1CANHTestPoint_THTPad_2.0x2.0mm_Drill1.0mmTP3
1CANLTestPoint_THTPad_2.0x2.0mm_Drill1.0mmTP4
1CH224KCH224K_ESSOP-10-1EP_3.9x5.0mm_P1mm_EP2.3x3.2mmU1
1CLEARSW_PUSH_6mmSW2
1CONFIRMSW_PUSH_6mmSW1
1EN11-HSB1AQ20RotaryEncoder_Alps_EC11E-Switch_Vertical_H20mmENC1
1ESP32-S3-WROOM-1ESP32-S3-WROOM-1U6
1GNDTestPoint_THTPad_2.0x2.0mm_Drill1.0mmTP2
1J1962F OBD-IISEP-A-OBD-D2J2
1LCD 18366PinHeader_1x08_P2.54mm_VerticalJ5
1MCP2515-I/SOSOIC-18W_7.5x11.6mm_P1.27mmU4
1MISOTestPoint_THTPad_2.0x2.0mm_Drill1.0mmTP6
1MOSITestPoint_THTPad_2.0x2.0mm_Drill1.0mmTP5
1PESD1CANSOT-23D1
1PTC 500mAFuse_1206_3216MetricF1
1RESETSW_PUSH_6mmSW5
1RETURNSW_PUSH_6mmSW3
1S25FL128LAGMFM010SOIC-8_5.3x5.3mm_P1.27mmU7
1SCKTestPoint_THTPad_2.0x2.0mm_Drill1.0mmTP7
1SKRHABE010SKRHABE010SW6
1SN65HVD230DRSOIC-8_3.9x4.9mm_P1.27mmU5
1SY6280AACSOT-23-5U10
1TS3USB221Texas_DRC0010JU9
1UARTPinHeader_1x03_P2.54mm_VerticalJ6
1USB-AUSB_A_Molex_67643_HorizontalJ4
1USB-CUSB_C_Receptacle_GCT_USB4085J1
1VBUSTestPoint_THTPad_2.0x2.0mm_Drill1.0mmTP8

Questions

How big is the Obd2-simulator PCB?

It measures 130 × 115 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Obd2-simulator use?

107 parts, built around the ESP32-S3-WROOM-1-N8, SN65HVD230DR, CH224K and S25FL128LAGMFM010. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Obd2-simulator KiCad files?

From the FilipRaic/obd2-simulator repository on GitHub, at the commit this page was made from: the board is hardware/kicad/obd2-simulator.kicad_pcb. PCBKit opens the board in the browser, with nothing to install.

Can I use the Obd2-simulator design in my own project?

Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).

Similar boards

  • 4 layers88 × 88 mmPump, the printed circuit board in 3D

    Pump

    EpicQuestBio/MR1

    MR1 specs

    28 parts1CC0-1.0
  • 2 layers64.2 × 35.6 mmCAN Board, the printed circuit board in 3D

    CAN Board

    WestianPKl/pcb-docs

    A collection of custom PCB designs created in KiCAD, centered around the Raspberry Pi Pico (RP2040) platform. Each board is a standalone module that connects to the Main Board and extends its functionality via I2C, SPI…

    30 parts
  • 4 layers236.1 × 156.9 mmImpeller18, the printed circuit board in 3D

    Impeller18

    buglalis/degree

    764 parts
  • 4 layers130 × 105 mmHomeDeck, the printed circuit board in 3D

    HomeDeck

    Kilan777/HomeDeck

    Jarvis HomeDeck: a Raspberry Pi CM4 carrier board and voice-assistant software for a 7-inch smart display (KiCad hardware, generated from Python, plus the Python/JS assistant)

    228 parts1
  • 4 layers149.6 × 98 mmMch2022, the printed circuit board in 3D

    Mch2022

    kitspace-test-repos/kicad6-file-collection

    235 partsMIT
  • 2 layers87.5 × 70 mm010 Implementation, the printed circuit board in 3D

    010 Implementation

    NewTec-GmbH/esp32-can-iot

    A ESP32 based interface between CAN-bus and IoT environments.

    70 parts51BSD-3-Clause
  • 2 layers60 × 48 mmHub, the printed circuit board in 3D

    Hub

    cUDGk/vrc-fbt-hardware

    VRChat向けフルボディトラッキング基板 — ハブ+デイジーチェーン端末・数と位置を自由に変更可能・KiCad/OpenSCAD一式

    57 parts