MTBuilder AcademyLearn it. Test it. Build it.
Code & microcontrollersLesson 25 of 48
Foundation50 minutes2 project connections

Programs as state-changing machines

Model firmware as explicit state transitions, then choose states that keep a desk robot responsive while it waits, moves, or reports a fault.

After this lesson, you can
  • Trace state variables through a timed input sequence and design a non-blocking finite-state machine with an explicit safe state.
ReadPracticedBench demonstrated
01

Understand

The working idea

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.

02

Follow the reasoning

Worked example

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.

  1. 1

    At 100 ms, transition IDLE → LIT and set deadline = 100 ms + 300 ms = 400 ms.

  2. 2

    At 260 ms, define the LIT + press transition to remain LIT and refresh deadline to 560 ms.

  3. 3

    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 checkThe final deadline is exactly 300 ms after the latest press, and the 20 ms loop quantizes turn-off by at most one loop period.

03

Try it yourself

Independent check

A robot has IDLE, MOVING, and FAULT states. While MOVING it detects overcurrent. Which transition is safest and easiest to audit?
04

Move to the bench

Implement and trace a three-state button-controlled LED machine without blocking delays.

Gather
  • 3.3 V microcontroller board
  • on-board LED or LED with calculated series resistor
  • momentary button or safe jumper
  • USB data cable
  • serial console

Experiment

  1. Write a transition table for OFF, ON_TIMED, and FAULT before writing code.
  2. Poll the button and monotonic milliseconds; print timestamp, input, old state, and new state only on transitions.
  3. Make a press enter ON_TIMED for 1 s and a second press refresh its deadline.
  4. Introduce a deliberate logical fault by temporarily omitting the refresh transition; reproduce it from the trace, then restore the transition.
  5. Add a long press that enters FAULT with the LED off, and define a release-plus-new-press recovery.

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 it

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.

Limits and 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.
05

Keep evidence

Bench note

Record what you expected, what you actually measured or observed, and one difference worth investigating. This is self-reported evidence, not a certification.

0 / 5,000A bench demonstration needs a concrete note of at least 20 characters.
Terms in this lessonBrowse the advanced glossary

Sources and further reading

  1. MicroPython RP2 quick reference
  2. Arduino Blink Without Delay