reid.wiki

Projects / Embedded & Control

Turbine Engine ECU

A from-scratch engine control unit for a miniature turbojet — custom STM32 PCB, safety-first bare-metal firmware, and a desktop bench app, all built after the factory ECU died.

Status
Active
Timeline
2026 — present
Last updated
June 2026
STM32G431C (bare-metal)KiCadPythonPySide6CMakeCOBS/CRC16

Why

I have an R.A. Microjets miniature turbojet with a dead factory ECU. Replacement controllers exist, but where’s the fun in that — an engine controller is a perfect excuse to build a complete embedded product: board, firmware, protocol, tooling, and the safety story that makes you willing to stand next to the thing.

The board

A 4-layer STM32G431 board designed entirely from Python scripts driving headless KiCad — netlist, placement, autorouting, and verification, with no hand-drawn schematic. Final board: 163×124 mm, 87 components, 55 nets, 0 DRC violations, 0 ERC errors, 0 schematic-parity issues. Fabricated at JLCPCB with a fully verified DigiKey BOM and a per-pin GPIO audit against the datasheet.

The analog side covers the whole engine interface: MAX31855 thermocouple input for exhaust gas temperature, an LM393 comparator front-end with hysteresis for RPM pickup, shunt-based current sensing on the actuators, a buck converter power stage, reverse-polarity ideal-diode protection, and USB-C with ESD protection.

The firmware

The core is portable, HAL-free C that compiles to the same object code on the STM32 and on the host — so the entire control system runs under CTest before it ever touches hardware. Five test suites, including a 20,000-iteration structural fuzz of the engine state machine and fault-injection coverage of every interlock.

The design rule that matters: the safety layer runs last on every 1 kHz tick and has final authority. It can only push outputs toward the safe state (fuel off, gas off). Hardware pull-downs keep actuators off through reset and brownout, and a ~250 ms watchdog backs it all up. Footprint: 24.2 KB flash, 8.4 KB RAM.

The wire protocol (COBS framing + CRC-16/CCITT) is generated from a single Python spec into C headers, a Python codec, protocol docs, and cross-language golden test vectors — firmware/host drift is structurally impossible.

The bench

A PySide6 desktop app (~1,900 lines) with live telemetry plots, a command console, parameter editor for the 22-entry tunable table, fault log, YAML-scripted test sequences that cannot bypass interlocks, and SQLite run logging with post-mortem analysis.

Before the hardware arrived, a software-in-the-loop simulator with a turbine plant model ran the full stack over TCP — including reproducing the original engine’s historical ignition-timeout failure mode, which is exactly the fault that killed the factory ECU’s usefulness in the first place.

Status

All six software phases are built and verified in simulation. The PCB is fabricated and in hand. Current work is hardware bring-up: flashing, USB-CDC wiring, sensor calibration, and metering real engine values before the first supervised start.