Embedded systems · In progress
In progress
ThermalGuard
Fault-tolerant cooling-controller firmware for the Arduino Mega 2560, with verified control logic and hardware bring-up still ahead.
An in-progress embedded controller with dual temperature sensors, an asymmetric fault-handling state machine, and a line-based serial protocol. The firmware logic and host harness are verified in software; no physical hardware bring-up has happened yet.
- Role
- Interface contract, state-machine design, firmware, native test suite, and Rust host harness.
- Year
- 2026
- Status
- In progress
- Stack
- C++ · Arduino Mega 2560 · Rust · CMake · GitHub Actions
What is verified, and what is not.
ThermalGuard is in progress. Its control logic and host tooling are verified in software only; no physical hardware bring-up has taken place.
Verified
- Firmware state-machine logic compiled natively: 50/50 checks passing
- Rust host harness: 13/13 tests passing against a mock serial peer
Not yet verified
- Any behavior on a physical Arduino Mega 2560
- Real sensor readings, fan drive, and relay switching
- Watchdog reset behavior under a hung main loop
- Chosen over-temperature and hysteresis values
Overview
ThermalGuard is a cooling controller for an Arduino Mega 2560 that reads a DHT11 and a thermistor, drives a fan through an L293D, and reports state over USB serial. It is designed to degrade and fail safe when sensors disagree, drop out, or report over-temperature.
The project is in progress. Its interface contract is frozen, the control logic is implemented and verified natively, and the host harness is verified against a mock peer. Physical hardware bring-up has not started.
Problem
A cooling controller that trusts a single sensor can fail silently. Sensor dropouts, disagreement, and over-temperature each need a defined response, and those responses need to be testable before any hardware is wired.
Solution
ThermalGuard separates an Arduino-independent state-machine core from the sketch that talks to pins, so the fault policy can be compiled and tested natively with deterministic input sequences. A Rust harness speaks the same serial grammar against a mock peer today and is structured to target a real serial port later.
Feature evidence
Asymmetric fault FSM
NORMAL, DEGRADED, FAULT, and SAFE states with fast escalation and slow, persistence-gated recovery.
Conservative temperature
Control and over-temperature checks use the hotter valid reading, or the surviving sensor when one is invalid.
Line-based serial protocol
Sequenced EVENT and STATUS lines, PING/PONG liveness, and NACKs for malformed input instead of silent drops.
Separated evidence tiers
Native firmware-logic tests, mock-peer harness tests, and real-hardware runs are tracked as distinct kinds of evidence.
System layers
The sketch handles pins, sensor reads, the serial grammar, and the watchdog. All state and fan decisions come from fw_logic, a plain C++ core with no Arduino headers that builds both inside the sketch and natively for tests.
- 01
DHT11 + thermistor
Two independent temperature sources.
- 02
Firmware sketch
Pins, sensor reads, serial protocol, and watchdog.
- 03
fw_logic core
Arduino-independent state machine and fan hysteresis policy.
- 04
Rust host harness
Protocol parser, timeouts, and scenarios against a mock peer.
Where the engineering concentrates.
Recovery without flapping
Escalation is fast, but every de-escalation path requires five consecutive healthy samples so the controller does not oscillate between states.
Keeping evidence honest
Software tests prove transition and protocol logic only. Physical relay fault injection and watchdog behavior are reserved for real-hardware runs that have not happened yet.
Choices and tradeoffs.
Arduino-independent logic core
The state machine has no Arduino or AVR dependencies, so it compiles and runs in native CI.
Tradeoff: Adds a boundary between sketch and logic, but makes the fault policy testable without a board.
Frozen interface contract
Pin map, transitions, timing, and serial grammar were written down before implementation.
Bench-tunable constants
Over-temperature threshold and hysteresis band are named, labeled defaults pending bench measurement, not final values.
Fail-safe bias
SAFE forces the fan on and raises the alarm, and the fan enable line is pulled up so it defaults on before firmware initializes.
Security, accessibility, and testing.
Security
- Malformed serial input returns NACK rather than being dropped
- Fault injection honored only in an explicit test mode, with a firmware-enforced time cap
Accessibility
- Plain-text serial protocol readable in any terminal
- Documented pin map and interface contract
Testing
- Firmware logic: 50/50 native checks passing (FW-LOGIC tier)
- Rust host harness: 13/13 tests passing against a mock peer (HOST-MOCK tier)
- Real-hardware tier: not started
Current boundaries
The current product has a deliberate scope. These boundaries define what it does not claim.
- No physical hardware bring-up yet
- Over-temperature threshold and hysteresis band not yet chosen
- Relay drive, LCD wiring, and fan supply still to be decided at the bench
- Not a certified safety system
- No claim of operation through power, motor-supply, driver, or wiring failure
The next credible steps.
- 01Assemble the board and bring up sensors, fan, relay, and serial link
- 02Run the same harness scenarios against the real serial port
- 03Measure and set the over-temperature and hysteresis values
What the implementation clarified.
- 01
Pulling decision logic out of the sketch makes an embedded fault policy testable long before hardware is on the bench.
- 02
Asymmetric thresholds—quick to escalate, slow to recover—keep a safety controller conservative without letting it oscillate.
- 03
Naming evidence tiers explicitly keeps software-only verification from being mistaken for hardware validation.