Bozoma Innovation Hub · Arduino Ladder · Band 6
Things That Move
Until now everything your board did was light or sound. Now it pushes something. The moment a program moves an object in the room, two new things become true, and neither of them is about code.
About 8 hours. Finish Bands 4 and 5 first. This band uses map, millis and your own functions as though you already know them, because you do.
Choose your build
- CoreThings That Movethe cardboard gate. This page. Everybody builds this one.
- SwapThe stepper dialA pointer that moves an exact number of steps and can turn for ever. It has no idea where it is, so you have to remember for it.
- SwapA fan on a transistorSpeed instead of position, and one three-legged part doing the whole job of a driver board.
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
- b6_01_servo_sweep_given.ino
- b6_02_servo_knob.ino
- b6_03_buggy_jitter.ino
- b6_04_servo_gate_worked.ino
- b6_05_motor_driver.ino
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.
What changes when a program moves something
A light does not care. Ask it for half brightness and it gives you half brightness, instantly, every time, and it never gets tired or stuck.
A moving thing is different in two ways that will surprise you.
- It takes time to get there. You tell it a position and it starts travelling. It arrives a moment later. Nothing in your code says so, and nothing warns you.
- It needs real power. A light draws a trickle. A motor pushing something draws far more than an Arduino pin can supply. Wire it the obvious way and the obvious way is wrong.
By the end you will be able to
- Make a servo go to a position you choose, and say why it is a position and not a speed
- Bring in code somebody else wrote, using a library, and read its documentation
- Explain why a shivering reading makes a shivering arm, and stop it
- Wire two power sources together correctly, and say what happens if you do not
- Build a mechanism out of cardboard that responds to something happening in the room
What you need
- Your board, USB cable and breadboard
- An SG90 servo, the small blue one with three wires and a bag of white plastic arms
- A potentiometer, one LED, one 220 ohm resistor, one push button
- A battery pack, four AA cells, with two loose wires
- Cardboard, scissors, tape, and a skewer or a straightened paper clip
- About ten jumper wires
- Only if you are doing one of this band's Swap projects instead of the servo gate:
- The stepper dial needs a 28BYJ-48 stepper and its ULN2003 driver board.
- The fan needs a small DC motor, an NPN transistor (an
S8050or2N2222; aBC547is too small for the job), a second 220 ohm resistor for the transistor's base, and a 1N4001-type diode, which is required and not optional. If you have no diode, use the ULN2003 board in the transistor's place; the project page explains how.
Think first: how hard is a push?
15 minBefore any wiring, spend ten minutes with your hands. This part has no board in it at all, and it is the reason the rest of the band makes sense.
Get a strip of card about as long as your hand and about two fingers wide. A piece of a cereal box or an exercise-book cover is ideal.
Pinch one end between your thumb and one finger so it sticks out sideways like a little gate. Now swing it up and down by turning your wrist.
Now put something on the far end. A coin, a rubber, a small stone. Swing it again.
Now hold the card still, halfway up, with the weight on it, for a full minute. Time it. Do not cheat.
Write these down
- Which was harder: moving the loaded card, or holding it still?
- When your fingers got tired, did the card sag smoothly, or did it wobble?
- If you made the card twice as long and kept the same weight on the end, would it get easier or harder? Try it and see rather than guessing.
The servo you are about to use has exactly your problem. Holding a position is work, not rest. A long arm is much harder than a short one with the same weight on it. And when it runs short of power, it does not stop cleanly. It wobbles, exactly like your tired fingers.
Keep this paper. In Part 7 your servo will wobble, and you will have two possible reasons for it rather than none.
What a servo is, and what it is not
20 minTake the servo out of the box. It is a small plastic block with three wires coming out of one side and a ridged stub on top. There is a small bag of white plastic arms with it.
Those white arms are called horns. Push one onto the stub now, gently, so you can see which way it is pointing. Do not screw it down, and do not turn it with your fingers. The reason is at the bottom of this part.
The idea that catches everybody
A servo is not a motor you switch on and off. You do not tell it to spin. You tell it an angle, and it goes to that angle and holds there until you tell it a different one.
So a servo is a position machine, not a speed machine. To move it slowly, you send it a long list of angles, one degree apart, with a small wait between each. The slowness comes from you, not from it.
This is the single most useful sentence in the band, so read it twice: the servo has no idea it is moving slowly. It is going as fast as it can, to a target you keep changing.
Words to know
- servo
- A small motor with gears and a sensor inside, which goes to an angle you name and holds it.
- horn
- The white plastic arm you push onto the top of a servo. Kits come with several shapes.
- angle
- Where the horn should point, from 0 to 180. The unit is degrees.
- library
- Code somebody else wrote that you can use in your own sketch by naming it at the top.
Guess, then make it move
30 minHere is the sketch you are about to run. Read it before you wire anything, and answer the four questions. Being wrong here is worth more than being right.
#include <Servo.h>
Servo gate;
int servoPin = 9;
void setup() {
gate.attach(servoPin);
}
void loop() {
for (int angle = 0; angle <= 180; angle = angle + 1) {
gate.write(angle);
delay(15);
}
for (int angle = 180; angle >= 0; angle = angle - 1) {
gate.write(angle);
delay(15);
}
}
Guess before you run it
- How many times does
gate.writerun in one full trip out and back? - Roughly how long does one full trip take? You have everything you need to work it out.
- What would happen if you changed both
15s to2? - What would happen if you deleted both
delaylines completely?
Write your four answers down before you go on.
Now wire it
Take three jumper wires with a stiff pin at both ends. Look at the end of the servo's lead: it is a small plastic block with three holes in it, not pins. The Arduino's sockets are holes too. So you need a pin at each end, one for each.
Brown or black wire to GND on the Arduino. Any GND pin. There are three and they are all the same.
Red wire to 5V on the Arduino.
Orange or yellow wire to pin 9.
Push a horn onto the stub so it points somewhere you can see, then plug in the USB and upload b6_01_servo_sweep_given.ino.
The answers to the four questions
1. 362 times. 181 angles going up, counting both 0 and 180, and 181 coming back.
2. About five and a half seconds. 362 steps at 15 milliseconds each is 5430 milliseconds. Your stopwatch will say roughly that.
3. It would sweep about seven times faster. It may also start to sound rough, because the servo is being given new targets faster than it can reach them.
4. This is the interesting one. The for loop would run through all 181 angles in a few thousandths of a second. The servo cannot move that fast, so it would only ever see the last target. What you would actually see is the horn jumping between the two ends, or shivering somewhere in the middle, not a sweep. The waits are not decoration. They are what makes it a sweep.
Look closer: using somebody else's code
30 minThree lines in that sketch are new, and all three are about the same idea.
The line at the top
#include <Servo.h>
This says: before you read the rest of my sketch, go and fetch the file called Servo.h and read that first. That file contains code somebody at Arduino wrote, tested, and gave away. It knows how to produce the exact signal a servo expects, which is fiddly and which you do not want to write.
A bundle of code like that is called a library. Take that line out and the word Servo means nothing, and the sketch will not compile.
The line that makes yours
Servo gate;
This makes one servo of your own and calls it gate. The name is yours to choose. Call it arm or lid or flap if that describes your build better.
If you had two servos you would write two lines, with two names, and each would be steered separately.
The two lines with a dot in them
gate.attach(servoPin);
gate.write(angle);
The dot means belonging to. Read gate.write(90) as “the write instruction belonging to gate, with the value 90”.
You have written digitalWrite(7, HIGH) many times, where the pin number is handed over every time. Here you told gate its pin once, in attach, and after that it remembers. Every later gate.write already knows which pin it is talking about.
Think of gate as a thing that remembers its own pin. You told it once. Ask it to write and it already knows where to write to. You do not need a word for this yet. You need to be able to read the dot.
Reading a library's instructions
You will meet libraries you have never seen. The skill is not remembering them, it is looking them up. For any Arduino library the reference lives at docs.arduino.cc under Libraries, and every library lists the same four things:
- What to include at the top of your sketch.
- How to make one, the
Servo gate;line. - What instructions it has, and what values each one takes.
- Examples. Open File, then Examples, then Servo in the Arduino software. Those examples are on your computer already and they run.
Servo has only a handful of instructions. Look them up now and write down what read() and detach() do. You will meet detach() at the end of Part 7, and use it in Part 11.
The knob drives the arm
35 minj7 may sit on it. That changes in Part 7 and never changes back.A sweep is a demonstration. A sweep that answers to something in the room is a machine. The smallest step from one to the other is the potentiometer from Band 4.
Move the servo's two power wires onto the breadboard rails. Red off the Arduino's 5V pin and into the + rail; brown off GND and into the − rail. The orange signal wire stays on pin 9 and does not move.
j7.This is also the shape Part 7 needs. When the battery arrives, the servo's red wire will not move at all. What changes is what feeds the rail.
Put the potentiometer into the breadboard so its three legs land in f5, f6 and f7. Press straight down on its body until it sits flat.
Wire j5 to the − rail and j7 to the + rail. These are the two outside legs, and either way round is fine: it only decides which way the knob turns.
j7 here, has to come off the + rail and go straight to the Arduino's own 5V pin instead.Learn it as a rule rather than a hole number, because you will meet it again in every build that has a battery: anything the Arduino reads is powered by the Arduino. The + rail is only for things that push. If you wire the knob the other way round, it is
j5 that has to move. Put a pencil mark on the power leg now.In this band, “the − rail” means the strip along the top edge, nearest row j. The + rail is the other strip up there. Pick both now and use only those two all band.
Wire j6 to pin A0. That is the middle leg, and the middle leg is the one that carries the answer.
Wire the + rail to 5V and the − rail to GND. Both are needed. The knob is a divider and it has to have both ends.
Plug in, upload b6_02_servo_knob.ino, and open the serial monitor (Tools, then Serial Monitor, and check the box in the corner says 9600).
Nothing here is new
map(reading, 0, 1023, 0, 180) is the same instruction you used in Band 4 to turn a knob reading into a brightness. The only difference is what is on the end of it. That is worth noticing: you have not learned a new idea, you have pointed an old one at a new thing.
Now break it on purpose
30 minTake your hand right off the knob. Do not touch the table. Listen.
This is not a fault in your wiring, and swapping parts will not fix it. Upload b6_03_buggy_jitter.ino, which is the same sketch with the printing removed so you can hear it clearly, and let us find out why.
Find the cause yourself
Go back to b6_02, which prints. Upload it, open the serial monitor, take your hand off the knob completely, and watch the numbers for twenty seconds without touching anything.
Now watch the angle column. Read twenty lines of it.
So who is at fault?
- Is the reading wrong?
- Is
mapwrong? - Is the servo faulty?
- What is the sketch doing with each of those readings?
The answer, after you have written yours
Nothing is wrong or faulty. A reading that wanders by one or two is normal and unavoidable. Every measurement of anything, anywhere, wobbles a little.
The fault is in the last question. The sketch acts on every single reading. Twenty times a second it says “go to 89”, then “go to 90”, then “go to 89”. The servo obeys. What you hear is a motor starting and stopping twenty times a second.
Say it in one sentence and keep the sentence: a shivering reading becomes a shivering arm, unless you decide it should not.
This is a new class of problem. In every band so far, a wrong output meant a wrong input or a wrong line. Here the input is right, every line is right, and the result is still bad. The fault is in what you chose to do with a good reading.
The fix has a name
You have built this once before. In Band 4 you used two limits with a gap between them, so a light reading wobbling on the boundary could not flap the lamp on and off. Same idea, new place, and now it gets a name.
Only move when the new angle is far enough from where you already are to be worth moving for. That gap is called a deadband, and it looks like this:
int deadband = 3;
int lastAngle = -100;
if (abs(wanted - lastAngle) >= deadband) {
gate.write(wanted);
lastAngle = wanted;
}
abs gives you the size of a number and throws away whether it was above or below. So abs(89 - 90) and abs(91 - 90) are both 1. You want to know how far apart they are, not which side.
lastAngle starts at −100, which is not a real angle. That is on purpose. Any first reading is more than 3 away from −100, so the arm always moves once at the start. Without it, the arm would sit wherever it happened to be until you touched the knob.
Words to know
- deadband
- A gap you decide on. A change smaller than the gap is ignored, so small wobbles do not become movement.
abs- Gives you the size of a number and throws away whether it was above or below zero.
abs(-3)is 3. detach- Stops the signal going to a servo. It goes limp, stops holding, and stops drawing much current.
- driver board
- A board that lets a small signal from a pin switch a large current from a battery. Needed for motors, not for servos.
The cost, and there is always a cost
With a deadband of 3, the arm can be up to 3 degrees away from where the knob says. It will not correct itself. You have traded a little accuracy for a lot of steadiness.
That is the right trade here and it is not always the right trade. Part 9 has you try three different values and listen to each. Think now about which you would choose for a gate, and which for a pointer on a dial, and why those are different answers.
Power, and the wire everybody forgets
35 minSo far your servo has been running off the Arduino's own 5V pin, with nothing attached to the horn. That works. It stops working the moment the arm has a job to do.
See it fail first
Tape a strip of card to the horn, about the length of your hand. Put something small and heavy on the far end. A coin taped on is ideal. This is the loaded card from Part 1, now driven by the servo.
Upload b6_01_servo_sweep_given.ino again and watch the small ON light on the Arduino while the arm swings.
Nothing is broken. The servo asked for more current than the Arduino's 5V pin can supply, and took what it could get. The voltage sagged for everyone on that pin, including the chip running your program.
This is the same thing as your tired fingers in Part 1. Not enough force available, so the position is not held cleanly.
The fix, and the trap inside the fix
Give the servo its own power. A battery pack of four AA cells goes straight to the servo's red and brown wires, instead of the Arduino.
Do exactly that and nothing works at all. The servo twitches, or buzzes, or sits there. This is where almost everybody gets stuck, and the reason is one missing wire.
You are going to build it wrong first, on purpose, and watch it fail. That takes two extra minutes and it is the difference between knowing this and having felt it.
Why the extra wire is needed, in plain words
“Five volts” is not a thing a wire has on its own. It is always five volts compared with something, and that something is ground.
The Arduino's signal wire says “here is a pulse, five volts above my ground”. The servo hears it and asks “five volts above my ground?” If those two grounds are not joined, nobody has told the servo where the Arduino's zero is, and the answer is meaningless.
Joining the grounds does not power anything. It tells both halves what zero means, so the signal has something to be measured against.
This matters. In a moment the + rail becomes battery power, about six volts, and the knob's wire to A0 would carry that straight into the chip. An Arduino pin must never see more than five volts. Take it out now and you cannot make that mistake.
The servo's red and brown wires do not move. They have been on the + rail and the − rail since Part 5, and the orange signal wire has been on pin 9 since Part 3. Nothing about the servo changes here.
What changes is what feeds the rail. That is the whole of this part: the same three wires, a different source behind them.
Battery pack red wire to the + rail. Battery pack black wire to the − rail.
Now check it before any power goes anywhere. Put your finger on each of the four wires now on the rails in turn, follow it to both ends, and say out loud where it starts and where it finishes.
Now, deliberately, leave out the last wire. Plug in the USB, then switch the battery pack on, and upload the sweep sketch.
Look at it for a moment. This is exactly what you would see if the servo were broken, and it is the state that stops most people. Nothing is broken.
Now switch the battery off and add the wire that matters: one jumper from the − rail to any GND pin on the Arduino.
This is the only wire joining the two halves. It carries no power. It carries an agreement.
Switch the battery back on. Nothing else has changed. One wire.
The rule, worth writing on the wall
Two power sources, one shared ground. Always. Whether it is a servo, a motor, a light strip or another board entirely. If two things have to understand each other's signals, they must first agree where zero is.
You will meet this rule again every time you add anything with its own power for the rest of your life in electronics.
gate.detach() stops the signal going out, and the servo goes limp and stops holding. It also stops drawing much current. If your build only needs to move now and then, attach, move, wait for it to arrive, then detach, and your batteries will last many times longer. It also stops the buzzing entirely while it is detached.Build the gate
60 minNow a whole device. A cardboard gate that sits where the knob puts it. Press the button and it opens all the way, then closes again three seconds later. A light shows whether it is open.
Nothing in it stops for long. The only wait anywhere is the 20 thousandths of a second that settles the button, which is the debounce from Band 3. You can turn the knob while it is closing, and the button is noticed the instant you press it.
The pin plan
| Part | Pin | Holes | Wiring |
|---|---|---|---|
| Servo signal | 9 | — | Orange wire straight to pin 9 |
| Servo power | — | — | Red to + rail, brown to − rail |
| Battery | — | — | Red to + rail, black to − rail |
| Ground link | GND | — | One wire, − rail to an Arduino GND pin |
| Knob | A0 | legs in f5, f6, f7 | Wire j5 to − rail; j6 to A0; j7 straight to the Arduino’s 5V pin, not to the + rail |
| Button | 2 | legs in e19, e21, f19, f21 | Wire j19 to pin 2; wire a21 to − rail |
| Light | 7 | long b3, short b4 | Resistor a3 to a1; wire b1 to pin 7; wire a4 to − rail |
The light's pin wire goes in b1, not a1. The resistor leg is already in a1, and a hole takes one leg only. The five holes in a column are joined underneath, so b1 reaches the resistor perfectly well.
The + rail now carries about six volts from four AA cells. The knob's middle leg goes to pin A0. Put the knob's end leg on the + rail and A0 sees up to six volts, and the chip is only built for five. It may work for a while and it may not, and you will not be told which.
So the knob's
j7 wire runs straight to the Arduino’s own 5V pin, on its own, and never to the + rail. Nothing on this breadboard except the servo and the battery touches the + rail.Build it in stages and test each one
Stage one: the light. Wire it as in the table, then test it with b0_01_blink_given.ino from Band 0. That sketch has the number 13 in it three times. Change all three to 7, then upload.
Stage two: the button. Seat it with its body over the middle channel and all four legs down, then test it with b3_02_serial_watch.ino from Band 3. Near the top it says int buttonPin = 2;, which is already right. Upload and open the serial monitor.
1 while you are not touching it, changing to 0 for exactly as long as you hold it down.Stage three: the knob. Test it with b6_02_servo_knob.ino, which you already have.
Now make the arm out of card. Cut a strip about the length of your hand. Tape one end firmly to a horn and push the horn onto the servo. Then tape or glue the servo body down to something heavy, so it cannot walk about when the arm swings.
Upload b6_04_servo_gate_worked.ino. Switch the battery on.
The knob only covers 0 to 120 degrees here, not the full 180. That is the line knobMax in the sketch, and it is on purpose: it keeps the closed positions well clear of the 180 the button opens to, so open always looks obviously different from closed. Change knobMax if your gate needs a different range.
deadband from 3 to 5, upload, and listen again. Different knobs are noisier than others.Look closer
35 mina. Read loop first
Open b6_04 and go straight to the bottom. The whole of loop is this:
void loop() {
checkButton();
moveGate();
showState();
}
Three lines, and you can say what the device does from reading them. That is not an accident and it is not decoration. It is the reason the sketch is easy to change.
Compare it with the alternative, where all of that is typed out in one long loop. Same behaviour, and you would have to read forty lines to find out what it is for.
b. Fill this in by hand
Assume deadband is 3 and lastAngle is currently 90. For each new wanted angle in order, say whether the servo moves and what lastAngle becomes.
| wanted | abs(wanted − lastAngle) | Moves? | lastAngle after |
|---|---|---|---|
| 91 | |||
| 92 | |||
| 93 | |||
| 94 | |||
| 95 |
Answer, after you have filled it in
91: gap 1, no move, stays 90. 92: gap 2, no move, stays 90. 93: gap 3, moves, becomes 93. 94: gap 1, no move, stays 93. 95: gap 2, no move, stays 93.
Notice what that means. Turning the knob slowly does not give you a slow smooth movement. It gives you a movement every third degree. The arm steps rather than glides.
That is the cost of the deadband, and it is exactly the accuracy you traded away for steadiness. There is no setting that gives you both.
c. Break it on purpose
In your copy of b6_04, change int deadband = 3; to int deadband = 0;. Predict what will happen, then upload.
Answer
Every reading now passes the test, because any gap is at least 0. You are back to b6_03 and the buzzing returns.
Worth seeing, because it proves the deadband is the thing doing the work, and not some other change you made at the same time.
Now try 1, then 3, then 10, listening to each one and watching how closely the arm follows your hand.
At 1 it is almost as noisy as 0. At 3 it is quiet and follows well. At 10 it is completely silent and lands noticeably away from where you pointed.
Then try 30. The arm becomes almost useless: it only moves when you swing the knob a long way. Both extremes are bad, which is why the middle is a choice you make rather than a rule you follow. Write down which value you would pick for a gate and which for a pointer on a dial.
d. The line that is easy to miss
Inside moveGate, in the branch where the gate is not open, there is a line that says openUntil = 0;. Take it out, upload, and see what happens.
Answer
The gate closes on time, but the light never goes out. showState asks whether openUntil is above zero, and it still is. It holds a moment in the past, but a moment in the past is not zero.
This is a small bug of a very common kind. Two pieces of code disagreed about what a value meant. moveGate treated a past time as closed; showState treated any non-zero as open. Neither is wrong on its own.
The lesson is not “remember that line”. It is that when one name means two things to two readers, one of them will be wrong. If you had used a separate bool isOpen, this bug could not have existed.
The other kinds of moving thing
30 minThis part is optional. Skip it if you have no motor and no driver board. Nothing later depends on it.
Three kinds, and what each is for
| Kind | What you tell it | Good for | Bad at |
|---|---|---|---|
| Servo | An angle, 0 to 180 | Arms, gates, lids, pointers, anything that goes to a place and holds | Going round and round. Most cannot. |
| DC motor | On or off, and how fast | Wheels, fans, pumps. Anything that just needs to spin. | Stopping in a chosen place. It has no idea where it is. |
| Stepper | A number of steps | Turning an exact amount, over and over, all the way round | Speed, and it draws current even standing still. |
Why a motor cannot hang off a pin
An Arduino pin can supply about twenty thousandths of an amp safely. A small DC motor wants ten to twenty times that at the moment it starts turning.
Connect one straight to a pin and you are not running a motor, you are damaging a chip. It may even appear to work for a while, which is worse, because you will not know when it stopped being fine.
A driver board solves it. Think of it as a switch that your pin operates and the battery powers. The small current gives the order. The big current does the work. The two never meet.
This is the same shape as the ground rule from Part 7. Signal and power are different jobs, and the mistakes come from treating them as one.
If you have an L293D and a DC motor
b6_05_motor_driver.ino has the full wiring in its header and runs the motor forwards, stops, backwards, stops. Read the header before you wire anything.
The idea inside is small. Two pins decide direction, by which of them is HIGH. A third pin, a ~ one, decides speed with analogWrite, exactly like brightness in Band 2.
If you have a 28BYJ-48 stepper and a ULN2003 board
The Stepper library comes with the Arduino software. Open File, then Examples, then Stepper, then stepper_oneRevolution. Set stepsPerRevolution to 2048 and wire the ULN2003's IN1 to IN4 to pins 8, 10, 9 and 11 in that order. The crossed order is not a mistake; it is the order the coils are in.
Your job here is to make the example run. Then write one sentence in your build log saying what a stepper gives you that a servo does not.
Change it
45 minWork on a copy of b6_04_servo_gate_worked.ino.
- Bronze
- Make the gate close slowly instead of snapping shut, over about a second, while the button still responds instantly during the whole close. You will need a name holding the angle it is travelling towards and a
millischeck that moves it one degree at a time. - Silver
- Replace the knob with the light sensor from Band 4, so the gate closes as the room darkens. Then find your two thresholds by measuring, exactly as you did in Band 4, and write them in your log. Use a different number for opening and closing, so a reading that wobbles on the boundary does not flap the gate. Read the box under this list before you wire it.
- Gold
- Make the servo
detach()whenever it has been still for two seconds, andattach()again the moment it needs to move. Then measure the difference: run the gate on batteries for ten minutes with and without it, and say what changed. This is hard for an interesting reason, and finding that reason is the task.
attach() the servo has no idea where it is. It jumps to whatever angle you write first. So you must write the angle it was already at, before you write the new one, or the arm will snap across and back every time it wakes up.Make: a mechanism that answers to the room
120 minWhat to build
Something made of cardboard that moves in response to something happening. A person watching must be able to tell what it is reacting to, without being told. Pick one, or bring your own:
- A physical gauge: a needle on a card dial that points at how bright, how near or how hot it is right now
- A sorting gate: a chute that swings one way or the other depending on a sensor
- A feeding hatch that opens for a fixed time on a button and closes itself
- A signal arm for a model level crossing, with the lights from Band 1
- A hand that waves when somebody comes near, using the knob for now and the distance sensor after Band 7
It is finished when all of these are true
- It moves because of something in the room, not because of a timer
- It holds still when it should be still, with no buzzing
- The servo has its own power and one shared ground wire
- The mechanism is fixed down and repeats the same movement every time
- Somebody watching can say what it is reacting to, without you telling them. If you are working alone, this counts as passed when you leave it running somewhere you will pass tomorrow, come back to it cold, watch it for thirty seconds, and can still say what it is reacting to.
The test that matters most in this band
Hand it to somebody, say nothing at all, and watch. Do not explain. Do not point.
Write down how long it takes them to work out what makes it move, and what they tried first. If they never work it out, that is the finding, and it is a finding about your build rather than about them.
Show your work
Post a video of the mechanism reacting to something real, a photo of the wiring showing the ground link clearly, and your build log. Then look at one other person's mechanism and tell them one thing a stranger would misunderstand about it.
Check yourself
20 minCode you have not seen. Answer from reading only. Do not upload it.
#include <Servo.h>
Servo arm;
int armPin = 9;
int knobPin = A0;
int lastAngle = 0;
int deadband = 4;
void setup() {
arm.attach(armPin);
Serial.begin(9600);
}
void loop() {
int reading = analogRead(knobPin);
int wanted = map(reading, 0, 1023, 0, 180);
if (wanted - lastAngle >= deadband) {
arm.write(wanted);
lastAngle = wanted;
}
delay(20);
}
- The knob is turned slowly all the way from one end to the other. Does the arm follow it the whole way?
- Now the knob is turned slowly back again, from 180 towards 0. What does the arm do? Explain your answer using the line with
deadbandin it. lastAnglestarts at 0 here rather than at −100. Give one situation where that makes a difference you could see.- The board is switched on with the knob already at the far end. The arm is physically sitting at 40 degrees. What happens in the first second?
- Somebody removes the
delay(20)to make it more responsive. What actually happens to the arm, and why? - The servo is powered from the Arduino’s 5V pin and has a long, heavy arm on it. The sketch is exactly as above. Name two different things you might see, and say which line of code is responsible for each.
Answers
1. Yes, roughly. Going up, wanted keeps getting bigger than lastAngle, so every four degrees the test is true and the arm steps forward.
2. The arm does not move at all. Coming back down, wanted is smaller than lastAngle, so wanted - lastAngle is negative, and a negative number is never greater than 4. The missing abs means this arm can only ever go one way. This is the question that matters most in this band. A deadband has to measure how far apart two numbers are, not which is bigger.
3. If the knob is near 0 when the board starts, wanted is about 0 and lastAngle is already 0, so the test fails and the arm is never written to at all. It will sit wherever it physically happens to be until the knob is turned up by four degrees. Starting at −100 guarantees one write straight away.
4. wanted is about 180 and lastAngle is 0, so the test passes on the very first round and the arm snaps from 40 to 180 in one movement, as fast as it can. That is normal for a servo: it does not know where it is until you first tell it where to be.
5. Almost nothing changes, and that is the surprise. The knob is read thousands of times a second instead of fifty, but the deadband still says no unless the wanted angle is a full four degrees past the last one. Four degrees is a long way: the wobble you saw in Part 6 was about one. So with a still knob nothing is written at any speed, and with a turning knob the arm still steps once every four degrees, just as before.
Reading faster does not make a wobbling reading truer, and it does not get past a deadband. What the delay was buying here was almost nothing, and the thing actually controlling the movement is the if.
6. Two answers, and they come from completely different places.
Jerky movement, or the ON light dipping, or the board resetting is the wiring. A loaded servo draws more than the Arduino's 5V pin can supply. No line of code causes it and no line of code can fix it. The answer is a battery and a shared ground.
The arm following the knob up but refusing to come back down is the code, and it is question 2 again. Nothing to do with the weight or the power at all.
Telling those two apart, quickly, is most of what Band 6 was for. When something moves badly, ask first whether it is short of power or short of instructions, because the two look similar and nothing you do to one helps the other.
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.
- Say why
gate.write(90)is a position and not a speed, and what makes a sweep slow - Name the three servo wires and say which two must never be swapped
- Explain, to somebody who has not done this band, why an arm shivers when nothing is touching the knob
- Say what a deadband costs you as well as what it buys you
- Draw the ground link between a battery pack and an Arduino, and say what happens without it
- Say why a DC motor needs a driver board and a servo does not (only if you did Part 10)
The one sentence from this band
A good reading does not have to be acted on. Deciding when to act is as much a part of the job as measuring.
That sentence is what separates Band 6 from Band 4. In Band 4 you learned to measure. Here you learned that measuring more often does not make a device better, and sometimes makes it worse.
Still stuck after 30 minutes?
Photograph the whole board from above in good light, so the ground link between the − rail and the Arduino is visible. Post that, your sketch, and one sentence on what you expected. In this band, say whether the servo is on USB power or battery power. That one detail answers most questions on its own.
When something goes wrong
| What you see | What it usually is | What to do |
|---|---|---|
| Servo twitches and does nothing else | No shared ground | One wire from the − rail to an Arduino GND pin. See Part 7. |
| Servo buzzes with nothing touching it | No deadband, or too small a one | See Part 6. Raise deadband to 5 and listen again. |
| Board resets when the arm starts moving | Servo on the Arduino's 5V pin, under load | Give it its own battery. See Part 7. |
| Servo gets hot | Red and brown swapped, or the horn is jammed | Switch off at once. Check the two wires, then check the arm swings freely. |
| Arm jumps across when the sketch starts | Normal | The servo does not know where it is until you first write to it. Write the resting angle in setup. |
| Arm will only go part of the way | The horn was pushed on at an angle | Take the horn off, run the sweep with no horn, then refit it so its travel covers what you need. |
Sketch will not compile, Servo not declared | Missing #include <Servo.h> | Add it as the very first line. |
| Servo moves but the knob does nothing | Middle leg not on A0 | The middle leg is the one that carries the answer. See Part 5. |
| Everything worked, then stopped after adding the battery | The + rail still runs to the Arduino's 5V pin | Take that wire out. The + rail is battery power now. |
What you know now
Before this band, everything your programs did stayed inside the board or came out as light and sound. Now they push things, and that turned out to be a different kind of problem.
The code part was small. attach, write, and one if holding a deadband. Almost everything that went wrong in this band was electrical, or was a decision about when to act rather than how to act.
That is the shape of the rest of your life in this. The programs stop being the hard part surprisingly early.
Before you move on, make sure you have
- A photo of your mechanism, and a video of it reacting to something
- A photo of the wiring where the ground link between the − rail and the Arduino is clearly visible
- Your completed deadband table from Part 9b
- Your notes from the loaded-card activity in Part 1
- The three deadband values you tried in Part 9c, and which you would choose for a gate and which for a dial
- Your build log for this band
- Five or six correct answers in Part 12, including question 2
Next is Band 7: Distance and Display. The board gets a new sense, measuring how far away things are with sound you cannot hear, and it gets a screen of its own so it no longer needs a computer to tell you anything.
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.
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: two power sources, one shared ground, and what happens without it.
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.