Assessment Practice: Tasks A & B
Rehearse the two assessed practicals in the simulator: a two-button speed selector that reports every change, and a sensor alarm with hysteresis that fails safe when the sensor breaks.
What this chapter is for
Two of the practical assessments are built and marked on the bench, with real buttons, a real sensor and a scope. This chapter rehearses the part that catches most people out: not the wiring, but the logic.
- Task A: Extractor Fan Speed Selector - two buttons, three speeds, one Serial line per change
- Task B: Cabinet Over-Temperature Alarm - a sensor, two thresholds, and an alarm that must never fail quiet
Work through the exercises here until they pass first time. Then you can spend the assessment sessions on the build, the measurements and the evidence, instead of debugging the logic.
Read this first. Passing the tests here is *not* the assessment and it is not evidence. The tasks are marked on your plan, your wiring, your measurements, your test table and your explanation. The simulator has no transistor, no oscilloscope and no thermistor - it only checks that your code decides the right thing.
Task A: one state variable runs everything
The fan has three speeds: OFF, LOW and HIGH. The temptation is to scatter analogWrite() calls all over the sketch. Don't. Keep one variable that says which state you are in, and one function that makes the outputs match it:
- the buttons only ever change
state showState()sets the fan, sets the running LED and prints one line
That is why the brief asks for exactly one Serial line per change: if showState() is only called when the state actually changed, you get that for free. Printing in loop() instead floods the monitor and fails the criterion.
The duty values come straight from the brief: OFF is 0, LOW is 40% which is 102, and HIGH is 100% which is 255.
| State | Fan D6 (PWM) | Running LED D5 | Serial line |
|---|---|---|---|
| OFF | 0 | off | Fan: OFF (0%) |
| LOW | 102 (40%) | on | Fan: LOW (40%) |
| HIGH | 255 (100%) | on | Fan: HIGH (100%) |
The three states, stepped by a timer
No buttons yet - this just walks through the three states so you can watch the two LEDs and read the Serial Monitor. The named constants are worth copying: SPEED_LOW says far more than 1.
Fan: OFF (0%) Fan: LOW (40%) Fan: HIGH (100%) Fan: OFF (0%)
- The fan LED is on a
~pin so it can dim. The running LED is only ever on or off. showState()is called once insetup()so the outputs are right before anything is pressed.
Make the outputs match the state
Before the buttons, get the outputs right. state is already declared; the tests set it to each of the three values in turn and check both LEDs.
In loop(), drive the fan on D6 and the running LED on D5 from state:
SPEED_OFF- fan0, running LED offSPEED_LOW- fan102, running LED onSPEED_HIGH- fan255, running LED on
Button A steps through the speeds
showState() is written for you at the bottom. All you have to write is the bit that changes state.
On each new press of Button A on D2, step OFF → LOW → HIGH → OFF and call showState() once. Nothing must be printed while the button is simply held down.
Fan: LOW (40%) Fan: HIGH (100%) Fan: OFF (0%)
Button B stops the fan
Add Button B on D3. A new press returns the fan to SPEED_OFF from any speed.
One catch, straight from the brief: it prints one line per change. Pressing B when the fan is already off changes nothing, so it must print nothing.
Fan: LOW (40%) Fan: HIGH (100%) Fan: OFF (0%) Fan: LOW (40%)
Twenty presses, twenty steps
The assessor will press Button A twenty times quickly and count the steps. Real contacts chatter, and the test below now feeds your sketch that chatter: two presses arrive as five steps.
The debounce timer is already written - it notices when either raw reading moves and restarts a 20 ms clock. Your job is the two blocks inside it: act on a button only when its trusted reading is HIGH and the settled raw reading is LOW.
Fan: LOW (40%) Fan: HIGH (100%)
Task B: two thresholds, and never fail quiet
Task B watches a cabinet and sounds an alarm when it overheats. On the bench the sensor is a thermistor and you convert its reading to °C with the Beta equation. Here we work in raw ADC counts so the exercise is about the two decisions that are actually marked - hysteresis and the fail-safe. Drag the slider to change the reading; higher means hotter.
Hysteresis means using two thresholds instead of one. With a single threshold at 700, a reading that wobbles 699, 701, 699, 701 switches the alarm on and off several times a second. So: switch on at 700 or above, and only switch off again at 600 or below. Between 601 and 699 nothing changes - whatever the alarm is doing, it keeps doing.
Fail-safe means deciding what a broken sensor should do. An unplugged thermistor reads either 0 or 1023, and neither is a real temperature. An alarm that stays quiet because its sensor fell off is worse than useless, so a fault must switch the alarm on.
| Reading | Alarm off now | Alarm on now |
|---|---|---|
| 0 or 1023 | fault - switch on | fault - stay on |
| 601-699 | stay off | stay on |
| 700 and above | switch on | stay on |
| 600 and below | stay off | switch off |
What the sensor is doing
Run this, then drag the slider. It prints the reading twice a second so you can see the range the thresholds sit in. The alarm LED is not wired up yet - that is the next exercise.
Sensor: 300 Sensor: 300 Sensor: 300
- Dragging the slider while the sketch runs is the simulator's version of warming the thermistor with your hand.
- 0 and 1023 are the ends of the slider - use them later to pretend the sensor has fallen off.
One threshold
Start with the naive version, so you can see what is wrong with it.
Read A0 and switch the alarm LED on D8 on when the reading is 700 or more, and off when it is below 700.
Add the hysteresis
Now the real requirement. Keep a variable that remembers whether the alarm is on, and use two thresholds:
- alarm off and the reading reaches 700 or more - switch on
- alarm on and the reading falls to 600 or less - switch off
- anywhere in between - leave it alone
The test walks the reading up past 700, back down to 650, and only then down to 550. The alarm must still be on at 650 on the way down, and off at 650 on the way up.
Fail safe, and report every change
The last two requirements together. There are now three states, and the constants and the reporting code are already written - you write the decision.
- reading is
0or1023- the sensor is broken: stateFAULT - coming back from
FAULTwith a sensible reading - back toNORMAL NORMALand 700 or more -ALARMALARMand 600 or less -NORMAL
The alarm output is on in ALARM and in FAULT. That one line is the difference between a Competent and a Not Yet Competent on the fail-safe criterion.
NORMAL ALARM NORMAL SENSOR FAULT NORMAL
The state on the LCD
Task B is marked on the display too: *both LCD rows are clean in every state, with no leftover or overlapping characters*. SENSOR FAULT is 12 characters and ALARM is 5, so printing ALARM over SENSOR FAULT leaves ALARMR FAULT on the screen.
Finish showState() so row 2 always shows the state padded to 12 characters. Row 1 is already done for you.
Taking it to the bench
What you have written here is the middle of each task. The marks are in what surrounds it, so plan for those too:
- Task A - the state table on paper before you wire anything, the LED current calculation, the scope measurement of D6 at LOW (about 490 Hz, 40% duty) and a test table with real observed results. The assessor will press Button A twenty times and count.
- Task B - the Beta equation with your own R0, T0 and B, a calibration table against a reference thermometer, and the transistor or MOSFET stage. The buzzer never goes straight onto a pin. The assessor will unplug your thermistor mid-demonstration.
Two differences to watch for when you move this code to real hardware. First, the readings here are raw ADC counts; on the bench you convert to °C first and compare against 30.0 and 28.0, using float for the temperature. Second, an NTC thermistor reading gets smaller as it gets hotter, so once you have wired yours, check which way your divider goes before you decide which comparison is >=.
The full briefs, the evidence lists and the marking grids are on the Practical Assessments page.