This button pad is made using a PCB and other components manufactured by Sparkfun. It is driven by an Arduino Mega. Each button is nice and squishy and satisfying to press, and it has an RGB LED inside!
I’ve been using it to control animations I’ve coded in Processing. The button pad sends a message whenever a button is pressed, saying which button it was. Processing receives these messages and changes variables in the sketch depending on what was pressed.
- LEDs are cool.
- Buttons are fun to push.
- Animated geometric patterns are nice.
I wanted to combine all three.
I took this project to a party, projected the visuals on the wall and let people play with the buttons. It could also be used by a VJ in a more performative way, much like a midi controller but more DIY.
There are four main parts to this project.
- Putting the button pad together –Starts in Step 1
This involves preparing the components and soldering them to the PCB
- The Arduino code –Starts in Step 10
For this, we need an understanding of matrix scanning, which I will talk through.
- The Processing code –Starts in Step 24
There are endless possibilities here, I’ll talk through one example I’ve made so far.
- Getting the Arduino to send messages to Processing –Step 16 for sending, Step 30-31 for receiving
This is nice and simple, it sends the message over a serial connection.
I try and write my tutorials in such a way that someone with absolutely no knowledge at all can at least follow along. You might find it helpful to first watch some introductory tutorials about Processing. I’d start with Daniel Shiffman’s YouTube channel.
All of the code (Arduino and Processing) is on my github here.
I learnt a bunch from this tutorial https://learn.sparkfun.com/tutorials/button-pad-ho… and much of the Arduino code is from there, although I have edited it to work slightly differently from any of the examples there.
Step 1: The components
Step 2: Prepare the diodes
Bend each diode and then push it through the PCB. The legs stick out on the button side, which we don’t want.
So take the diode out again and cut the legs short. (You might have some snips that will let you cut the legs flush with the board while it’s still in there which will make your life easier, but I only had normal scissors so I had to pull them out to cut them short enough.)
It is super important to bend the legs and push them through the PCB before you cut them short. If you cut them short first then you won’t be able to bend them into shape.
Make 16 of these little ant-like thingies.
Step 3: Solder the diodes on to the boards
Place each of the diodes back into the board.
Its important to check the orientation of the diode. It has a black line on one side which lines up with the line on the PCB. (See image)
Getting the diodes into place is kind of fiddly which is why I said if you have snips that will let you cut the legs flush without removing them, it will make your life easier. I didn’t have that so I used tweezers to place them back in, which helped a bit.
Solder each of the diodes into place.
Step 4: Prepare the LEDs
Push the LEDs through the board and then cut the legs off. Just like with the diodes; its important to push the legs through the board first, to get them spread to the correct angles, before cutting the legs.
There’s a bit of trial and error with cutting the legs to the right length. If you make them too long they will stick out, but too short and it’s difficult to get the LED back in.
Prepare 16 of these little amputated fellas.
Step 5: Solder the LEDs on to the board
Push all the LEDs back into the board.
The orientation is important again here. One side of the LEDs has a flat edge and this should line up with the flat edge of the circle on the PCB diagram. (See image)
See if the LEDs are pushed in far enough by putting the silicone pad over the board and checking that they don’t interfere with the buttons being pushed.
Solder the LEDs onto the board.
Note: It’s since been pointed out to me that since it doesn’t matter so much if a bit of the legs sticks out on the back, you could just push the LEDs through, solder them at the back, and then cut the legs off.
Step 6: Sort out the jumper cables
Lets talk about the board a bit.
The board is arranged into 4 columns and 4 rows of LEDs/Buttons.
Each of the columns require 2 connections, one for the LED ground and one for the button ground.
Each of the rows require 4 connections, because we need a separate connection for the red, green and blue channels, as well as a connection for the button input.
Here are the cable colours and pin numbers I selected for each of those connections.
|Row||What it’s for||Cable color||Pin number||PCB Label|
|Column||What it’s for||Cable color||Pin number||PCB Label|
|Col 1||LED ground||White||38||LED-GND-1|
|Col 2||LED ground||White||40||LED-GND-2|
|Col 3||LED ground||White||42||LED-GND-3|
|Col 4||LED ground||White||44||LED-GND4|
Step 7: Prepare the jumper cables
Each jumper cable needs one male end, and one end that is stripped of a few mm of wire.
I like to use some kind of container to capture stripped wire bits as otherwise they end up all over my flat and its possibly worse than glitter.
Step 8: Solder the jumper cables to the board and plug them in
Use the chart from a couple of steps back to get the cables soldered to the correct places on the PCB, and plugged in to the correct pins on the Arduino.
Step 9: Build done!
Take a small moment to celebratorily push some (as yet nonfunctional) buttons and then lets get onto some code!
Step 10: Schematic
This is a schematic of the PCB and the stuff we’ve soldered to it.
The grey boxes each represent one of the button / LED combos.
If this looks super complicated (it did to me the first time I saw it) then don’t worry, I’m going to break it down.
If you just want to look through the code yourself, its on my github here.
Step 11: Just the buttons
The LEDs and the buttons are actually separate from each other (aside from all being connected to the Arduino) so lets just look at the buttons first.
Each grey box contains one button and a diode (the ones we soldered on – I’ll explain the purpose of those in a bit).
I’m sure this is super obvious to some people, but I wasn’t sure of it when I first started figuring this out so I’ll say it! The rows (in green) and the columns (in blue) are not connected, they’re just laid across each other. Stuff is only connected where there is a small black dot. Closing one of the button switches however, does create a connection between the row and column.
Step 12: Set up button pins
For the buttons, we are going to use the columns as outputs and the rows as inputs.
We’ll be able to check if a button is pushed because if there’s a connection between a row and column then the voltage from the output will reach the input.
Step 13: Scanning
In the loop, a function called scan() goes through one column at a time and sets its voltage to be low.
If a button row reads low, then that means the button that connects that row and column has been pushed.
Step 14: Not all button pushes are created equal
If the button is pushed quickly and firmly then the voltage transfer from the column to the row will be nice and clean.
However, if it’s pushed a bit slowly or wonkily, then the voltage might jitter a bit until there is a good connection between the button pad and the contacts on the PCB.
This means that a button push that a human thinks is just one, might be interpreted by the arduino as several separate pushes.
Step 15: Debouncing
To account for this potential glitch, we use a technique called debouncing.
Every button has a counter (they are held in an array).
When the scan finds that a button is being pushed, we increment that counter. Once the counter reaches a certain threshold, we can consider the button to be really truly pushed. Around 3 or 4 scans is enough for this hardware.
Have a look at the attached gif to see this happening.
Step 16: Really truly pushed – LED on and message sent
Once the button is really truly pushed we want to turn on the LED and send a message to the Processing sketch with this button’s number.
Each LED has a boolean value (stored in an array) to say whether it should be on or off, so this gets set to true.
(We actually turn the LED on in a bit of code we’ll look at in a few steps. You might be wondering why we don’t just turn the LED on here. Well, it’s because I want the LED to stay on the whole time the button is being pushed, not just flash on and off at the moment it first becomes pushed.)
To write the message to the serial port, we need to calculate the button number from the row and column. There is a simple formula to do that, which you can see in the image.
Step 17: Letting go
If a row’s voltage is high, then there is no connection between the row and the current column, so that button is not being pushed.
We check to see what its counter is at. If it’s at 0 then nothing happens at all – that button isn’t being pushed and it wasn’t pushed recently.
If the counter is above 0, then we start to decrease it. In the same way that we used a debounce counter to check if a button is really truly pushed, we now need to make sure it’s really truly let go of. The scan() function will loop through a few times, reducing the counter until it’s at 0.
In the loop that the counter rolls from 1 to 0, then we turn the corresponding LED’s boolean to false, so it will no longer get lit up.
Step 18: The end of the loop
The scan() loop also contains some code for lighting up the LEDs but we’re just concentrating on the buttons at the moment, so lets skip past it for now.
At the end of the scan() loop, the voltage for the current column is set to high again, and the current column number is incremented.
Step 19: Wait, so what are the diodes for?
If we didn’t have the diodes, then when two buttons in the same row are pressed, the low voltage from the current column could become connected to the high voltage from another column and cause a conflict.
The diodes control the direction of the current, which stops the voltages from separate columns from meeting and conflicting.