Week 9 · Monday, November 2, 2026 · Room D-221
The dashed arrow turns solid.
For eight weeks the architecture diagram has promised a link between the two machines. Today the ESP32 joins Wi-Fi, the Pi runs a message broker, and the light reading you calibrated last week leaves the USB cable for the network, where anything on the bench can hear it. One protocol carries it all: MQTT, the quiet standard behind most of the Internet of Things.
What happens today
Theory · first hour
Publish/subscribe, and MQTT
Why request/response is the wrong shape for telemetry; the pub/sub pattern and the decoupling it buys; MQTT's broker, topics, wildcards, quality-of-service levels, retained messages and last wills; and the honest word on security for an open bench broker.
Lab · two hours
End to end, both boards
Install and configure Mosquitto on the Pi (two walls stand between you and a working broker; both fall in this hub), put the ESP32 on Wi-Fi, publish the calibrated light reading once a second, subscribe from Python with paho-mqtt, then a ladder that adds node status, a dark alert on the Pi's LED, and a command channel back to the node.
In the course outline
This is Week 9 of 420-302-VA, the middle week of phase 3 and of Assignment 2: whatever the brief asks of telemetry gets built and demonstrated this week, per the three-week plan, with A2 due next Monday, November 9. The administrative course-drop deadline (AE) is tomorrow, Tuesday, November 3; anyone weighing that decision should speak with the teacher today. Everything built this week is permanent infrastructure: the broker serves Week 10's controller, Week 11's Flask dashboard, and the LIA project to the end of term.
The week the system appears
Until now the course has built parts: a repository, a server, programs, a sensor node. This afternoon, for the first time, there is a system: two computers with different jobs, cooperating over a network, using an industrial protocol, about something physically real. The moment to watch for comes early in the lab, a terminal on the Pi printing bench/s07/light 42.3 while your hand shades a sensor wired to a different machine entirely. It looks small. It is the architecture of every connected factory, greenhouse and building you will ever work in, at desk scale.
Why not just request the data?
The obvious design is the one the web taught everyone: the Pi asks the node for a reading, the node answers, repeat. Request/response is a fine pattern, and for telemetry it ages badly on three fronts:
- It couples everyone to everyone. The asker must know each device's address, be updated when devices appear or vanish, and ask each one separately. Ten nodes and three consumers is thirty standing relationships to maintain.
- Polling wastes exactly what IoT lacks. Asking once a second costs traffic and power whether or not anything changed, and still leaves up to a second of staleness; asking faster costs more of both. Battery nodes and constrained links cannot afford conversation that mostly says "nothing new".
- It inverts who knows when there is news. The device holding the sensor knows the instant something changes; request/response makes it wait to be asked. Event-driven systems, your
when_pressedcallbacks since Week 4, already taught you the better shape: the side with the event speaks.
Publish/subscribe fixes all three with one move, a middleman, and the next page is the theory of that move.
Why this course teaches it now
The node earned it
A network lesson with nothing to say is ceremony. Your node has a calibrated reading and a message format you designed on purpose last week; today that design decision becomes live topics.
A2 and Week 10 stand on it
The brief's telemetry lives here, and next week's controller needs eyes: the control loop closes over exactly the messages this week starts flowing.
It is the industry's answer
MQTT is the de facto IoT standard, born in industrial telemetry and now everywhere from factory floors to home automation. Learning it is not a classroom abstraction; it is the actual tool.
Three ideas you will reuse for the rest of the course
Decouple through a middleman
Publishers and subscribers never meet: both talk only to the broker, addressed by topic. Adding a consumer, a logger, a dashboard, a second student's laptop, changes nothing at the source. That is what architects mean by loose coupling.
Topics are a namespace you design
bench/s07/light is a design decision, like a variable name times a thousand: hierarchy, wildcards and future growth all hang on it. Week 8's message-format rung was the warm-up.
Callbacks, again, bigger
The Pi does not loop asking "anything yet?"; it registers on_message and the library calls it when news arrives, your when_pressed pattern, graduated from a button to a network. Week 6 promised this exact moment.
What you will be able to do by the end of the week
- Explain pub/sub versus request/response and the decoupling a broker buys, with the telemetry arithmetic.
- Define topic, payload, QoS level, retained message and last will, and choose each appropriately.
- Install Mosquitto on the Pi, configure it past its localhost-only default, open its port in UFW, and verify it with the command-line clients.
- Connect the ESP32 to Wi-Fi from MicroPython, keep credentials out of Git, and publish the calibrated light reading on a sensible topic.
- Subscribe from Python with paho-mqtt, callbacks as bound methods on a monitor class.
- Give the node a retained status topic with a last will, and send it commands on a channel of its own.
Words you will hear all day
| Term | Plain meaning | Common mix-up to avoid |
|---|---|---|
| Broker | The server every message passes through; ours is Mosquitto, on the Pi. | It routes and holds almost nothing; it is a post office, not a database. |
| Client | Anything connected to the broker: the node, the Pi's script, a terminal tool. | Publisher and subscriber are roles, not kinds of client; one client can be both. |
| Publish / subscribe | Send a message to a topic / ask to receive messages matching a topic filter. | Publishers never address subscribers; both only ever address the broker. |
| Topic | A slash-separated name messages are published under: bench/s07/light. | Case-sensitive, no spaces by convention, and never starts with a slash. |
| Wildcard | + matches one level, # the rest: bench/+/light, bench/#. | Wildcards appear only in subscriptions, never in a published topic. |
| Payload | The message body: bytes on the wire, meaning by your design. | Expect bytes in code; decode() before treating it as text. |
| QoS | Delivery promise per message: 0 at most once, 1 at least once, 2 exactly once. | Higher is not better, it is costlier; periodic telemetry is happy at 0. |
| Retained message | The broker keeps the last retained message per topic for late subscribers. | One per topic, replaced each time; it is a sticky note, not a history. |
| Last will (LWT) | A message the broker publishes for a client that vanishes ungracefully. | Declared at connect time, before anything goes wrong; that is the point. |
| Port 1883 | MQTT's standard TCP port (8883 for its TLS twin). | A port the firewall must allow, exactly as 22 was in Week 3. |
| Service / daemon | A program the OS supervises: started at boot, restarted, logged. Mosquitto becomes one today. | Managed with systemctl, not launched by hand in a terminal. |
| SSID | A Wi-Fi network's name; the node joins the bench network by it. | The ESP32 speaks 2.4 GHz only; a 5 GHz-only network is invisible to it. |
Where this fits in the course
Week 8 · Oct 26
ESP32 and analog
The node and its calibrated reading: everything published today was measured and formatted there, on purpose.
Week 9 · Nov 2 · this hub
MQTT and Wi-Fi
The bench becomes a network: broker on the Pi, node on Wi-Fi, subscriber in Python, status, alerts and commands.
Week 10 · Nov 9
Control: closing the loop
The PID lesson lands and A2 is due: the controller's eyes are this week's telemetry, its hands last week's PWM.
Working at home
The full bench reproduces at home with the Week 2 Pi setup plus one condition: the ESP32 and the Pi must share a 2.4 GHz Wi-Fi network (the ESP32 cannot see 5 GHz-only networks; most home routers and phone hotspots can offer 2.4 GHz, sometimes behind a setting). The node's broker address is whatever hostname -I says on that network, not the bench value, which is exactly why the config-file pattern keeps such numbers out of the code. No second network at hand? Everything up to the broker's loopback tests runs on the Pi alone.