Metatransformer report
Programs as state-changing machines
Foundation · 50 minutes · Model firmware as explicit state transitions, then choose states that keep a desk robot responsive while it waits, moves, or reports a fault.
Text report: images and diagrams are omitted, and links to project files are inactive. Keep the exported project alongside this PDF for wiring diagrams, models, and linked files.
Learning outcomes
- Trace state variables through a timed input sequence and design a non-blocking finite-state machine with an explicit safe state.
Prerequisites
- engineering-workflow
Concepts
A program inside a product is less like a written recipe and more like a board-game position. At any instant, variables remember the position: whether a button was previously down, when a motor started, or which screen page is visible. Incoming events change that remembered state. A toy car may be IDLE, DRIVING, or FAULT; the same button press means “start” in IDLE and “stop” in DRIVING.
Formally, a finite-state machine can be written as next_state = F(current_state, input). Outputs may depend only on state, or on state and input. Time becomes an input when firmware compares a monotonic clock with a saved deadline. A transition table makes the contract inspectable: for every state and relevant event, name the next state and output. This is preferable to scattered Boolean flags, where impossible combinations such as moving = true and faulted = true can arise.
Blocking delays hide inputs while the processor waits. A non-blocking loop instead samples inputs, updates state, sets outputs, and returns quickly. For a desk robot, choosing a separate FAULT state is a build decision: motor commands become zero from one auditable branch rather than from several hoped-for checks. Entry actions run once when a state changes; continuous actions run every pass while it remains active.
A common misconception is that more states always mean needless complexity. Too few states can conceal distinct obligations such as “motor stopping” versus “motor stopped.” The opposite failure is encoding every sensor value as a state. Keep durable operating modes as states and transient measurements as data. Trace events on paper before coding; an unhandled event is a design gap, not merely a syntax problem. The associated simulator is a bounded behavioral state model, not MCU or electrical emulation.
Worked example
Problem
A status LED must be ON for 300 ms after a button press while the loop runs every 20 ms. Trace a non-blocking two-state design when presses arrive at 100 ms and 260 ms.
Steps
- At 100 ms, transition IDLE → LIT and set deadline = 100 ms + 300 ms = 400 ms.
- At 260 ms, define the LIT + press transition to remain LIT and refresh deadline to 560 ms.
- Checks at 400, 420, …, 540 ms keep the LED on because now < 560 ms; the 560 ms check transitions to IDLE and turns it off.
Result
The LED is on from 100 ms through the check before 560 ms, so the second press extends the visible interval without pausing input handling.
Sanity check
The final deadline is exactly 300 ms after the latest press, and the 20 ms loop quantizes turn-off by at most one loop period.
Check your understanding
A robot has IDLE, MOVING, and FAULT states. While MOVING it detects overcurrent. Which transition is safest and easiest to audit?
A. Set a fault flag but remain MOVING until the current falls B. Transition immediately to FAULT, command zero motor output, and require an explicit reset condition C. Call a 5-second delay and then return to IDLE D. Toggle between MOVING and IDLE on every loop pass
Your answer: ______________________________
Reasoning:
Answer key
ANSWER KEY — check only after attempting the question.
B. Transition immediately to FAULT, command zero motor output, and require an explicit reset condition
An explicit FAULT transition centralizes the safe output and recovery rule. A flag while remaining MOVING permits other MOVING logic to keep issuing drive commands. A blocking delay prevents observation and cannot establish that the cause disappeared. Rapid toggling is not recovery; it creates unpredictable output and loses the meaning of state.
Hands-on lab
Goal
Implement and trace a three-state button-controlled LED machine without blocking delays.
Equipment
- 3.3 V microcontroller board
- on-board LED or LED with calculated series resistor
- momentary button or safe jumper
- USB data cable
- serial console
Procedure
- Write a transition table for OFF, ON_TIMED, and FAULT before writing code.
- Poll the button and monotonic milliseconds; print timestamp, input, old state, and new state only on transitions.
- Make a press enter ON_TIMED for 1 s and a second press refresh its deadline.
- Introduce a deliberate logical fault by temporarily omitting the refresh transition; reproduce it from the trace, then restore the transition.
- Add a long press that enters FAULT with the LED off, and define a release-plus-new-press recovery.
What to observe
- Expected: normal loop activity continues during the one-second interval and the second press moves the deadline.
- Record actual transition timestamps and compare each interval with 1.00 s; do not report expected timing as a measurement.
- Expected fault signature: with the refresh transition omitted, the state still returns to OFF at the first deadline despite the second press.
Transfer challenge
Sketch the states and transition guards for a small screen that alternates between a menu, a live sensor view, and a recoverable sensor-error page.
Cautions
- Use only board-level 3.3 V/5 V hardware; calculate an external LED resistor and never connect an LED directly across the supply.
Evidence record
Learner: ____________________ Date: ____________________
Evidence artifact or file: ____________________________________________
| Item | Record |
|---|---|
| Prediction or expected result | |
| Actual observation or measurement | |
| Conditions and tools used | |
| Difference from expectation | |
| Next decision or follow-up |
Notes: