What
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.

Why

  • 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.

How

There are four main parts to this project.

  1. Putting the button pad together –Starts in Step 1
    This involves preparing the components and soldering them to the PCB
  2. The Arduino code –Starts in Step 10
    For this, we need an understanding of matrix scanning, which I will talk through.
  3. The Processing code –Starts in Step 24
    There are endless possibilities here, I’ll talk through one example I’ve made so far.
  4. 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.

Level

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.

Code

All of the code (Arduino and Processing) is on my github here.

Credits

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

    (There’s also a bunch of stuff you can get from Sparkfun to house the whole thing a bit more neatly, but I have not done this)

    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
    Row 1 Red Red 22 RED1
    Green Green 23 GREEN1
    Blue Blue 30 BLUE1
    Button input Yellow 31 SWITCH1
    Row 2 Red Red 24 RED2
    Green Green 25 GREEN2
    Blue Blue 32 BLUE2
    Button input Yellow 33 SWITCH2
    Row 3 Red Red 26 RED3
    Green Green 27 GREEN3
    Blue Blue 34 BLUE3
    Button input Yellow 35 SWITCH3
    Row 4 Red Red 28 RED4
    Green Green 29 GREEN4
    Blue Blue 36 BLUE4
    Button input Yellow 37 SWITCH4
    Column What it’s for Cable color Pin number PCB Label
    Col 1 LED ground White 38 LED-GND-1
    Button ground Black 39 SWT-GND-1
    Col 2 LED ground White 40 LED-GND-2
    Button ground Black 41 SWT-GND2
    Col 3 LED ground White 42 LED-GND-3
    Button ground Black 43 SWT-GND3
    Col 4 LED ground White 44 LED-GND4
    Button ground Black 45 SWT-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.

    First, we assign the pin numbers for the rows and columns. 

    Then, in the setup(), we output a high voltage to all of the columns.

    We set the rows to be pull up inputs which means that by default they also read high.

    Step 13: Scanning

    In the loop, a function called scan() goes through one column at a time and sets its voltage to be low.

    Then it looks at each button connection row, to see if any of them are reading 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.