Arduino Ladder · Bozoma Innovation Hub

Bozoma Innovation Hub  ·  Arduino Ladder  ·  Band 8

Build for Nzemaland

The last band. No new components, and that is the point. You already have everything you need to build something a person actually wants. What you do not yet have is a way to organise a device that does several things, and a way to find out honestly whether it works.

About 12 hours, and most of that is your own build. Finish Bands 5 and 7 first. Band 6 helps if your project moves something.

Choose your build

Swap means build it instead of the one on this page: it teaches the same things and leaves you just as ready for the next band. Everything else on this page still applies, including the Check yourself questions. Practice is short, comes after the core, and gives you no sketch: the job, the check, and the code is yours. Bench is not a build at all: it is an instrument or an idea, done once, and everything after it is easier for having done it.

Sketches for this band

Click one to save it, or get every sketch at once from the downloads page. Each file opens with a plain-English header telling you what it does and how to wire it.

Start here

What is different about this band

Every band so far handed you a brief. Build a signal tower. Build a lock. Build a game. You could always check your work by comparing it with the picture.

This time nobody gives you the brief. You go and find one, from a person with a problem, and the only way to know whether you succeeded is to give the finished thing back to them and watch.

That is a genuinely harder job, and it fails in ways that have nothing to do with code.

Two things you need first

  • A way to organise a device that does several things. Every project worth building has modes: waiting, working, warning, quiet. Written the obvious way, four modes become a tangle nobody can follow, including you next week. Parts 1 to 5 teach the way out.
  • A way to be honest about whether it works. Everything works on the desk of the person who built it. Parts 6 to 10 are about finding out whether it works anywhere else.

By the end you will be able to

  • Break a device into states and write it so an impossible combination cannot happen
  • Turn something a person said into criteria you can actually check
  • Say what your device does when the power comes back
  • Draw wiring somebody else can follow without asking you a question
  • Watch a real person use your build without helping them
  • Judge your own work against criteria you wrote before you started

What you need

  • Everything from the previous bands. No new parts.
  • Band 6's battery pack, if your build moves anything. Which means Band 6's rules come with it, and this is the band where nobody is checking your work. Battery red to the + rail, battery black to the − rail, or the rails are dead metal and nothing you build will move; the + rail is then about six volts and no Arduino pin may ever touch it; a knob's power leg goes straight to the Arduino's 5V pin, never to the + rail; and one more wire, separate from the battery's black one, joins the − rail to an Arduino GND pin, always, or the Arduino and the battery share no ground and your signals have no way home. Write those four lines onto your wiring drawing before you build anything, and check the finished board against them with the battery switched off.
  • The same full-size breadboard Bands 5 and 7 needed. This band's worked example runs out to column 42.
  • Card, tape, a box or a bottle, and whatever will make a housing that survives being carried
  • Paper, for the criteria and the wiring drawing. This band uses more paper than solder.
  • One real person with a real problem, and their patience for twenty minutes twice
If you cannot find a personThen the person is you, and you have to be strict about it. Pick a problem you actually have, in a place you actually go, and write the brief before you know what you will build. Then test it a week later, cold, in that place. Being your own user is harder than it sounds, because you already know all the answers.
Part 1

Think first: what is the kettle doing?

20 min

No board for this part. Pick a thing near you that has more than one behaviour: an electric kettle, a phone, a fan with a timer, a washing machine, a torch with modes.

Write down every different thing it can be doing. Not what it can do; what it is being, right now, at any given moment. For a kettle: sitting there, heating, boiled, empty and refusing.

Now for each one, write what makes it stop being that and become something else. Sitting there becomes heating when somebody presses the switch. Heating becomes boiled when the water is hot enough. Heating becomes sitting there if somebody lifts it off.

Then ask the awkward question: can it ever be two of them at once? Can a kettle be heating and boiled at the same time? Can it be empty-and-refusing while heating?

You should seeNo. Not one pair of them can happen together. A kettle is always doing exactly one of those things, and never none of them either.
Write these down
  1. How many different things can your object be doing? Most people find three to five.
  2. Pick two of them. What exactly would it look like if it were doing both at once?
  3. Is there a way for it to be doing none of them? What would that even look like?
  4. When you plug it in after a power cut, which one is it doing? Who decided that?

That last question is the one nobody thinks about and everybody meets. Your device will lose power. When it comes back, it will be doing something, and if you did not choose what, then it chose for you.

Keep this paper. Part 3 turns it into code almost line for line.

Part 2

One thing at a time

30 min

What you just wrote down has a name. Each of those behaviours is a state, and a device that is always in exactly one of them is a state machine.

That sounds grand and it is not. It is one variable and a few branches. But choosing to write it that way changes what your device can do wrong, and that is why it is worth a whole part.

WAITINGlamp offARMEDlamp onALARMbuzzer + flashSNOOZEDquiet 30 sbutton pressedwater is highbutton pressed30 seconds up The board is in exactly one box at a time. An arrow is the only way out of a box, and every arrow has something written on it that has to happen first.
A water tank alarm as four states. The boxes are what it is doing. The arrows are the only ways to move between them, and every arrow has a condition written on it.

Read that picture like a map. There is no arrow from WAITING straight to ALARM, so that jump cannot happen. Not “should not”. Cannot. There is no line to travel along.

Why not just use true-or-false names?

The obvious alternative is a name for each thing that might be true:

bool armed = false;
bool alarming = false;
bool snoozed = false;

That looks simpler and it is a trap. Three true-or-false names means eight combinations, and only four of them make any sense. The other four are nonsense that nothing prevents and nothing warns you about.

Flags everywhere One state bool armed = false; bool alarming = false; bool snoozed = false; bool wasHigh = false; if (armed && !snoozed) { if (high && !alarming) { if (!wasHigh) { ... } } else if (alarming) { if (snoozed) { ... } int state = WAITING; if (state == WAITING) { ... } else if (state == ARMED) { ... } else if (state == ALARM) { ... } Four true-or-false names means sixteen combinations. Most are nonsense, and nothing stops the board reaching one. One name, four values, four branches. Nonsense combinations cannot happen, because there is nothing to combine.
The same device written both ways. On the left, four flags and a nest of conditions. On the right, one name with four values and one branch each.
Count it yourself

Two true-or-false names: 2 × 2 = 4 combinations. Three: 2 × 2 × 2 = 8. Four: 16. Five: 32.

Every one you add doubles the number of situations your code has to survive. And you have to think of each one yourself, because nothing tells you when the device reaches a combination you never considered.

One state name with four values reaches four situations. Adding a fifth state makes five. Not ten. Five.

Words to know
state
What a device is doing right now. Always exactly one, never two, never none.
state machine
A way of writing a program as a set of states and the conditions that move between them.
transition
Moving from one state to another. An arrow in the picture.
flag
A true-or-false name standing for one fact. Useful alone, dangerous in groups.
Part 3

Guess, then run the machine

40 min
+ − − + j i h g f e d c b a 1 5 10 15 20 USB ARDUINO UNO + + 220 220 button button a1 a1 a21 a21 a3 a3 a4 a4 b1 b1 b3 b3 b4 b4 e19 e19 e21 e21 f19 f19 f21 f21 j19 j19 SCL SCL SDA SDA AREF AREF GND GND 13 13 12 12 11 11 10 10 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 IOR IOR RST RST 3V3 3V3 5V 5V GND GND GND GND VIN VIN A0 A0 A1 A1 A2 A2 A3 A3 A4 A4 A5 A5
Two parts, five wires, nothing else. Everything hard about this part is in the sketch.

Here is the heart of b8_01_states_given.ino. Read it before running it.

const int WAITING = 0;
const int ARMED   = 1;
const int ALARM   = 2;
const int SNOOZED = 3;

int state = WAITING;

void enterState(int newState) {
  state = newState;
  stateSince = millis();

  if (state == WAITING) digitalWrite(ledPin, LOW);
  if (state == ARMED)   digitalWrite(ledPin, HIGH);
  if (state == SNOOZED) digitalWrite(ledPin, LOW);

  Serial.print("now in state ");
  Serial.println(state);
}
Guess before you run it
  1. WAITING is just the number 0. Why bother giving it a name?
  2. Why is there no line for ALARM inside enterState?
  3. stateSince = millis() happens on every change, whichever state you go to. What is it for?
  4. Somewhere in this sketch is the only line that ever changes state. Why does having exactly one matter?
Start from an empty boardUnplug the USB. Take everything from Band 7 off the breadboard: the sensor, the screen, the buzzer, the knob and all their wires. This build needs two parts and you want to see them clearly.

Both ends of every wire. Pull them out of the Arduino header too, so nothing is left in the pins. A wire you forgot is invisible when you are looking at the breadboard, and one Arduino pin takes one wire.

Which rails this band means. Your breadboard has two pairs, one along each long edge, and on most boards the two pairs are not joined to each other. In this band, “the + rail” and “the − rail” always mean the pair along the top edge, nearest row j. Pick that pair now and use only it. The buzzer sits down in rows a and b, so its rail wire is a long one that runs round the end of the board; run it rather than reaching for the nearer rail, because mixing the two pairs means nothing works and nothing looks wrong.

The light. LED long leg into b3, short leg into b4. Resistor from a3 to a1. Wire b1 to pin 7. Wire a4 to the − rail.

The pin wire goes in b1, not a1, because the resistor leg is already in a1 and a hole takes one leg only. Same column, same connection.

The button. Four legs into e19, e21, f19 and f21, body over the middle channel. Wire j19 to pin 2. Wire a21 to the − rail.

One wire from the − rail to a GND pin.

You should seeTwo parts on the board, five wires in total, and nothing else.

Upload b8_01_states_given.ino and open the serial monitor (Tools, then Serial Monitor, 9600).

You should seenow in state 0 printed once. The light is off. Press the button: state 1, light on steady. Press again: state 2, light flashing fast. Press again: state 3, light off. Wait five seconds without touching anything: state 1 again, light back on steady.
If one press moves it two statesThe button is bouncing. Look at the delay(20) inside buttonJustPressed and make sure it is still there. That is the debounce from Band 3.
If nothing prints at allSerial monitor not at 9600, or the wrong board or port selected.

Now go round the whole cycle three times, watching the printed states, and check they always go 0, 1, 2, 3, 1, 2, 3, 1 and never anything else.

You should seeExactly that. Press as fast as you like; you will not find a fifth number and you will not find two at once.
The answers to the four questions

1. The board does not care. You do, in six months. if (state == 2) tells a reader nothing; if (state == ALARM) tells them everything. It is the same reason you gave your pin numbers names in Band 1, and you counted the benefit yourself then.

2. Because ALARM flashes, and flashing is not one thing you set once. It is something that has to keep happening, so it lives in runAlarm, which is called over and over. enterState is only for what happens at the moment a state begins.

3. So that any state can ask “how long have I been here?” SNOOZED uses it to leave after five seconds. Putting it in enterState means every state gets it for free and you cannot forget to set it.

4. This is the important one. With one place that changes state, everything that must happen on a change happens there, once. Scatter state = ALARM across five places and you will eventually write one of them and forget the light, and the device will be in ALARM with the wrong light on, which is very hard to spot.

Part 4

Now break it on purpose

35 min

b8_02_buggy_flags.ino is the same device, wired the same way, written with three flags instead of one state.

It is not badly typed. Every line in it is reasonable on its own. Upload it and press the button slowly, watching both the light and the serial monitor.

What you will actually seePress once: light on steady, and it prints armed=1 alarming=0 snoozed=0. Press twice: flashing. Press a third time and the light freezes, stuck at whatever it happened to be, for five whole seconds. The serial monitor says armed=0 alarming=1 snoozed=1.
Find the fault yourself

Look at the bottom of the sketch. There are three branches that write to the light:

if (armed && !alarming && !snoozed) { ... }
else if (armed && alarming) { ... }
else if (!armed && !alarming) { ... }
  1. Take the combination the serial monitor printed: armed false, alarming true, snoozed true. Check it against each of the three branches in turn. How many match?
  2. So which line of code writes to the light during those five seconds?
  3. Now press a fourth time, and a fifth, and keep pressing. Can you ever get back to a steady light again?
  4. Three flags. How many combinations are there? How many make sense?
The answer, after you have written yours

1. None of them match. The first needs armed true. The second needs armed true. The third needs alarming false. The combination armed=false with alarming=true fits nowhere.

2. No line at all. That is the whole answer. The light is not off, and not on: it is untouched. Whatever it was doing when the freeze began is what it keeps doing, because nothing is writing to it.

3. Only by accident, and never on purpose, and that is worse than never. Snoozing always lands it back in flashing, because nothing clears alarming on the way out. But two more presses inside the frozen five seconds happen to walk the three flags back to 1 0 0, and the steady light returns. Let the five seconds run out and any press puts you straight back into flashing.

Sit with that for a moment, because it is the real lesson. The behaviour depends on how fast you pressed. Nobody can describe this device, nobody can write instructions for it, and nobody can repair it, because the same button does different things depending on timing that is not written down anywhere. Write down the exact presses that got you back, and then notice that you could not have predicted them by reading the code. Neither could I.

4. Eight combinations. Four make sense. The code defends three of them. The other five were never thought about, and one of them is where the device is stuck.

Nothing here was a typing mistake, so no amount of careful typing would have prevented it. The fault is in the shape.

The comparison that matters

Go back and look at b8_01. Ask yourself: could that sketch reach a state with no branch?

It could not, and not because it was written carefully. state is one name holding one of four values. There is no fifth value, so there is no unhandled case to reach. The bug in b8_02 is not merely absent from b8_01; it is impossible there.

That is what people mean when they say a piece of code is well structured. Not that it is tidy. That whole families of mistakes cannot occur in it.

Part 5

Look closer: the shape you will reuse

30 min

Every state machine you write from here on, and probably for the rest of your life, has the same five pieces. Learn the shape, not the sketch.

PieceWhat it isIn b8_01
The namesOne const int per state, starting at 0WAITING, ARMED, ALARM, SNOOZED
The one variableHolds which state you are in, and nothing elseint state
The one doorThe only place state ever changes. Sets outputs for the new state.enterState()
One function per stateWhat to do while here, and what would make you leaverunWaiting(), runArmed(), and so on
The dispatcherA few lines in loop that call the right oneThe if chain at the bottom

The rule about enterState

Look at what it does and notice something easy to miss: it sets the light for every state, including the ones where the light is off.

That is deliberate, and it is the same habit you learned in Band 1 when you wrote all three lights in every traffic state rather than only the ones that changed. Set every output every time. Leaving one out is how a buzzer gets stuck on, and it will be stuck on in exactly one rarely-used path that you will find at the worst moment.

In b8_03 you can see this taken seriously: enterState starts by turning the buzzer and both lights off, and then switches on only what the new state needs.

Fill this in by hand

For b8_01, complete the table. Two of the boxes have no answer, and working out which two is the exercise.

From stateButton pressedFive seconds pass
WAITING
ARMED
ALARM
SNOOZED
Answer, after you have filled it in

WAITING + button goes to ARMED; time does nothing. ARMED + button goes to ALARM; time does nothing. ALARM + button goes to SNOOZED; time does nothing. SNOOZED + button goes to WAITING; SNOOZED + five seconds goes to ARMED.

So the empty boxes are the first three in the time column. Only SNOOZED cares about time.

A table like this is worth drawing for your own project before you write any code. It is quicker than writing the code and it finds the same mistakes. Every empty box is a question: is nothing really supposed to happen there?

When you have more than five statesTwo of them are probably the same thing with a different light on. Look for two states whose functions differ only in an output, and see whether one variable can tell them apart instead. Five is a lot. Ten means the shape is wrong.
Part 6

Finding a brief worth building

45 min

Now the other half of the band. Everything above was about how to write it. The rest is about knowing what to write, and whether it worked.

A brief is not an idea you had. It is a problem somebody else has, described in their words, before you have thought of any solution.

Briefs on offer, if you want one
  • Water tank level alarm. Warns before the poly tank overflows, in time to close the valve.
  • Poultry brooder temperature alarm. Warns when the chicks' house gets too cold at night.
  • School bell or period timer. Rings at set times so nobody has to watch a clock.
  • Borehole pump run indicator. Shows from the house whether the pump is actually running.
  • Market stall night alarm. Notices if the stall cover is opened after closing.
  • Charging kiosk queue light. Shows from a distance whether a slot is free.

Every one of these is buildable with what is already in your box. None of them needs a part you do not have.

If none of those six is your problem, do not take one anywayA brief you do not care about produces a device nobody wants, and you will feel it by day three. Go and find your own: an hour walking round the hub, the compound or the market asking three people what goes wrong in their day that nobody has fixed will give you something better than this list.

Then read Invent a project before you design anything. It has the pin budget that decides whether your idea fits on one board at all, the four questions that kill a bad idea in five minutes, and the one-sheet plan this band is about to ask you for anyway.
Nothing in this course goes near mains electricity, and nor do you

Three of those briefs sit next to something that plugs into a wall: a bell, a pump, a charging kiosk. You do not wire onto any of them. Your board, your battery pack and everything you have built in nine bands work at six volts or less. Mains is hundreds of volts, it does not warn you, and it kills people who were sure they knew what they were doing.

The rule for this band, and for everything you build after it. Never open, cut into, strip or connect anything to: a wall socket, a plug, a mains cable, a distribution board, a pump, a bell, a fridge, a fan that plugs in, or any wire you did not put there yourself.

What you do instead is better engineering anyway. A device that senses from the outside is a device that cannot break the thing it is watching, and can be fitted by anybody, and removed in a second.

  • Is the pump running? Feel it, do not tap into it. A pump vibrates and it is loud. Tape the board's box to the pipe and sense the shake, or put the sound sensor near it.
  • Ring the bell. Do not switch the bell. Use your own buzzer, loudly, or a light. A period timer that beeps is a period timer.
  • Is the charging slot free? Do not touch the charger. Sense the phone with the distance sensor, or put a button under the shelf that the phone's weight presses.

If a brief seems to need you to switch mains, the brief is not finished yet. Go back to the person and ask what they would actually see, hear or feel if the thing were working. That answer is always something you can sense from outside, and it is always the honest version of the problem.

Go and ask somebody

Whether you take a brief from that list or bring your own, the next step is the same and it is not optional.

Find the person who has the problem and ask them to describe it. Not what they want you to build. What goes wrong now.

Write down what they said, in their words, in quotation marks. Do not tidy it. Do not turn it into a specification yet.

You should seeSomething messier than you expected, containing at least one detail you would never have guessed. That detail is usually the most valuable thing in the whole conversation.

Ask three questions and write the answers down.

  • “When it goes wrong, what happens next? What do you do about it?”
  • “Where would this thing live, and who else is around it?”
  • “What have you already tried?”

The third question saves the most time. If somebody already tried something and it failed, find out why before you build the same thing again.

The most common mistake in this partArriving with a solution already in mind and asking questions that confirm it. If you catch yourself saying “so would it help if it beeped?”, stop and ask “what happens now?” instead. You are trying to learn the problem, not sell the answer.
Part 7

Criteria, written before you build

40 min

Now turn what they said into a list of things you can check. This is the single most valuable half hour in the band, and it is the one people skip.

The reason to write criteria first is not organisation. It is honesty. Criteria written afterwards are always met, because you write down whatever you happened to achieve. Written first, they can tell you something you did not want to hear.

Words to know
brief
A problem somebody else has, in their words, written down before you have thought of any solution.
criterion
One thing you can go and check, that decides whether the device works. More than one of them are criteria.
hysteresis
Using two numbers instead of one, so a reading has to move a real distance to change anything. You do not need the word. You do need the habit.
EEPROM
A small permanent memory in the chip that survives being switched off. For settings and totals, not for anything that changes every second.

What makes a criterion checkable

Not checkableCheckableWhy
The alarm is loud enoughCan be heard from the next room with the door shutSomebody can go and stand there
It warns in good timeWarns when the water is 15 cm from the top, which is about four minutes of fillingThere is a number and a reason for it
It is easy to useSomebody who has never seen it can silence it within ten secondsYou can watch and count
It is reliableRan for six hours overnight without a false alarmYou either did that or you did not
It handles power cutsComes back armed by itself, with nobody there to press anythingPull the plug and see
Write five criteria for your own brief now

Before any wiring. Before any code. Five is enough, and they must include these two:

  1. One about what happens after a power cut.
  2. One about whether a person who has never seen it can tell what it is doing without being told.

Then show the list to the person whose problem it is and ask: “if it did all five of these, would that solve it?”

You should seeEither yes, in which case you now have a target, or a correction, in which case you have just saved yourself a week. Both answers are good. Only silence is bad.

Put the list somewhere you will see it while you build. Tape it to the wall. Every time you are tempted to add a clever feature nobody asked for, the list is there to ask why.

Part 8

A worked capstone, end to end

60 min
+ − − + j i h g f e d c b a 1 5 10 15 20 25 30 35 40 45 USB ARDUINO UNO HC-SR04 VCC / Trig / Echo / GND HC-SR04 VCC / Trig / Echo / GND + + 220 220 + + 220 220 button button + + buzzer buzzer a1 a1 a21 a21 a3 a3 a4 a4 a40 a40 a42 a42 a5 a5 a7 a7 a8 a8 b1 b1 b3 b3 b4 b4 b40 b40 b42 b42 b5 b5 b7 b7 b8 b8 e19 e19 e21 e21 f19 f19 f21 f21 f24 f24 f25 f25 f26 f26 f27 f27 j19 j19 j24 j24 j25 j25 j26 j26 j27 j27 SCL SCL SDA SDA AREF AREF GND GND 13 13 12 12 11 11 10 10 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 IOR IOR RST RST 3V3 3V3 5V 5V GND GND GND GND VIN VIN A0 A0 A1 A1 A2 A2 A3 A3 A4 A4 A5 A5
The worked capstone. The sensor is at f24 to f27, not Band 7's f20 to f23, because the button already owns columns 19 and 21.

Read b8_03_tank_alarm_worked.ino from its first comment to its last line before you build anything. It is a whole project done properly and it is shorter than you would expect.

The brief it came from

“Our poly tank overflows at night because nobody sees it filling. I want a warning while there is still time to close the valve, loud enough to hear from the next room, and I want to be able to shut it up without switching the whole thing off.”

Notice what is in there. A problem, a time constraint, a loudness constraint, and one specific complaint about a device they have used before: it could only be silenced by switching it off entirely. That last clause is where the SNOOZED state came from.

How it measures water with no water sensor

The ultrasonic sensor from Band 7, pointing straight down at the water from the top of the tank. A full tank means a short distance.

Nothing touches the water. Nothing corrodes. This is how real tank sensors work, and you already had the part.

This is what the map means by “no new components required, and the constraint is the point”. Almost every problem in this list can be solved with something you already have, pointed at it differently.

The two thresholds

int alarmLevel = 15;          // cm from the sensor. Measure yours.
int clearLevel = 20;          // must fall below this to count as safe

Two numbers, not one, and the reason is the same as the deadband in Band 6 and the light threshold in Band 4. With a single threshold of 15, a reading wobbling between 14 and 16 starts and stops the alarm several times a second.

With 15 to alarm and 20 to clear, the water has to genuinely fall by five centimetres before the alarm stops. The reading can wobble all it likes in between and nothing flaps.

The name for this, if you want to look it upIt is called hysteresis. You do not need the word. You do need the habit, and you have now met it three times in three different bands, which is how you know it is a real idea and not a trick.

Build it and test it

Before you startUSB unplugged. The wiring is in the sketch's header, hole by hole. Read the sensor's holes there rather than reusing Band 7's. Band 7 put the sensor in f20 to f23, and the button in this build sits in columns 19 and 21, so f21 would end up holding a sensor pin and a button leg at once. The sketch puts the sensor in f24 to f27 instead. Every rail wire in this band goes to the top pair, nearest row j. Build it in stages and test each one, as you have every band since Band 3.

Build it and prove each state in turn with a bucket, or with a book you move towards the sensor to stand in for rising water.

You should seeGreen light on, quiet. Bring the book within 15 cm: red light flashing and a beep in time with it. Press the button: quiet, green light back on, but it does not go off again for 30 seconds even though the book is still there. After 30 seconds, if the book is still close, it alarms again.

Now test the criterion nobody tests. With the alarm going, pull the USB cable out and put it straight back in.

You should seeIt comes back on, green light, armed, all by itself. Within a second it notices the book is still there and alarms again. Nobody pressed anything.

Then test the awkward one. Take the book away entirely, wave your hand once across the sensor, and watch.

You should seeA brief alarm as your hand passes, then it clears. Ask yourself whether that is acceptable for a tank, and write your answer down. There is a real answer and it depends on the tank.
The question to answer in your log

Nothing in b8_03 checks that the water is still high before alarming again after a snooze. It just goes back to ARMED and lets ARMED decide.

Is that a bug, or is it the right design? Argue both sides in three sentences, then say which you would ship and why.

One way of thinking about it

It is the right design, and the reason is that ARMED already knows how to decide. If SNOOZED also checked the water level, there would be two places in the sketch that decide what “too high” means, and one day somebody would change one and not the other.

Every rule about your device belongs in exactly one place. That is the same principle as the single enterState, and the same as putting the sensor's zero-means-far-away decision inside readDistance in Band 7.

If you argued the other way and gave a good reason, that is also fine. The point of the question is to have the argument.

Part 9

What happens when the power cuts

30 min

Your device will lose power. In Aiyinasi it will lose power more than once a week. Every project in this band has to answer for that, and it is the criterion that separates a demonstration from something that can be left alone.

The three questions

  1. What state does it come back in? Whatever setup says. If setup says nothing, it is whatever the first value of your state variable happens to be, which is a decision you made by accident.
  2. Does that need a person? A device that comes back needing somebody to arm it is disarmed most of the time, because nobody knows the power came back.
  3. Does it forget anything that mattered? Counts, settings, the time. All of it is gone. Every number in your sketch goes back to what you typed.
The rule for this band

The state it comes back in should be the safe one, and it should get there without anybody.

For an alarm, that means armed. Not off, not waiting for a button. Look at b8_03: there is no OFF state at all, and setup ends with enterState(ARMED). That one line is criterion four.

Test it properly, three times

Cut the power while it is idle. Restore it. Does it come back doing the right thing?

Cut the power while it is alarming. Restore it. Does it alarm again, or has it forgotten?

Cut the power while it is snoozed. Restore it. This one usually surprises people.

You should seeThe snooze is gone and it alarms immediately. Whether that is right is a decision, and now you have to make it deliberately rather than discover it in the middle of the night.
If you need something remembered across a power cutThe chip has a small permanent memory called EEPROM that survives being switched off, and there is an EEPROM library that comes with the Arduino software. It holds a thousand or so numbers and can only be rewritten about a hundred thousand times, so it is for settings and totals, not for anything that changes every second. You do not need it to pass this band. Reach for it only if one of your criteria genuinely requires it.
Part 10

Wiring somebody else can follow

40 min
+ − − + j i h g f e d c b a 36 40 45 USB ARDUINO UNO + + buzzer buzzer servo servo orange orange red red brown brown 6 V battery pack 6 V battery pack a40 a40 a42 a42 b40 b40 b42 b42 SCL SCL SDA SDA AREF AREF GND GND 13 13 12 12 11 11 10 10 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 IOR IOR RST RST 3V3 3V3 5V 5V GND GND GND GND VIN VIN A0 A0 A1 A1 A2 A2 A3 A3 A4 A4 A5 A5
What a wiring drawing has to show. Note the two separate wires on the − rail: the battery's black one, and the ground link. Neither does the other's job.

A photograph of your breadboard is not documentation. It shows where the wires are, not what they are for, and a jumble of six identical red wires tells a reader nothing.

What another learner needs is a drawing plus a table, and both fit on one sheet of paper.

The drawing

Draw the breadboard as a rectangle. Mark the two rails and the middle channel. Draw each part roughly where it sits, and label it. Draw each wire as a line, and write on it where it goes.

It does not have to be beautiful. It has to be unambiguous. If two people could read it differently, it is not finished.

The table

Exactly like the pin plans in every band from 3 onwards, because those were written for the same reason.

PartPinHolesWiringWhy this pin
Buzzer6long b40, short b42a40 to pin 6, a42 to − railAny digital pin. 6 was free.
Battery pack——Red wire to the + rail. Black wire to the − rail. Without these two the + rail is dead metal and nothing moves. Band 6 Part 7 has the same two rows; Part 3 of this band took them off the board, so put them back.—
Ground linkGND—One wire from the − rail to an Arduino GND pin. Not optional, and not the same wire as the battery's black one. Without it the Arduino and the battery have no ground in common, and pin 9's signal has no way home.—
Servo9—Orange to pin 9, red to + rail, brown to − rail. The + rail here is the battery, about six volts. Only the servo's red wire may touch it. And any knob's power leg goes straight to the Arduino's 5V pin, never to the + rail.Any digital pin. But Servo.h stops analogWrite working on pins 9 and 10, and tone stops it working on 3 and 11.

The last column is the one people leave out and the one a reader most needs. “Any pin, 6 was free” tells them they can move it. “Must be a ~ pin because it fades” tells them they cannot. Without that column, every pin looks equally sacred.

The test for your documentation

Hand it over and walk away

Give your drawing, your table and your parts to somebody who has done Band 3, and go and do something else. Do not hover. Do not answer questions.

Come back in twenty minutes. Whatever they got wrong is a fault in your documentation, not in them.

You should seeAt least one thing they got wrong, and it will be somewhere you thought was obvious. That is the normal result and it is exactly what the exercise is for.
If you are working aloneTake your sketch apart completely, put every part back in the box, wait a full day, and rebuild it from your own documentation only. No looking at photographs. A day is long enough to have forgotten the things you never wrote down.

And the code

Your sketch is documentation too. Three things make the difference, and you have been doing all three since Band 5:

  • A header comment saying what it does, the wiring hole by hole, and anything surprising.
  • Names instead of numbers. Every number that could be tuned lives at the top with a name, once.
  • Small functions. If loop is more than about ten lines, something in it wants a name.

b8_04_project_skeleton.ino is a blank version of all of this. Save a copy under your own name and start there.

Part 11

Change it

50 min

Before you build something of your own, change somebody else's. Work on a copy of b8_03_tank_alarm_worked.ino.

Each of these forces you to touch a different one of the five pieces from Part 5, which is the point of doing them in order.

Bronze
Add a fifth state, TESTING, that you reach by holding the button down for two seconds from ARMED. In it, the red light and the buzzer come on for three seconds and then it goes back to ARMED, whatever the water is doing. Every alarm needs a way to prove it still works without waiting for a real emergency, and every alarm you have ever met has one.
Silver
Make alarmLevel settable from a potentiometer instead of being typed into the sketch, and show the level it is currently set to on the serial monitor. Then say in your log what this makes better and what it makes worse. There is a real cost and it is not obvious.
Gold
Make the snooze survive a power cut, using the EEPROM library, so that a device switched off and on again during a snooze comes back still snoozed with the right amount of time left. This is hard for an interesting reason, and finding the reason is most of the task.
The interesting reason, if you get stuck on GoldThe board does not know what time it is. millis starts again from zero every time it powers up, so a saved “snooze ends at 47000” is meaningless after a restart. You have to save how much snooze is left, not when it ends, and you have to write it often enough to be roughly right without wearing the EEPROM out.

That last sentence is the whole problem, and there is no clean answer. Write down the trade you chose.
The cost hiding in SilverA threshold you can turn is a threshold somebody can turn to the wrong place, including by accident, and the device will never tell them. A number typed into the sketch cannot be knocked. Convenience against reliability, and which one wins depends on who is standing next to it.
Make

Your capstone

6 hours or more
What to build

A device that solves a problem you can point at, for a person who is not you, tested by that person, housed well enough to live where it belongs.

No new components. Everything you need is in the box already, and the constraint is deliberate: it forces the interesting question, which is what to point your existing parts at.

It is finished when all of these are true
  • It meets the five criteria you wrote in Part 7, and you can demonstrate each one
  • It is written as states, and you can name every state and every transition
  • It comes back doing the right thing after a power cut, with nobody present
  • Its housing survives being carried to where it lives and left there
  • Another learner built it from your documentation without asking you a question. If you are working alone, this counts as passed when you take your own build apart, wait a full day, and rebuild it from your documentation only, with no photographs.
  • The person whose problem it is has used it and told you what they think. If that person is you, this counts as passed when it has been installed where it belongs for a full week and you have written down whether you trusted it and whether you acted on what it told you.

How to spend the time

StageRoughlyWhat you are doing
Brief and criteria1 hourParts 6 and 7. Paper only. No parts on the desk.
States on paper30 minBoxes, arrows, and the table from Part 5. Still no parts.
Build in stages2 hoursOne part at a time, tested before the next. As every band since Band 3.
Make it survive1 hourHousing, mounting, taping the wires down where they leave the board, and the power-cut test.
Test with a person30 minWatch. Say nothing. Write everything down.
Fix what they found1 hourThere will be something. There is always something.
Document and evaluate1 hourPart 10, then the honest write-up below.

Notice that an hour and a half of it happens before you touch a single wire, and two and a half hours happen after the code works. Most people spend all their time in the middle stage, which is why most projects work only on the desk of the person who built them.

The test that matters most in the whole course

Take it to where it belongs. Hand it to the person whose problem it is. Say one sentence, no more. Then be quiet and watch.

Do not help. Do not explain. Do not say “you just have to”. Let them be confused, and write down every second of it.

  • What did they look at first?
  • What did they try that you did not expect?
  • At what moment did they understand what it was telling them, and how long did that take?
  • What did they ask you? Every question is a thing your device failed to say.

Then ask them one question: would you leave this switched on tonight? The answer to that is worth more than everything else you will collect.

If you are working aloneInstall it where it belongs and leave it for a week without touching it. Then write down: did it still work, did you trust it, and did you actually use what it told you. A week of leaving something alone tests things no demonstration reaches, and it will find something.

The honest evaluation

One page, written against the criteria you wrote in Part 7, before you knew how it would turn out. For each of your five criteria, write which of these it is:

  • Met. With the evidence: what you did to check, and what happened.
  • Partly met. With what is missing and what it would take.
  • Not met. With why, honestly. A criterion you missed and understood is worth more than one you quietly rewrote.
The rule about changing criteriaYou may not change them now. If you found halfway through that one was wrong, say so in the evaluation and explain what you learned. That is a better answer than a list of five green ticks, and any facilitator worth having will value it more.
Evidence

What to hand in

Five pieces. All of them producible on your own, all reviewable in ten minutes.

PieceWhat it isWhat it proves
The thing itselfA three-minute video of it working where it belongs, including the power-cut testThat it exists, and that it works somewhere other than your desk
The brief and criteriaTheir words in quotation marks, and your five criteria, dated before the buildThat you solved a real problem rather than an imagined one
The documentationWiring drawing, pin table with the why column, and your commented sketchThat somebody else could build it
The build logWhat broke, what you tried, what fixed it, in orderThat you debugged rather than copied. A log with no failures in it is a copied project.
The evaluationOne page against your own criteria, plus what the user saidThat you can judge your own work without flattering it
The ninety-second explain

One more thing, and it is the cheapest to record and the hardest to fake. A voice note, ninety seconds, walking through your own sketch.

Pick any line and say why it is there. If you cannot say why line 12 exists, the band is not earned yet, and it is far better to find that out now than in six months when somebody asks you to change it.

Show your work

Post all five pieces. Then look at one other person's capstone and do the hardest useful thing: build their project from their documentation alone and tell them exactly where you got stuck.

If you are doing this course aloneThere may be nobody to post to and nobody else's work to look at. That is fine, and it does not let you off this part. Do it this way instead: save the video, the photographs and all five documents into a folder named for this band, and then be your own second reader. Take the build apart, wait a day, and rebuild it from your own documentation only. Every point where you had to remember something rather than read it is a gap, and you should fix it before you call the band finished.
Part 12

Check yourself

20 min

Code you have not seen. Answer from reading only. Do not upload it.

const int IDLE  = 0;
const int OPEN  = 1;
const int SHUT  = 2;

int state = IDLE;
int lampPin = 7;
int buzzerPin = 6;
int sensorPin = A0;

unsigned long stateSince = 0;

void enterState(int newState) {
  state = newState;
  stateSince = millis();

  if (state == IDLE) digitalWrite(lampPin, LOW);
  if (state == OPEN) {
    digitalWrite(lampPin, HIGH);
    tone(buzzerPin, 880);
  }
}

void setup() {
  pinMode(lampPin, OUTPUT);
  pinMode(buzzerPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int reading = analogRead(sensorPin);

  if (state == IDLE && reading > 600) enterState(OPEN);
  if (state == OPEN && reading < 600) enterState(SHUT);
  if (state == SHUT && millis() - stateSince > 2000) enterState(IDLE);
}
  1. Three states are named. How many of them does enterState set the outputs for?
  2. The device goes IDLE, then OPEN, then SHUT. Describe exactly what the lamp and the buzzer are doing once it reaches SHUT, and say why.
  3. There is no enterState call in setup. Name one thing that is different because of that, in the first moment after the power comes on.
  4. The sensor is sitting right on the boundary and its reading wobbles between 599 and 601. Follow what happens, round by round, and say what a person watching would see and hear.
  5. Fix question 4 without adding a new state and without changing loop. Say which two numbers you would use and why they must be different.
  6. Somebody says “this is fine, it only has three states, so nothing can go wrong”. Using questions 2 and 4, say in two sentences why having states is not by itself enough.
Answers

1. Two. SHUT has no line at all in enterState.

2. The lamp stays on and the buzzer keeps sounding, for ever, until the state changes again. Nothing turns them off, because enterState never mentions SHUT. This is exactly the fault Part 5 warns about: set every output every time, including the ones being switched off. This is the question that matters most in this band. A state machine does not protect you if the door out of it forgets something.

3. Two things. stateSince is 0 rather than the moment the device started, so the two-second wait in SHUT is measured from the wrong place the first time round. And the lamp is never explicitly switched off, so at power-up it is in whatever state the pin happens to come up in rather than a state you chose.

A single enterState(IDLE) at the end of setup fixes both. It will not tell you what state you began in, though: unlike b8_01, this enterState has no Serial.print in it. Adding one is the second thing worth doing, and it is the single most useful line you can add to any state machine.

4. 601 sends it to OPEN, so the lamp and buzzer come on. 599 sends it to SHUT, which silences nothing, so they stay on. Two seconds later it goes to IDLE and the lamp goes off but the buzzer is still sounding. Then 601 again and round it goes. A person sees the lamp flickering on and off every couple of seconds while the buzzer never stops. It looks broken and every single line is doing what it says.

5. Two different numbers: go to OPEN above about 620, and back to SHUT only below about 580. The reading then has to move a real distance to change anything, so a wobble of one or two cannot flap it. They must be different, because a single boundary is a line the reading sits on, and any reading that sits on a line will cross it constantly. You met this in Band 4 with the light threshold, in Band 6 with the deadband, and in Part 8 of this band with alarmLevel and clearLevel.

6. States stop the device being in a combination nobody thought about, and that is worth a lot. They do not stop you forgetting an output on the way into a state, and they do not stop a wobbling reading throwing you between two states many times a second.

Part 13

Say these out loud

Part 12 was the real test. This is a warm-up for it, and a list to come back to. Say each of these out loud, to somebody or to yourself, without looking anything up.

  • Draw your own project as boxes and arrows, and name every state and every transition
  • Say why three true-or-false names are more dangerous than one name with four values
  • Say why enterState sets every output, including the ones being switched off
  • Turn a sentence somebody said into a criterion that can be checked
  • Say what your device does when the power comes back, and why you chose that
  • Hand your documentation to a stranger and have them build it
  • Say one thing about your own build that is not good enough yet
The one sentence from this band

It works on my desk is not a claim about the device. It is a claim about the desk.

Still stuck after 30 minutes?

Photograph the board from above, post your sketch, and say which state it was in when it went wrong and which state you expected. In this band that one detail is worth more than everything else, because it turns “it does not work” into a question somebody can answer.

If there is nobody to send it toWrite the three things down anyway, in your build log: what you expected, what happened, and what you have already tried. Add a print inside enterState if there is not one, and watch the serial monitor while you reproduce the fault. The sequence of states it prints usually contains the answer.
Problems

When something goes wrong

What you seeWhat it usually isWhat to do
A light or buzzer stuck on in one stateenterState does not set that output for that stateSet every output in enterState, including the ones being switched off. See Part 5.
The device freezes and no branch runsFlags instead of one stateSee Part 4. Rewrite it as one state variable.
One button press skips two statesBounceOnly act on the moment of pressing, and debounce. Band 3, and buttonJustPressed in b8_01.
It alarms and clears repeatedly on the boundaryOne threshold instead of twoUse a different number for going in and coming out. See Part 8.
Everything stops for a second at a timeA delay inside a state functionmillis and stateSince. Band 5, and every state machine here.
Works on the desk, fails where it livesLight, temperature, mounting or power differ thereRecalibrate in place. Band 4 taught this and it is still true.
Comes back doing the wrong thing after a power cutsetup does not choose a stateEnd setup with enterState(...) naming the safe one. See Part 9.
Wires fall out when it is carriedNo strain reliefTape every wire down where it leaves the board. A breadboard is not a permanent joint and never was.
Somebody used it wronglyNot their faultWrite down exactly what they did. That is your best finding of the day.

That is Band 8, and the end of the ladder. Go and build something nobody asked you to.

Done

What you know now

And that is the ladder

Nine bands. You started by making one light blink and not knowing which way round an LED goes. You can now measure the world, decide what a measurement means, move something in response, tell a person about it, organise a program that does several things at once, and find out honestly whether what you built is any use.

None of that is beginner work any more. The parts in your box have not changed since Band 0, and everything you can now do with them came from you.

What comes next is not another band. It is a bigger problem, a part you have not used before, and the same six steps you have run nine times: think first, guess, run it, look closer, change it, make your own. That pattern is the thing you actually learned. The Arduino was only where you practised it.

Before you call the ladder finished, make sure you have

  • All five pieces of evidence from the Evidence section, saved together in one folder
  • Your brief in the user’s own words, and your five criteria, written before you built anything
  • Your states drawn as boxes and arrows, and the transition table from Part 5
  • Your Bronze, Silver or Gold change to the tank alarm from Part 11, with the note on what it cost
  • Your ninety-second voice note explaining your own code
  • Your build log, with at least one thing that broke and what fixed it
  • Five or six correct answers in Part 12, including question 2

Ship it

One video under sixty seconds, and one post of five lines. The video is the same one this band already asks you for as evidence, so this is not extra work. It is the same work, done once, somewhere a person can see it.

Point the camera at: the device in the place it belongs, with the person whose problem it is.

The four shots: three seconds of the thing sitting still, fifteen of you doing something to it, fifteen of it responding all the way to the end, and ten of the honest bit, which is your measurement or the wire that was wrong the first time.

The line worth writing in the post: the criteria you wrote before you built, and how you scored against them.

Show your work has the five-line template, a worked example, and the three checks to make before anything goes public. Tag it #BozomaBuilds so all nine of yours sit together.