Band 3 · Combination Lock
Swap The keypad lock
A four-digit code on a real keypad. Sixteen buttons on eight wires, and the trick that makes that possible.
Sketches for this project
Every file opens with a plain-English header saying what it does and how to wire it, hole by hole.
Sixteen buttons on eight wires
The four-button lock in Band 3 uses four buttons on four pins. One each. That does not scale, and a keypad is where it stops working.
Sixteen keys, one pin each, would be sixteen pins. An UNO has eighteen usable. You would have a keypad and nothing else.
So a keypad does something cleverer, and it is the same trick that is hiding inside every multi-digit display in the drawer, including the one in Band 7. It is worth understanding rather than accepting.
How it works, in one paragraph
The keys are in a grid: four rows of four. Every key sits where one row wire crosses one column wire, and pressing it joins that row to that column.
So the board switches on one row at a time and looks at all four columns. If column 3 answers while row 2 is switched on, the key at row 2 column 3 is down. It does that about a hundred times a second, and to you it looks instant.
Four rows plus four columns is eight wires for sixteen keys. Add a row and a column and you get twenty-five keys on ten wires. That is what makes it worth the cleverness.
You already know this shape. It is Band 3's loop over four buttons, done in two directions at once.
Wire it
40 mina, so every jumper goes into row b.a, the same pair Band 3 uses, and the one your parts sit next to. Put every rail wire on that pair and it works; split them across both and nothing lights, with nothing visibly wrong.This is not tidiness. The keypad needs eight pins in a row, and Band 3's lock had its green light on pin 8, its red on pin 9 and its buzzer on pin 10, which is exactly where three of the keypad's eight wires are going. Leave them and you have two wires in one pin three times over, which the course forbids for good reason: the two fight each other and neither works. The table below rebuilds the lights and the buzzer in new holes on new pins.
The keypad
Eight pins along one edge. Hold it with the buttons facing you and the right way up, so 1 2 3 A is the top row. The pins are then, reading left to right:
If you have female-to-male wires (a socket at one end, a pin at the other): push the socket end onto the keypad pin and the pin end into the Arduino. Eight wires, done.
If you do not: push the keypad's eight pins into the breadboard, into row
a, one pin per column: a20, a21, a22, a23, a24, a25, a26, a27, with the leftmost pin in a20. Then run an ordinary jumper from the row b hole in each of those columns up to the Arduino pin the table names: b20, b21, b22, b23, b24, b25, b26, b27. Eight columns, eight wires, in that order. That is eight wires as well, and it holds the keypad steady while you press it, which is worth something.| Position | What it is | Arduino pin |
|---|---|---|
| 1st, leftmost | Row 1 — the 1 2 3 A row | 9 |
| 2nd | Row 2 — the 4 5 6 B row | 8 |
| 3rd | Row 3 — the 7 8 9 C row | 7 |
| 4th | Row 4 — the * 0 # D row | 6 |
| 5th | Column 1 — the 1 4 7 * column | 5 |
| 6th | Column 2 — the 2 5 8 0 column | 4 |
| 7th | Column 3 — the 3 6 9 # column | 3 |
| 8th, rightmost | Column 4 — the A B C D column | 2 |
The rest
| Part | Holes | Wiring |
|---|---|---|
| Green light | long b3, short b4 | Resistor a3 to a1; wire b1 to pin 10; wire a4 to − rail |
| Red light | long b7, short b8 | Resistor a7 to a5; wire b5 to pin 11; wire a8 to − rail |
| Buzzer | long b40, short b42 | Wire a40 to pin 12; wire a42 to − rail. No resistor. |
If the buzzer's legs are set too far apart to reach b40 and b42, use b40 and b43 instead and move the − rail wire to a43. Buzzers are made to two different leg spacings and both are common. Do not force the legs; they snap. | ||
| Ground | — | One wire from the − rail to a GND pin |
The pin wires go in b1 and b5, not a1 and a5, because the resistor legs are already in those holes and a hole takes one leg only. Same column, same connection.
tone, which an active buzzer cannot follow. It will still beep, at its own single note, and the lock works perfectly. If you would rather it were exact, replace each tone(buzzerPin, ...) with digitalWrite(buzzerPin, HIGH) and each noTone(buzzerPin) with digitalWrite(buzzerPin, LOW). Run id_01_which_buzzer.ino if you are not sure which you have.Install one library, then test in two stages
Install the Keypad library. Tools, then Manage Libraries, search for Keypad, and install the one by Mark Stanley and Alexander Brevig. Once, on one machine.
No such file or directory. Nothing is broken. On any machine that does have a connection, search for the library, download it as a .zip, and carry it here on a phone or a USB stick. Then use Sketch, then Include Library, then Add .ZIP Library, and point it at the file. If your kit came with a folder of libraries on a stick or a disc, it is already in there. Do this before you wire anything, because without the library nothing you build can be tested.Stage one: prove every key works, before the lock is anywhere near it. Upload b3_07_keypad_test.ino, which does nothing at all but print, and open the serial monitor at 9600. Press every one of the sixteen keys in turn, reading along the rows.
key 1, key 2, key 3, key A, and so on, matching what is printed on the key you pressed. All sixteen.Stage two: use the lock. The secret is 1 9 4 2. Type it.
matchesSecret. It compares with !=, meaning “is different from”, and it returns false the moment it finds one digit that does not match. If you have edited that function, check you have not turned != into = by accident: = is an instruction to change the value, not a question about it, and the compiler will accept it without a word. That is exactly the trap Band 3 Part 7 set for you.Watch the scanning happen
25 minThe library hides the row-and-column trick. Here is how to see it.
Take one wire out
- Upload
b3_07_keypad_test.inoagain first. You are about to press twelve keys in a row, and on the lock that is three wrong codes, so the third one would lock you out for ten seconds in the middle of the experiment. - Unplug the USB. Take the row 1 wire out of pin 9. Leave everything else exactly as it is.
- Plug back in and try every key.
1, 2, 3 and A are dead. The other twelve keys work perfectly. One wire, one whole row.- Put row 1 back. Now take the column 1 wire out of pin 5.
1, 4, 7 and * are dead. A different four, in a line the other way.Only 1 was dead both times, because 1 is where row 1 crosses column 1. That is the grid, and you have just proved it exists without opening anything.
The guard you have seen before
if (pressCount < 4) {
entered[pressCount] = key;
pressCount = pressCount + 1;
}
This is the same guard as Band 3 Part 11, for the same reason. entered holds four things, so its positions are 0, 1, 2 and 3. Without the check, a fifth key would be written to entered[4], which is outside the list, and the lock would jam permanently.
Two questions for your log
- The
*key clears what you have typed. Find the two lines that do it, and say whystartAgainsets every position back to 0 rather than only resettingpressCount. - The four-button lock had to do edge detection: notice the moment a button goes down, not that it is down. This sketch has no edge detection anywhere. Why not?
Check your answers
1. Strictly, only pressCount has to change, because nothing reads past it. Clearing the rest is a habit worth having: it means that if you ever add code that does look at the whole list, it cannot find yesterday's leftovers there. The same reason Band 1 writes all three lights in every state.
2. Because pad.getKey() already does it. It hands back a key once, at the moment it goes down, and then NO_KEY until something changes. The library is doing the edge detection and the debouncing for you. Worth knowing, because when you meet an input without a library you will have to do both yourself, and now you know what “both” means.
Make it yours
35 min- Bronze
- Change the secret, and change its length from four digits to six. Count how many places you had to edit. If it was more than two, look for the number 4 written somewhere it should have been a name.
- Silver
- Let the user set their own code: press
#twice in a row, then type four keys, and that becomes the new secret until the power goes off. Then say in one sentence what happens to it when the power goes off, and why. (If you would rather it were a two-second hold, you cannot do it withgetKey, because that only ever tells you the moment a key goes down. The library hassetHoldTimeandgetStatefor exactly this, and its ownCustomKeypadexample, installed on your machine alongside it, shows them working. That is a real piece of research and it is worth the hour.) - Gold
- Make the lockout get longer each time: ten seconds, then thirty, then two minutes. Do it without ever using
delay, so that keys pressed during a lockout can still be seen and ignored deliberately rather than missed. This is Band 5 arriving early, and it is the honest way to write a lockout.
secret, the size of entered, the loop that compares them, the loop that clears them, the guard that stops a fifth key being stored, and the test that decides the entry is finished. Find all six before you change any of them. A single const int CODE_LENGTH = 4; at the top fixes all six at once, and that is Band 1's variables lesson paying off two bands later.You still owe Band 3 the same evidence
This Swap replaces the four-button lock. To claim Band 3 you still need:
- A video of a correct entry, a wrong entry, and the lockout
- Your build log, including which wires the row-and-column ordering caught you on
- Your answers to the two questions above, and your list of hesitations: the places where somebody using it stopped, guessed, or pressed the wrong thing. Watch another person if there is one. If you are on your own, film yourself using it while thinking aloud, then watch it back tomorrow, when you have forgotten what you meant. Both work. Building it and never watching anybody use it is the only option that does not.
- Your completed edge-detection table from Part 12a, and your number from Bronze
- The sentence “not pressed is 1, pressed is 0” in your glossary
- Five or six correct answers in Part 15, the Check yourself questions, including question 6
The Check yourself questions are about INPUT_PULLUP, edge detection, debounce and the one-equals-sign trap, and this build hides the first three of those behind a library. Answer them anyway. If you can, you have understood the band; if you cannot, go back and wire two loose buttons for twenty minutes, because the library will not always be there.
Ship it
One video under sixty seconds, and one post of five lines. You built something different from the person next to you, so your video is the one nobody else in the room can post. Say in the post which build you chose and why — that choice is itself worth a line.
The four shots: three seconds of the thing still, fifteen of you doing something to it, fifteen of it responding all the way to the end, and ten of your measurement or the thing that went wrong first.
Show your work has the template and the three checks to
make before anything goes public. Tag it #BozomaBuilds.