Case study08of 08

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
ThermalGuard design diagram showing sensors feeding firmware glue and an fw_logic state machine that drives a fan and alarm, a Rust harness on USB serial, and evidence tiers with firmware logic and host mock passing and real hardware not started.
System diagramDesign diagram and evidence tiers

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.

  1. 01

    DHT11 + thermistor

    Two independent temperature sources.

  2. 02

    Firmware sketch

    Pins, sensor reads, serial protocol, and watchdog.

  3. 03

    fw_logic core

    Arduino-independent state machine and fan hysteresis policy.

  4. 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.

01

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.

02

Frozen interface contract

Pin map, transitions, timing, and serial grammar were written down before implementation.

03

Bench-tunable constants

Over-temperature threshold and hysteresis band are named, labeled defaults pending bench measurement, not final values.

04

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.

  1. 01Assemble the board and bring up sensors, fan, relay, and serial link
  2. 02Run the same harness scenarios against the real serial port
  3. 03Measure and set the over-temperature and hysteresis values

What the implementation clarified.

  1. 01

    Pulling decision logic out of the sketch makes an embedded fault policy testable long before hardware is on the bench.

  2. 02

    Asymmetric thresholds—quick to escalate, slow to recover—keep a safety controller conservative without letting it oscillate.

  3. 03

    Naming evidence tiers explicitly keeps software-only verification from being mistaken for hardware validation.