Final examination & D3: one day, two proofs
420-302-VA · WEEK 13 · FALL 2026

Utility · the misconception clinic, part two

Clinic 2

Week 7's rule has not changed: exam questions are built around the specific wrong beliefs students reliably form, because distinguishing who shed them is what an exam is for. These are the post-midterm suspects, each a plausible model that happens to be wrong, stated plainly and corrected, with its home page holding the demonstration. Misconceptions feel exactly like knowledge from the inside; read the left column slowly enough to notice any pull.

Same clinic, new suspects

Part one, Week 7's clinic, covers Git, the Pi, the terminal, Python and GPIO; it is still live and still examinable. This page continues the series through the distributed system, and the beliefs below are stickier than part one's for a reason worth knowing: each is a correct model of a simpler system, imported. Request/response intuitions imported into pub/sub, single-program intuitions imported into five programs, "more gain is more control" imported from proportional thinking into dynamics. The correction, in every row, is noticing which system the belief actually describes.

The clinic: wrong belief, true belief

Wrong beliefTrue beliefWhere it costs
"All ESP32 pins with ADC are equivalent; pick any."Two banks: ADC2 is unusable while Wi-Fi is on; networked sensing lives on ADC1 (GPIO32–39), which is why the bench reads on GPIO34.Any "reads garbage since we added Wi-Fi" scenario; W8
"Publish sends the data to whoever asked for it."Nobody asks. Publishers address a topic, the broker routes to current subscribers, and sender and receiver never know each other: decoupling is the point.Sequence and architecture questions; W9
"The broker stores the messages, so late joiners get the history."The broker stores at most one retained message per topic, the last one flagged -r; history is your own logger's job.Ghost readings, logging designs; W9, figure below
"QoS 2 is the best setting, so use it everywhere."QoS buys delivery promises with handshakes: 0 fits once-a-second telemetry whose next value supersedes the last; 1 can duplicate; 2 pays most. Fit, not rank.Design-choice questions; W9
"Keep-alive means the node re-connects automatically."Keep-alive is the broker's death test (silence beyond 1.5 × the interval ⇒ presumed dead, LWT fires). Reconnection is your code's job; the bounded retry wrote it."Status says online but…" scenarios; W9
"Raising Kp always improves control."Raising Kp shrinks ess = (SP − d)/(1 + K·Kp) and destabilizes: overshoot grows, then sustained oscillation. The sweep figure is the proof.Tuning questions; W10
"The D term reduces steady-state error too; it fights error like the others."D responds to the error's rate only: at rest it contributes nothing, so it cannot touch ess; what it buys is damping, and what it costs is noise × 2πf.Term-matching questions; W10
"Integral windup means Ki is set too high."Windup is the integrator accumulating while the actuator is saturated, at any Ki; the cure is conditional integration, not merely a smaller gain.The windup figure's question; W10
"Our broker has no password, so MQTT is an insecure protocol."Mosquitto ships secure-by-default (local-only since 2.0); the bench's open config is a deliberate classroom choice, and password_file plus TLS (8883) are the protocol's normal dress.Security-honesty questions; W9
"0.0.0.0 is an address you type into the browser."It is a bind choice: which interfaces the server listens on (loopback only vs all). The browser visits the Pi's real address; the two walls, bind and firewall, fall separately.The two-walls questions; W11
"Timeout, connection refused, and a null reading are three flavours of 'it's down'."Three different culprits: timeout = never reached (network, firewall); refused = reached, nobody listening (service, port, bind); null/stale = listening but empty (the bridge never fed). Three probes, three fixes.Diagnosis questions; figure below, W12
"active (running) means the service works."It means a process exists. Serving is separate (the refused test), and health is separate again: Restart= can hide a crash loop that only journalctl shows.Service questions; W12
"The walking skeleton is a quick prototype we will throw away."A spike is throwaway; the skeleton is the first permanent version, grown rung by rung. Cockburn's distinction, and the repo's tags are its paper trail.Method questions; W12
"Polling is wasteful; push is simply better."Patterns fit loops: push serves the machine-speed loop, polling serves the human-speed one, and at 2 s on a bench the cost is negligible while the simplicity is not. Week 11 priced it.Two-patterns questions; W11

Demonstration: the retained ghost

A timeline demonstrating the retained message ghost. At time one, the node publishes retained 62 on the light topic; the broker's retained slot for that topic now holds 62. At time two, the node powers off; the slot still holds 62. At time three, hours later, a fresh dashboard subscribes and immediately receives 62, shown as a ghost reading on the page, looking alive. At time four, the fix: publish a retained empty message, mosquitto pub dash r dash n, and the slot is cleared; a fresh subscriber now receives nothing until real data flows. 1 · publish -r 62 2 · node dies 3 · fresh subscriber 4 · the fix node publishes-r "62" slot: 62 slot: still 62 ✕ powered off,hours pass page shows 62the ghost: looks alive slot: 62 → handed over mosquitto_pub -r -nclears the slot slot: empty
One slot per topic, holding the last flagged message, forever. The ghost is that slot outliving its publisher: a fresh page "receives data" from a node that died hours ago. The status topic with its LWT is the antidote pattern (the page can see the node is offline), and -r -n is the exorcism. Run it as a rung-5 experiment; the review page scripted it.

Demonstration: three signatures, three causes

Three panels, each a different failure signature for the same user complaint, the page shows nothing. Panel one, timeout: the request hangs then gives up; the arrow from laptop toward Pi fades before arriving; cause, never reached, network or firewall; first probe, ping, then the firewall rules. Panel two, connection refused: the arrow reaches the Pi and bounces back instantly; cause, reached but nobody listening on that port; first probe, is the service running and bound where you think, systemctl then the Flask banner in journalctl. Panel three, null or stale value: the request succeeds, 200, but the JSON holds null or an old number; cause, the server is fine and the bridge never fed it; first probe, the firehose, is anything arriving to bridge. timeout connection refused 200, but null / stale you Pi …hangs, then gives up you Pi reached · bounced, instantly you Pi answers politely: {"light": null} never reached:network path or firewall probe: ping, then ufw status reached, nobody listening:service down, wrong port, bind probe: systemctl, then the banner server fine, bridge never fed:subscription, topic, or node probe: the firehose, upstream One complaint, three signatures, three first probes: reading the signature correctly saves the whole ladder below it.
The system tells you which wall you hit, if you listen. Timeout, refused, and null are as different as three dial tones, and Weeks 9, 11 and 12 each taught one: the firewall's silence, the bind's bounce, the bridge's polite shrug. Exam diagnosis questions are this figure in prose.

Stuck?

Revision stuck is its own symptom with its own ladder, and Week 7's still fits: find the layer (recall, application, connection) before throwing hours at the wrong one. The one addition for this material: when a distributed-system idea will not settle, run it (rung 5 of the ladder) before rereading it; five minutes of firehose beats an hour of prose for QoS, retained, and the walls.

Before you ask for help

  • The belief as you would have stated it, in one sentence; naming it is most of the cure.
  • What the home page's demonstration showed, and where your model and the demonstration part ways.
  • For bench-testable beliefs: your written prediction and what actually happened.