ESP32 & analog: the world is more than on and off
420-302-VA · WEEK 8 · FALL 2026

Stage 5 of 6 · Released today · 15% · due Week 10 (Monday, November 9)

Assignment 2

The PID light-harvesting brief is on Omnivox as of today, and it is written as a requirements document in exactly the house style Week 5 taught, on purpose. This page does not replace the brief; it teaches you how to work it, and gives the control theory behind it an honest preview.

What Assignment 2 is

A2 asks your pair to build a closed-loop light controller on the bench you assembled this week: the system measures light with your calibrated sensor, compares it to a setpoint, and drives the PWM output with a PID control law so the measured value holds the target despite disturbances, a hand's shadow, a flashlight, the room changing. It is worth 15%, spans three weeks by design (released Week 8, networked context Week 9, control implemented and verified Week 10), and is due in Week 10, Monday, November 9. The brief on Omnivox is the authoritative document: its requirement IDs, deliverables and dates govern wherever this page is more general.

Why "harvesting"

The name points at the application family: systems that manage captured light automatically, greenhouse supplemental lighting that tops up the sun to a growth setpoint, daylight-harvesting building controls that dim fixtures as windows brighten. Your bench version is the same loop at desk scale, and the engineering content, sensing, setpoint, correction, verification, is identical.

Reading the brief like an engineer

A requirements document is worked, not read. The protocol, which is Week 5 cashing out:

  1. First pass: the shape (today, 15 minutes, together)

    Scope, deliverables, dates, grading weights. No analysis yet; the goal is that both partners can say what is due, when, in what form, without opening the document again.

  2. Second pass: the contract (this week, an hour)

    Go shall by shall. For each requirement, write its row in a verification table before any code exists: the R-ID, the check you will perform, the evidence you will keep. A requirement you cannot yet imagine verifying is a question for the teacher, not a blank to skip.

  3. The questions log

    Ambiguities, apparent conflicts, missing numbers: log them, date them, and ask early, in class or by Omnivox message. Week 5's repair shop taught you to spot weak spec lines; a real project is where spotting them earns actual marks and saves actual weekends. An ambiguity discovered November 8 is a crisis; the same ambiguity on October 28 is an email.

  4. Trace everything to the table

    From here to the due date, the verification table is the project's dashboard: every work session should turn at least one row from open to demonstrated. "Are we done?" has a defined answer, which is the whole point of specifying first.

PID, previewed honestly

You have met PID in your automation courses as the workhorse of industrial control; A2's novelty is that you will write one, in Python, around twenty lines. The structure, so the brief's vocabulary lands today. Everything starts from the error, the gap between where you want the measurement and where it is:

e(t) = setpoint − measurement(t)

The controller's output (for us, the PWM duty) is a weighted sum of three views of that error:

u(t) = Kp·e(t)  +  Ki·∫ e dt  +  Kd·de/dt
         now        the past       the trend
  • P, proportional: push in proportion to the present error. The muscle of the controller, and alone it typically settles near the target with a persistent offset, since zero error would mean zero push.
  • I, integral: accumulate past error and push on the total. The memory that grinds away steady-state offset, and the term that misbehaves when the actuator saturates (the accumulated total "winds up"); the brief and Week 10 deal with that honestly.
  • D, derivative: respond to the error's rate of change. The anticipation that damps overshoot, and the term most sensitive to noise, which is why your averaging choice from the analog page is already a control decision.

In discrete code, the integral becomes a running sum of e·Δt and the derivative a difference quotient (e − e_prev)/Δt, which is why the loop runs at a fixed period measured with monotonic()-style ticks, Week 5's timing rule reporting for duty. Week 10 implements and tunes all of this; today you only need the three terms' names and jobs, because the brief speaks them. Reference for the curious: PID controller, whose diagrams will look like home.

The loop you will build

A2's system is this week's bench plus one box:

Loop elementControl nameYou built it
Calibrated light percentageProcess variable (PV)Analog in: calibration, smoothed per averaging
The target light levelSetpoint (SP)A number in your code today; where it comes from later is a design question the brief addresses
SP − PV, each cycleError eOne subtraction, Week 10
The PID lawControllerWeek 10's lesson and A2's core
PWM duty on the LEDActuator / control output uAnalog out, clamped to 0 to 65535
Shadows, flashlights, the roomDisturbancesYour hand, during verification, on purpose

Notice how much of the loop already exists after one afternoon: of the six elements, four are running on your bench. That is why A2 is released today and not in Week 10, the sensing and acting deserve two weeks of maturing before the control law arrives to depend on them.

The three-week plan

WeekA2 workDone means
8 (now)Both brief passes; verification table drafted; questions logged and sent; bench skills from this hub solid; calibration anchors recorded; LightNode class workingTable committed to the A2 repo with every R-row present; node reads calibrated percent on demand
9 (Nov 2)MQTT week: the node's readings go on the network, per what the brief asks of telemetry; the message format from rung 4 becomes real topicsWhatever the brief's networking requirements are, their table rows demonstrated
10 (Nov 9)Control week: the PID lesson lands, the loop closes, tuning and disturbance tests fill the remaining rows; A2 due per the briefEvery row demonstrated, evidence committed, submission per the brief's instructions

Also on the calendar: the administrative course-drop deadline (AE) is Tuesday, November 3, and the LIA project's first milestone (D1) follows in Week 11; A2 finishing on time is what keeps that week calm.

Working protocol

  • One repository for A2, from today: docs/ holding the verification table and questions log, src/ holding the node code, .gitignore as always. Commits from both partners, messages that say what changed; the repo's history is part of the evidence of how you worked.
  • Pair rules per the brief; the course default stands, navigator and driver, swapping, with the navigator owning spec and capsule boundaries.
  • Evidence as you go, never retroactively: a table row turns demonstrated with its proof attached, a photo, a logged run, a REPL transcript, the day it happens.
  • The brief wins. Wherever this hub's examples and the brief differ, pin numbers, thresholds, message formats, deliverable names, the brief governs, and noticing a difference is worth a questions-log line.

Checklist for this stage

Check yourself

Why does A2 arrive two weeks before the lesson that implements its core?
Because the control law is the smallest part of a control system: the sensing, actuation, calibration and verification scaffolding deserve maturing time, and the brief-reading itself is assessed engineering work. Four of the loop's six elements run after today; the schedule exists so the last two land on a solid floor.
What belongs in a verification-table row, and why is the table written before the code?
The requirement's ID, the concrete check that will demonstrate it, and the evidence to be kept. Written first, it defines "done" independently of the implementation, turns progress into rows demonstrated, and surfaces untestable or ambiguous shalls while they are still cheap questions.
P alone leaves an offset; I removes it. Explain both facts from the equations.
With u = Kp·e, holding any nonzero output (needed to fight a constant disturbance) requires a nonzero error: the system settles where the push balances the load, short of the target. The integral term accumulates that residual error over time, growing its contribution until the error itself is driven to zero, the memory that finishes the job.
Why is your averaging n from the analog page already a PID decision?
The derivative term amplifies rapid changes, noise included: a jittery PV makes D twitch the actuator. Heavier averaging calms D but delays the PV, adding lag the loop must tolerate. The filter and the controller are one design, which is why the brief cares about your sensing chain.
The measured light sits at 60%, setpoint 50%. What sign is the error, and which way should a sensible controller move the duty?
e = 50 − 60 = −10: negative error, too bright. The controller's output should decrease, lowering the LED's duty, u moves with e's sign through the positive gains. Checking this sign convention on paper before coding prevents the classic runaway-in-the-wrong-direction first test.
Where does Week 5's "monotonic for intervals" rule reappear in A2?
The discrete integral and derivative both divide or multiply by Δt, so the loop must run at a known, steady period measured with a monotonic clock. A wall-clock jump would corrupt both terms at once; the timing rule is now a control-correctness rule.