

Esp32board
N2K Engine Interface with BLE built around an ESP32 and ADS1115 ADCs
- Size
- 108 × 47 mm
- Copper layers
- 2
- Thickness
- 1.6 mm
- Parts
- 88
- Nets
- 64
- Pads
- 236
- Tracks, vias
- 668, 39
- Pours
- 3
- Routed
- Yes
- KiCad
- KiCad 9.0 (file 20241229)
- Created
- 10 Oct 2026
- Updated
- 12 Oct 2026
Overview
Esp32board is an open-source printed circuit board by ieb, from the ieb/N2KEngineEsp32 repository on GitHub. It is a 2-layer board of 108 × 47 mm with 88 parts on 64 nets, routed with 668 tracks and 39 vias.
It is built around the ADS1115IDGS, AMS1117-5.0 and LM393, with the TJA1050, BAT46 and S1J among its other parts. Its parts include 46 resistors, 14 connectors, 10 diodes, 8 capacitors and 7 ICs. It belongs with the interfaces and adapters boards and the ESP32 and RISC-V boards of this library.
Main components
8ADS1115IDGS
MSOP10Ultra-Small, Low-Power, 4 Channels 16-Bit Analog-to-Digital Converter with Internal ReferenceTexas InstrumentsUncategorisedAMS1117-5.0
SOT-223-40℃~+125℃ 1 1.3V 15V 1A 5V 60dB Fixed Positive Short Circuit Protection、Thermal shutdown SOT-223 Voltage Regulators - Linear, Low Drop Out (LDO) Regulators ROHSAdvanced Monolithic SystemsVoltage Regulators - Linear, Low Drop Out (LDO) RegulatorsLM393
SOP-8-16V~16V 0℃~+70℃ 2 2.5mA 250nA 2V~36V 36V 5mV 5nA Fail-safe function Open-drain SOP-8 Comparators ROHSMSKSEMIComparatorsTJA1050
SOIC-8SOIC-8 New Arrivals ROHSPhilips SemiconsUncategorisedBAT46
DO-35Schottky DiodesSTMicroelectronicsS1J
SMA(DO-214AC)-65℃~+150℃ 1 Independent 1.1V@1A 1A 5uA@600V 600V SMA(DO-214AC) Diodes - General Purpose ROHSDiodes IncorporatedDiodes - General PurposeBSS138
SOT-23-55℃~+150℃ 1 N-channel 1.1Ω@10V、1.2Ω@4.5V 1.2V 1.7nC@10V 17.5pF 340mA 350mW 50V 6.5pF N-Channel SOT-23 MOSFETs ROHShongjiachengMOSFETsSMAJ16CA
SMA-55℃~+150℃ 1 15.3A 16V 19.7V 26V 400W 5uA Bidirectional TVS SMA ESD and Surge Protection (TVS/ESD) ROHSDiodes IncorporatedESD And Surge Protection (TVS/ESD)
README
README.mdNMEA 2000 Marine Diesel Engine Interface (ESP32-C3)
This project provides an open, high-reliability NMEA 2000 marine engine interface for diesel propulsion engines. Built on the ESP32-C3 microcontroller and ADS1115 16-bit ADCs, it monitors engine speed, operating pressures, temperatures, electrical systems, and alarm conditions, broadcasting them across the vessel's NMEA 2000 CAN network.
High-Level Architecture
+------------------------------------+
| ESP32-C3 |
| |
Flywheel Sensor --->| GPIO4 (Pulse Interrupt) |
Stop Relay --->| GPIO5 (Coil Sense) |
Glow Relay --->| GPIO6 (Coil Sense) |
Start Relay --->| GPIO7 (Coil Sense) |
1-Wire DS18B20 --->| GPIO0 (Dallas Temp Bus) |
| |
I2C Bus (SDA/SCL) ->| GPIO8 / GPIO9 |
+-----+------------------------+-----+
| |
v v
+-------------------------+ +------------+
| 3x ADS1115 16-bit ADCs | | CAN / TWAI | (GPIO3 TX, GPIO1 RX)
| (Running at 5V via LS) | +-----+------+
+------------+------------+ |
| v
| +--------------+
NTC1: Exhaust Water Trap| | NMEA 2000 |
NTC2: Alternator Temp | | Bus |
NTC3: Engine Room Temp | +--------------+
NTC4: Gearbox Temp |
NTC5: Exhaust Elbow Temp|Key Hardware Peripherals & Pinout
| Pin | Peripheral | Purpose |
|---|---|---|
| GPIO0 | 1-Wire | Dallas DS18B20 digital temperature bus (4K7 pull-up to 3V3) |
| GPIO1 | CAN-RX | ESP32 TWAI CAN bus receive |
| GPIO3 | CAN-TX | ESP32 TWAI CAN bus transmit |
| GPIO2 | Bench Output | Optional LEDC test signal for RPM bench testing (CLI T) |
| GPIO4 | Pulse Input | Flywheel reactive pickup via LM393 comparator (30 teeth per revolution) |
| GPIO5 | Digital Input | Stop Relay Coil (10k / 4.7k divider from 12V, BAT46 clamp to 3V3) |
| GPIO6 | Digital Input | Glow Plug Relay Coil (10k / 4.7k divider from 12V, BAT46 clamp to 3V3) |
| GPIO7 | Digital Input | Start Relay Coil (10k / 4.7k divider from 12V, BAT46 clamp to 3V3) |
| GPIO8 | I2C SDA | 400 kHz I2C data to 3x ADS1115 ADCs |
| GPIO9 | I2C SCL | 400 kHz I2C clock to 3x ADS1115 ADCs |
ADC Mapping (3x ADS1115 @ 5V, 64 SPS)
- ADC1 (
0x48, Addr $\to$ GND):AIN0: NTC1 (10K NTC, 5V 4k7 pullup) — Exhaust Water TrapAIN1: NTC2 (10K NTC, 5V 4k7 pullup) — Alternator TemperatureAIN2: NTC3 (10K NTC, 5V 4k7 pullup) — Engine Room Air TemperatureAIN3: Alternator Voltage Divider (10k / 4.7k)
- ADC2 (
0x49, Addr $\to$ VDD):AIN0: Oil Pressure Sender (0–5V sensor)AIN1: Engine Coolant Sensor (12V 1k pullup)AIN2: Engine Block Negative Offset Divider (5V — 10k — ADC — 10k — Engine Block -)AIN3: Engine Starting Battery Voltage Divider (10k / 4.7k)
- ADC3 (
0x4B, Addr $\to$ SCL):AIN0: NTC4 (10K NTC, 5V 4k7 pullup) — Gearbox TemperatureAIN1: NTC5 (10K NTC, 5V 4k7 pullup) — Exhaust Elbow TemperatureAIN2: Fuel Tank Level Sender (European 0–190 $\Omega$, 5V 1k pullup)AIN3: Spare Voltage Divider (10k / 4.7k)
Signal Processing & Calibrations
- Engine Speed (RPM):
- Computed from flywheel pulses: $\text{RPM} = \text{Hz} \times 2.0$.
- Two implementations, selected with
RPM_SENSOR_EDGE_TIMINGinsrc/config.h:- Edge timing (
EdgeRpmSensor, default): the ISR timestamps edges (1 µs) and RPM is computed over whole revolutions, giving a new value every revolution with accuracy limited only by interrupt latency jitter (~0.01–0.04%). Registered as an IRAM interrupt so pulses are not lost during flash writes; edges closer than 150 µs are rejected as glitches. - Window counting (
RpmSensor): counts pulses over a ~100 ms window; ±1 pulse (±20 RPM) quantisation plusmillis()jitter.
- Edge timing (
- The ESP32-C3 has no PCNT (pulse counter) peripheral, so hardware counting is not available on this board.
- The native tests print a side-by-side comparison of both implementations; on the board use the
Tbench signal. - Details, measurements and caveats: docs/rpm_measurement.md.
- Engine is considered Running when $\text{RPM} \ge 800$ and Stopping when $\text{RPM} < 500$.
- 10K NTC Thermistors (NTC1–NTC5):
- Converted analytically using the exact Beta parameter model ($\frac{1}{T} = \frac{1}{T_0} + \frac{1}{\beta} \ln\left(\frac{R}{R_0}\right)$ with $R_0 = 10000,\Omega$, $T_0 = 298.15\text{ K}$, $\beta = 3950\text{ K}$, $R_{\text{top}} = 4700,\Omega$).
- Provides smooth, continuous sub-0.01°C resolution matching the 16-bit ADS1115 without piecewise discretization or boundary kinks.
- Engine Block Negative Offset Compensation:
- Measures voltage drop between boat DC ground and engine block negative caused by heavy alternator charging current: $$V_{block} = 2.0 \cdot V_{adc} - 5.0\text{ V}$$
- The Volvo Penta coolant sensor is connected to the engine block; its voltage reading and supply rail are automatically adjusted relative to $V_{block}$ to prevent false temperature spikes during high charging.
- Volvo Penta Coolant Temperature Sender:
- Evaluated through a dedicated lookup table (
coolantTable, 10°C to 120°C) with ratiometric battery supply voltage compensation.
- Evaluated through a dedicated lookup table (
- Oil Pressure Sensor:
- Linear 0.5V (0 psi) to 4.5V (100 psi) transfer function with disconnection detection.
- Fuel Tank Level:
- Supports European 0–190 $\Omega$ resistive senders (0 $\Omega$ = Empty, 190 $\Omega$ = Full), scaled to 0.0%–100.0%.
Alarms & Raw Water Flow Collapse Protection
- 15-Second Startup Grace Period: Prevents spurious alarms while the engine spins up to idle.
- Raw Water Flow Collapse Protection (Exhaust Elbow NTC5):
- Evaluates rate-of-rise over a 30-second sliding anchor window. If exhaust elbow temperature climbs $\ge +8.0\text{°C}$ inside 30 seconds once above 35°C baseline, a raw water flow failure alarm is tripped immediately.
- Absolute over-temperature alarm at $> 45.0\text{°C}$. If sustained for $> 5$ seconds, triggers an Emergency Stop discrete alarm.
- Engine Protection Alarms:
- Coolant Over-Temperature: $> 97.0\text{°C}$ sustained $> 15$ seconds.
- Low Oil Pressure: $< 10.0\text{ PSI}$ (68.9 kPa) sustained $> 5$ seconds while running.
- Low System Voltage: Engine battery $< 11.8\text{ V}$ sustained $> 5$ seconds.
- Alternator Charge Indicator: Alternator voltage $< 12.2\text{ V}$ sustained $> 5$ seconds.
- High Alternator Temperature: Warning Level 1 triggered at $> 110.0\text{°C}$.
- High Engine Room Temperature: Warning Level 1 triggered at $> 70.0\text{°C}$.
Non-Volatile Storage & Event Logging
The flash memory uses a 2MB Application / 2MB SPIFFS partition layout (src/no_ota.csv):
- Engine Hours Accumulator: Accumulated per second while $\text{RPM} \ge 800$, committed to wear-leveled NVS Preferences.
- Persistent Event History: Historical alarms are appended to
/events.csvon the SPIFFS filesystem. - No flash writes while the engine runs: flash writes stall non-IRAM interrupts (CAN today, BLE later) for up to tens of ms during a sector erase. While running, engine hours and alarm events are held in RTC no-init memory (survives crashes, watchdog resets and restarts) and written to flash when the stop relay is energised, when the engine stops and before a CLI restart. A valid RTC copy that is ahead of flash is recovered at boot. A backstop save of engine hours every
ENGINE_HOURS_BACKSTOP_SAVE_S(default 3600 s, 0 disables) protects against an abnormal power cut; board power normally stays on 30–60 s after shutdown. Alarm flags are still sent immediately in PGN 127489. Setting hours (E) and clearing events (C/ N2K command) write immediately. - GPS UTC Synchronization: Automatically synchronizes timestamps when NMEA 2000 System Time (PGN 126992) is received from on-bus GPS receivers.
NMEA 2000 Messages & Display Remapping
To allow standard marine multifunction displays (MFDs) and dedicated instruments (such as Raymarine i70) to present all engine and electrical metrics without proprietary software:
| PGN | Name | Period | Special Mapping / Rationale |
|---|---|---|---|
| 127488 | Engine Parameters, Rapid Update | 500 ms | RPM broadcast when engine is running ($\text{RPM} \ge 800$). |
| 127489 | Engine Parameters, Dynamic | 1000 ms | Alternator Temp (NTC2) sent as Engine Oil Temperature so standard gauges display alternator thermal load. Also conveys coolant temp, alternator voltage, total engine hours, oil pressure, and discrete alarm bitfields. |
| 127493 | Transmission Parameters, Dynamic | 4.85 s | Exhaust Water Trap (NTC1) sent as Transmission Oil Temperature for displays lacking an exhaust gauge. |
| 127508 | Battery Status | 1.0 s | Broadcasts two instances: • Instance 0: Engine Starting Battery Voltage. • Instance 2: Alternator Output Voltage & Operating Temperature. |
| 127505 | Fluid Level | 2.5 s | Tank Instance 0, Fuel level % (60.0 L capacity default). |
| 130312 | Temperature (Legacy) | 4.85 s | Emits Exhaust Gas (Source 14), Engine Room (Source 3), Alternator (Source 30), and Dallas 1-Wire sensors (Source 31+i). |
| 130316 | Extended Temperature | 2.5 s | Emits high-resolution (0.001 K) temperatures. |
Interactive Serial Console
Connect to the USB Serial port at 115200 baud for real-time monitoring and commands:
h— Show command menus— Print complete formatted engine status dashboardF— Toggle Fake 1000 RPM mode for bench testingE— Set / calibrate accumulated engine hoursl— Dump SPIFFS alarm event logC— Clear SPIFFS event historyd— Toggle raw ADC voltage debug streamT— Cycle the RPM bench test signal on GPIO2 (off → 100 Hz → 400 Hz → 1500 Hz) and print min/mean/max/std-dev of the measured RPM every 2 s. Wire GPIO2 → 1K → GPIO4 and short the flywheel input (J15) so the LM393 output is released. Build once with eachRPM_SENSOR_EDGE_TIMINGsetting to compare.R— Software restart of the ESP32-C3
Building & Flashing
This project uses PlatformIO:
# Build firmware
pio run
# Flash to ESP32-C3
pio run -t upload
# Open Serial Monitor
pio device monitorParts
88| Qty | Value | Footprint | References |
|---|---|---|---|
| 13 | 2.2K | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R4, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31 |
| 11 | 4K7 | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R1, R2, R6, R7, R8, R10, R12, R13, R14, R40, R46 |
| 9 | 10K | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R5, R9, R11, R33, R34, R37, R39, R41, R45 |
| 5 | 100nF | Capacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolder | C1, C4, C5, C6, C9 |
| 5 | 4.7K | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R15, R16, R17, R18, R19 |
| 4 | BAT46 | Diode_SMD:D_SOD-123 | D5, D6, D10, D11 |
| 4 | S1J | Diode_SMD:D_SMA | D2, D3, D7, D8 |
| 3 | 22K | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R36, R43, R44 |
| 3 | ADS1115IDGS | Package_SO:TSSOP-10_3x3mm_P0.5mm | U4, U5, U6 |
| 2 | 10uF | Capacitor_SMD:C_1206_3216Metric_Pad1.33x1.80mm_HandSolder | C2, C3 |
| 2 | BSS138 | Package_TO_SOT_SMD:SOT-23 | Q1, Q2 |
| 1 | 12V In | Connector_JST:JST_XH_B2B-XH-A_1x02_P2.50mm_Vertical | J12 |
| 1 | 1K | Resistor_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P5.08mm_Horizontal | R35 |
| 1 | 1K | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R32 |
| 1 | 1Wire | Connector_JST:JST_XH_B3B-XH-A_1x03_P2.50mm_Vertical | J1 |
| 1 | 1nF | Capacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolder | C8 |
| 1 | 3.3K | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R3 |
| 1 | 3K3 | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R42 |
| 1 | 470K | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R38 |
| 1 | AMS1117-5.0 | Package_TO_SOT_SMD:SOT-223-3_TabPin2 | U2 |
| 1 | CAN | TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2-5.08_1x02_P5.08mm_Horizontal | J5 |
| 1 | ESP32-C3-Waveshare | iebSpecials:ESP-C3-Zero-Waveshare | U1 |
| 1 | Engine | Connector_JST:JST_XH_B4B-XH-A_1x04_P2.50mm_Vertical | J14 |
| 1 | Flywheel | Connector_JST:JST_XH_B2B-XH-A_1x02_P2.50mm_Vertical | J15 |
| 1 | FuelLevel | Connector_JST:JST_XH_B2B-XH-A_1x02_P2.50mm_Vertical | J11 |
| 1 | LED | LED_SMD:LED_0805_2012Metric_Pad1.15x1.40mm_HandSolder | D9 |
| 1 | LM393 | Package_SO:SOIC-8_3.9x4.9mm_P1.27mm | U7 |
| 1 | NTC1 | Connector_JST:JST_XH_B2B-XH-A_1x02_P2.50mm_Vertical | J6 |
| 1 | NTC2 | Connector_JST:JST_XH_B2B-XH-A_1x02_P2.50mm_Vertical | J7 |
| 1 | NTC3 | Connector_JST:JST_XH_B2B-XH-A_1x02_P2.50mm_Vertical | J8 |
| 1 | NTC4 | Connector_JST:JST_XH_B2B-XH-A_1x02_P2.50mm_Vertical | J9 |
| 1 | NTC5 | Connector_JST:JST_XH_B2B-XH-A_1x02_P2.50mm_Vertical | J10 |
| 1 | Oil Pressure | Connector_JST:JST_XH_B3B-XH-A_1x03_P2.50mm_Vertical | J13 |
| 1 | Polyfuse | Fuse:Fuse_1812_4532Metric_Pad1.30x3.40mm_HandSolder | F1 |
| 1 | Relays | Connector_JST:JST_XH_B3B-XH-A_1x03_P2.50mm_Vertical | J16 |
| 1 | SMAJ16CA | Diode_SMD:D_SMA-SMB_Universal_Handsoldering | D1 |
| 1 | TJA1050 | Package_SO:SOIC-8_3.9x4.9mm_P1.27mm | U3 |
| 1 | V2_spare | Connector_PinHeader_2.54mm:PinHeader_1x01_P2.54mm_Vertical | J2 |
Questions
How big is the Esp32board PCB?
It measures 108 × 47 mm and has 2 copper layers, 1.6 mm thick.
What parts does the Esp32board use?
88 parts, built around the ADS1115IDGS, AMS1117-5.0, LM393 and TJA1050. 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 Esp32board KiCad files?
From the ieb/N2KEngineEsp32 repository on GitHub, at the commit this page was made from: the board is pcb/esp32board/esp32board.kicad_pcb and its schematic pcb/esp32board/esp32board.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Can I use the Esp32board design in my own project?
Its repository states no licence, so its author keeps all rights: ask ieb before reusing the design.
Similar boards
- 2 layers97 × 54.3 mm

- 2 layers100 × 100 mm

- 2 layers100 × 56 mm

- 4 layers49.2 × 38.7 mm

- 4 layers90.8 × 58.8 mm

HALSER
hatlabs/HALSER-hardware
Hat Labs Serial Interface Device hardware design files
199 partsCC-BY-4.0 - 4 layers21 × 67.7 mm

Fan controller txu0204-pico
Lannakin/fan-controller-pico
(note: hobbiest) expansion board for controlling 4 4-pin 12v fans for the raspberry pi pico series using pwm output with tachometer feedback designed by a cat
61 parts - 4 layers203.5 × 90 mm

BDCMotorController
nunosousa/TelescopeMirrorTester
This is an application intended to provide useful tools to perform Foucault or Wire testing on reflective telescope mirrors
323 partsMIT - 2 layers82.5 × 127 mm

Power supply
nunosousa/SCART-switcher
An old school SCART switcher. Its main purpose will be to automaticaly detect and switch the video output to the active input video source.
59 parts