My sons wanted color LED strips to light up their desks, and I didn't want to use a canned RGB strip controller, because I knew they'd get bored with the fixed patterns these controllers have. I also thought it would be a great opportunity to create a teaching tool for them that they could use to sharpen the programming and electronics skills I've been teaching them. This is the result.
I'm going to show you how to build this simple, programmable RGB LED strip controller using an Arduino Uno (or Nano), an Adafruit Trellis, and a handful of other parts.
The Adafruit Trellis is one of my favorite new toys from Lady Ada and crew. First of all, it's a mere $9.95 for the board, and another $4.95 for the silicone elastomer button pad (prices as of this writing). That's a great deal for a 16-button 4x4 matrix with LED capability. It doesn't come with any LEDs mounted, you need to supply them, but that gives you the flexibility to choose the colors you want (and keeps cost and complexity down vs building in addressable LEDs). To build this project like mine, you'll need a handful of 3mm LEDs. I used 2 red, 2 green, 2 blue, 4 yellow, and 6 white.
The Trellis uses I2C to communicate, so it requires only two I/O pins (data and clock) to control 16 buttons and 16 LEDs.
You can do the hardware part of this project on a small proto board, which is how I did my prototype. I quickly realized that I needed something neater and more contained on their desks (a bare Arduino and proto board banging around would be too fragile), so I made my own shield to drive the LED strips. Instructions and files for building the shield are included in the last step.
The driver uses three IRLB8721 MOSFETs and three resistors. And of course, you'll need an LED strip to drive; pretty much any plain 12V RGB LED strip will do. These are simple LEDs, like SMD 5050s, not fancy individually-addressable ones (no NeoPixels, etc.)--that's another project! You also need a 12V power supply large enough to drive the number of LEDs you intend to use.
So, to recap, here are the basic hardware needs for this project:
- One Arduino Uno or Nano (these instructions are for Uno with female headers installed, but Nano on a breadboard works fine) (Adafruit, Amazon, Mouser);
- One Adafruit Trellis board and silicone button pad (Adafruit);
- Three IRLB8721 N-channel MOSFETs (Adafruit, Amazon, Mouser);
- Three 1K resistors (Amazon, Mouser);
- Three 220 ohm resistors (Amazon, Mouser)
- One small proto board (my first was 1/4 size--choose any size you can work with comfortably) (Adafruit, Amazon);
- A 12V RGB LED strip (SMD 5050) (Adafruit, Amazon);
- 12V power supply -- choose a wattage appropriate for the number of LEDs you plan to drive.
Requisite disclaimer: the links above are provided for your convenience and are not an endorsement of any product or vendor; nor do I profit from any purchases made at these links. If you've got vendors you like better, by all means support them!
Let's get started...
Step 1: Wire Up the Driver Board
Here's the LED driver circuit. It's very simple. It uses an IRBLxxx N-channel MOSFET for each channel on the LED strip. The LED strip is common anode, meaning +12V is sent to the LED strip, and the red, green, and blue LED channels are controlled by providing ground on the respective connection to the strip. So, we'll be connecting the drain of the MOSFETs to the LED color channels, and source to ground. The gates will be connected to Arduino digital outputs, and the resistors provide a pull-down that ensures each MOSFET switches fully on or off as needed.
The Arduino offers pulse-width modulation on some of its digital outputs, so we'll use those outputs (specifically D9, D10, D11) so that the intensity of each color channel can be controlled.
If you're confused about what to connect where on the IRLB8721 MOSFETs, hold one in your hand with the front facing you as shown in the photo above. The pin on the left (pin 1) is the gate, and will connect to an Arduino digital output pin and the resistor (the other end of the resistor should connect to ground). The pin in the center (pin 2) is the drain, and connects to LED strip color channel. The pin on the right (pin 3) is the source, and is connected to ground. Make sure you keep track of which transistor connects to which LED color channel.
I won't go into the details of how to solder up proto boards. Honestly, I hate it, and I'm not good at it. But for better or worse, it works, and it's a quick and dirty way to get a solid prototype or one-off done. My first board is shown here.
You could also breadboard this up. It would certainly be faster than soldering up everything on a proto board, but less permanent.
Once you've got your driver wired up, connect the MOSFET gate inputs to the Arduino digital output pins: D9 for the green channel, D10 for the red channel, and D11 for the blue channel. Connect the LED strip to your proto board as well.
Also, make sure your driver board has a separate connection from its ground to one of the Arduino's ground pins.
Finally, for LED power, connect the negative (ground) lead of the 12V supply to a ground on your driver board. Then connect the positive lead of the 12V supply to the anode lead of your LED strip (this is a black wire on my cables shown in the picture).
Ultimately, I ended up designing a PC board shield that mounts on the Uno, and also has a mounting support for the Trellis. This provided a much more finished final product. If you want to do that, you might skip using the proto board as described here and just get the shield board made. That all is described in the last step.
Step 2: Put LEDs on the Trellis
The Trellis board has empty pads for 3mm LEDs that we'll need to fill. Note carefully the symbols at the pads--there's a very subtle "+" next to the pad to designate the anode side. If you're holding the board so the text is right-side up, there's also a notation at the top and bottom of the board advising that the LED anodes are on the left.
Solder your 3mm LEDs to the board. Looking at the front of the board, text right-side up, the upper-left switch/LED position is #1, the upper right is #4, the bottom left is #13, and the bottom right is #16. Here are the colors I used in each position (and there's a reason why, so I advise you follow my pattern at least for the top two rows):
1 - red
2 - green
3 - blue
4 - white
5 - red
6 - green
7 - blue
8 - white
9 - white
10 - white
11 - yellow
12 - yellow
13 - white
14 - white
15 - yellow
16 - yellow
Step 3: Connect the Trellis to the Arduino
The Trellis has five wiring pads, but only four are used in this project. The Trellis needs SDA and SCL to communicate with the Arduino (using I2C), and 5V and GND for power. The last pad, INT, is not used. The Trellis pads appear on all four edges of the board. You can use any set of pads you wish.
Solder a solid interconnect wire to the 5V, GND, SDA and SCL pads. Then, connect the 5V wire to the 5V pin on the Arduino, the GND to the ground pin, the SDA wire to A4, and the SCL wire to A5.
Next, we're going to power up the Arduino and upload the sketch to it. Now is a good time to put the silicone button pad on the Trellis board. It just sits on the board (note the "nubs" on the bottom of the pad that fit into holes on the board), so you may want to use a couple of pieces of tape to hold the edges of the pad to the board for now.
Step 4: Download the Project Sketch and Upload It to the Arduino
You can download the sketch from my Github repo for this project.
Once you've got it, open it in the Arduino IDE, connect the Arduino using a USB cable, and upload the sketch to the Arduino.
If the sketch is uploaded and the Trellis is properly connected, any of the buttons on the Trellis should flash quickly three times when pressed. This is an indication that you've pressed an invalid button, because the system comes up in its "off" state, so the only valid keypress is the one required to turn it on.
To turn the system on, press and hold the bottom left button (#13) for at least one second. When you release the button, all of the LEDs should light up briefly, and then the bottom two rows will go out, except for #13 (bottom left). The system is now in the powered-up and idle state.
You can try using the top two rows to brighten and dim the LED channels as a first test. If that's working, you're good to go on to the next step. If not, check:
- LED power supply is connected and on;
- Driver board MOSFETs are correctly wired. If you use the same IRLB8721's I used, check:
- Driver board signal inputs (MOSFET gates, IRLB8721 pin 1) are connected to Arduino D9=green, D10=red, D11=blue (see note below);
- LED strip is connected to driver board and LED color channels are connected to MOSFET drains (IRLB8721 pin 2);
- MOSFET source pins (IRLB8721 pin 3) are connected to ground on the driver board;
- Ground connection between driver board and Arduino ground pin.
In the next step, we'll play with some of the functions of the button pad user interface.
NOTE: If your controller is working but the intensity buttons don't control the right colors, don't worry and don't rewire! Just go into the Sketch in the Arduino IDE and modify the RED, GREEN, and BLUE pin definitions near the top of the file.
Step 5: Basic Control Functions
Now that the system is powered up, we can play with some of the buttons and make it do stuff.
As I said in the previous step, when powered up, the system comes up in its "idle" state. In this state, you can use the buttons on the top two rows to increase and decrease the color intensity of each of the red, green, and blue LED channels. If you use the white increase/decrease buttons, the system increments or decrements the intensity of all three channels equally and at equal levels.
The bottom two rows are used to play back preset patterns. These patterns are stored in the Arduino's EEPROM. When the sketch runs for the first time, it sees that the EEPROM doesn't have any patterns stored, and stores a set of default patterns. Thereafter, you can change these patterns, and your changes are stored in the Arduino's EEPROM, replacing the preset pattern. This ensures that your patterns survive power disconnects. The editing function is described in the next step.
For now, briefly press any of the preset buttons (the eight buttons in the bottom two rows) to run the pattern stored for that button. The button flashes while the pattern runs. To stop the pattern, press the pattern button briefly again. While a pattern is running, the white up/down buttons in the top rows can be used to change the pattern rate.
If you leave the project alone for a few seconds without touching any buttons, you'll notice the LEDs dim. This is both for power saving and to avoid having the Trellis over-illuminate any "mood" the LEDs are trying to create. Touching a button on the Trellis will wake it back up.
To turn the system off, press and hold the lower-left (#13) button for one or more seconds and release. The Trellis and LED strip will go dark.
Step 6: Editing Patterns on the Keypad
As I said in the previous step, the sketch stores eight default patterns in EEPROM the first time it runs. You can change 7 of these patterns to something else if you wish using the pattern editing mode on the button pad.
To enter pattern editing mode, first decide which button you want to edit the pattern for. You can choose any button other than the bottom left button. Enter pattern editing mode by long-pressing (hold down more than one second) on your chosen pattern button. When released, the button will illuminate solid, and the upper two rows will start flashing. This indicates that you are in editing mode.
Editing mode begins at the first step of the pattern and continues until you exit editing or finish editing the 16th step (16 steps max per pattern). At each step, use the channel intensity buttons in the top two rows to select the color you want for that step. Then short-press the pattern preset button to save that color and move on to the next step. On your last step, instead of short-pressing, just long-press to exit editing.
After you exit pattern editing, the pattern automatically plays.
That's it! You now have an RGB LED controller that will sequence patterns that you can program through the keypad. You can stop here, or if you want to build a more formal version of this project, keep going through the rest of the steps.
Step 7: Better Hardware: RGB LED Driver Shield and Enclosure
Once I had a working prototype, I knew that I couldn't leave a bare Arduino and proto board on my kids' desks as a permanent solution. I needed an enclosure for the project. I also decided that I would make a better driver board, and I thought it was the perfect opportunity to make my own shield.
I cleaned up my paper schematic by entering it into ExpressSCH, a free tool offered by ExpressPCB, a board fabricator that offers inexpensive short runs of small PC boards. I've been using ExpressPCB for over a decade on projects, but use whatever tools and fabricator you prefer, by all means.
I added a couple of small features to the basic schematic so that it would function well as a shield for this project. I added wiring pads to connect the Trellis, a power jack, a pilot lamp, and a connector for the LED strip. I also added a spot for a capacitor across the power supply. The final circuit is shown here.
I decided that power for the project should come from the shield. The 12V supplied to the shield powers both the LED strip and the Arduino. Power to the Arduino is provided by connecting the supply input to the Arduino's VIN pin, which is bi-directional (you can supply power to the Arduino on this pin, or if you connect power to the Arduino elsewhere, it will give you the supplied power on this pin). Protection diode D1 prevents any power connected directly to the Arduino (e.g. USB) from trying to power the LEDs.
Why not use the Arduino's power jack and just connect 12V there? While I could have supplied 12V to the Arduino's power jack and used the VIN pin to grab that power for the shield, I was concerned that the Arduino's D1 diode and traces weren't going to be up to the high currents possible in driving the LED strips. So, I decided that my shield would take over power input and supply power to the Arduino instead.I also needed 5V for the Trellis, but the Arduino's on-board power regulation supplies 5V on several pins, so I used one of them for the Trellis. That saved me putting a regulator circuit on the shield.
I then laid out the PCB. I used some resources I found to get the exact measurements for placement of the pins to meet the headers on the Arduino Uno. A little diligence and it matched up on the first try. There's not much to the shield circuit itself, so I had plenty of room. I laid out wide traces for the LED loads, so there'd be plenty of current-carrying capacity for my needs. I set the MOSFETs out where they could be mounted flat, with or without heat sinks. So far, I haven't needed heat sinks for the number of LEDs I've been using, but the space is there if needed.
I also added holes that matched mounting holes on the Trellis, so that I could use stand-offs to mount the Trellis to my shield. With the shield plugged in to the Arduino, and the Trellis suspended on stand-offs over the shield, everything should be nice and solid.
I then printed the board layout and glued it to a piece of foam core, and insert my parts to make sure everything fit. All good, so I sent the order off.
I then started working on an enclosure. Using Fusion 360, I designed a simple enclosure to contain the three boards (Arduino Uno, shield, and Trellis). Holes in the enclosure allow connection to the Arduino's USB port, and of course, access to the LED strip connect and shield power jack. The Arduino power jack is covered by the enclosure, to ensure that it isn't used. After a couple of prototypes for test fitting, I finally had a design I was satisfied with. I've posted the STL files for the enclosure to Thingiverse.
In future, I'll do a version of the board that a Nano can be plugged in to directly, This would make the project even more compact. Until then, you could also use a Nano to Uno shield adapter like this.
If you're going to do the shield, here's what you'll need in addition to the parts mentioned in step 1:
- RGB LED Driver Shield PC board (from ExpressPCB or others; you can download the files from my Github repo for the project);
- 1N4002 diode;
- 100uF 25V radial electrolytic capacitor (use 220uF or 470uF if large LED load);
- Power jack, PJ202-AH (5A rated model).
The following parts are optional:
- 3mm LED -- any color, for pilot lamp (may be omitted)
- 1500 ohm resistor -- only needed if using LED pilot lamp