Stage 2 of 6 · The synthesis · read before any rereading
One system, one story
Twelve weeks taught twelve subjects, and the exam will test one system. The strongest review move is to collapse the subjects back into the thing they always were: a single causal chain you can narrate hop by hop, with the governing number at each hop. Once the story runs in your head without notes, every topic has an address in it, and recalling a fact becomes walking to where it lives.
Why one story beats twelve summaries
Memory research and bench experience agree here: isolated facts decay, and facts woven into a causal structure prop each other up, because each hop cues the next (shade the LDR and you cannot help but remember what the divider does to the voltage, which cues the ADC, which cues the averaging). The same structure is how exam questions are built: almost every question is a zoom into one or two hops of this chain, asked forward (what happens next?), backward (what caused this reading?), or broken (which hop failed?). Learn the chain once and you have pre-answered the framing of most of the paper; the Week 12 half-splitting page already taught you to navigate it under the third framing.
The journey: photon to pixel
Practice the narration in all three exam directions. Forward: start at the photon, speak every transformation. Backward: start at a pixel showing 62 % and account for where that number has been. Broken: pick any hop, imagine it failing, and name the symptom each later hop would show, which is Week 12's half-splitting run in reverse.
The two loops
The deepest structural fact of the course, and the one that organizes the most exam material, is that the system is two loops sharing a sensor, running at speeds roughly an order of magnitude apart:
Hold this figure against any "why" question from the last five weeks and it answers: why two protocols (each loop got the pattern matching its rhythm, Week 11's two-patterns argument), why the supervisory setpoint travels over cmd while control stays local (the fast loop must survive the slow one disconnecting, Week 10's fast-local rule), why polling at 2 s is honest engineering rather than waste (the human loop needs human speed, nothing more), and why the dashboard's reading may lag ~3 s while the LED answers in a blink (count the loop each signal rides).
Where each week lives in the story
| Weeks | Hops owned | The one-line summary the story compresses to |
|---|---|---|
| 8 | Photon → percent | The analog world enters: divider, ADC1 under Wi-Fi, averaging, and a class that speaks percent |
| 9 | Percent → every subscriber | The bench becomes a network: topics, QoS, retained, LWT, and a broker with two walls |
| 10 | Reading → action | The loop closes: error, three terms, tuning, and the supervisory pattern over cmd |
| 11 | Reading → pixel, hand → setpoint | The human loop: Flask, the bridge between push and ask, and a dashboard that steers |
| 12 | All hops, joined and kept alive | The method: skeletons, one join at a time, half-splitting, and services that survive the night |
| 1–6 · via W7 | Everything underneath | Git, the Pi, the terminal, Python, GPIO and objects: the floor the story stands on |
Checklist for this stage
Check yourself
The dashboard reads 62 %. Account backward for that number through four transformations, with the governing fact at each.
fetch (within the past 2 s) got from /api/light, which returned the bridge's latest, updated at the last publish (within about 1 s), so the number is at most ~3 s old. The published 62 came from LightNode mapping a raw reading onto the dark-to-bright calibration span. That raw reading was read_avg's mean of 16 ADC samples, noise cut by √16 = 4. Each sample was the 12-bit ADC on GPIO34 (ADC1, so Wi-Fi-safe) placing the divider's voltage on one of 4096 levels; and the divider's voltage followed the LDR's resistance, which followed the light. Five sentences, the whole top half of the figure.Why would moving the rule into the browser's JavaScript break the system's design, in two-loops terms?
Name the two places the loops meet, and explain why the SP meeting point travels over MQTT's cmd topic rather than being written by Flask directly into the rule program's memory.
cmd message because the bridge and the rule are separate programs, by design, since Week 10 split deciding from showing; MQTT is the course's one mechanism for programs to talk without sharing memory, and a "sp:N" message keeps the contract written, observable on the firehose, and stubbable with mosquitto_pub. Writing into shared memory would work only by merging the programs, trading away the decoupling that lets each be probed, restarted and owned separately, which Week 12 turned into services.