Want to build a work of art? With an Arduino and a few bits of hardware, you can!
BUILD TIME: < 1 Hour
DIFFICULTY RATING: EASY
The world of addressable LEDs opened up a brave new world in computer-controlled lighting. No longer was it an arduous task to connect multiple LEDs. Gone were the days of daisy-chains and loads of hardware required to drive a few LEDs. Now with simple power and one data pin, you can control a huge array of addressable LEDs.
Of course, LEDs are fun, but sometimes aesthetics matter! It’s one thing to prototype and test, but it’s another to create an object we can put on display.
THE BROAD OVERVIEW
Using a small section of addressable RGB LED strip, and a small Arduino, we can quickly gain some fantastic control of our colours. The scope for patterns and styles are virtually endless!
There are two parts to this circuit plus the 3D printed case and the acrylic panels.
HOW IT WORKS
The Arduino provides a massive amount of power to drive the LED strip in a variety of creative ways; really, it’s loads more than we need. But it’s easy to use, so it’s a great choice. We have boiled it down to three human controls, to keep the interface simple but highly functional:
A MOMENTARY PUSHBUTTON SWITCH: To change between light modes, the pushbutton simply moves the programme to the next available light mode.
POTENTIOMETER ONE: A global dimmer, providing overall brightness control, regardless of the current light mode.
POTENTIOMETER TWO: Modifies the speed of the colour effects that are running. However it provides a secondary function. When the lamp is in single-colour mode, it provides control over the colour selection itself.
Our software uses the NeoPixel library to do the heavy lifting of controlling the colour and intensity of two strips, each with five LEDs. Sure, they look great on their own, but we’ve designed a number of easily selectable display patterns. The LED modules are mounted such that their light is reflected into and through pieces of acrylic, so as to produce a colourful display.
THE LED STRIPS
The LED strips are in fact flexible circuit boards with the LED packages attached. Each LED package consists of a package of three LEDs (one red, one green, and one blue), and a controlling IC. Each LED in the package is capable of 256 brightness levels, which means that between the three LEDs they support 24-bit colour. That’s 16.8 million colours!
The strips have a cut-point between each LED module. Each module has power and ground pins at each end plus a “Din” (data input) pin at one end, and a “DO” (data out) pin at the other. Data is fed into the strip on the Din pin and will be passed to the next LED module via the DO as necessary. Part of the software setup is to nominate how many LED modules are being used. This helps control the data flow from module to module.
THE ARDUINO
Our Arduino has a fairly easy task for this project. We’re implementing the NeoPixel library for control of our RGB LED strips. The library means we have minimal code to implement, and can focus on the actual control. It would be entirely feasible to use an ATtiny85 or similar for this project, due to the low volume of IO, but an Arduino is convenient and easy to use too.
THE 3D PRINT
One of the biggest physical tasks here is the overall look and design of the lamp. Often we’re designing our enclosure purely for function, but this is a lamp after all so we want it to look interesting and be aesthetically pleasing. So we took the challenge. The end result is a combination of acrylic and 3D printing, which is easy to build, and highly functional too!
There are three parts to the 3D print: the blank support, the support with controls, and the base which ties the two together. It’s been designed to compensate for some of the limitations in 3D printing, as well as make access easy for construction (in particular the LED strip).
THE BUILD
Parts Required: | Jaycar | Altronics |
---|---|---|
1 x Arduino Nano | XC4414 | Z6372 |
1 x 100k Resistor* | RR0620 | R7606 |
1 x 10k Resistor* | RR0596 | R7249 |
1 x 100nF Capacitor | RG5126 | R2736B |
1 x 1000µF Capacitor | RE6328 | R5182 |
2 x 50k 16mm Linear Pots | RP3516 | R2227 |
1 x SPST Momentary Action Switch | SP0710 | S1060A |
2 x 3D Printed Stands | ||
1 x 3D Printed Base | ||
5 x 100 x 50 x 6mm Laser Cut Acrylic Panels† |
* Quantity required shown, may be sold it packs.
† If you can’t get laser cut acrylic panels, you can cut these by hand and then polish using wet and dry sandpaper. It will achieve a very similar effect, albeit slightly rounded edges.
You'll also require jumper wires and standard prototyping hardware.
BUILDING THE CIRCUIT
Construction is fairly straight forward. Cut the LED strips to length (5 x LEDs in length) and solder some wire to each of the three pins: +5V, Din and GND. Since we’re mounting everything into the case, it’s best to mount the potentiometers into the 3D printed case. If you’re planning on your own mounting, you can skip this step.
Since things are going to be fairly stationary in our lamp, it’s entirely possible to build all of this onto breadboard. However the circuit is simple and easily transferred to Veroboard, which will add some robustness to the overall result.
THE CODE
The LED strip is easy to take control of. While we are using generic RGB LED strip, the NeoPixel library can be used for control. This takes all the heavy lifting out of our code. We’ll assign pin 4 for this purpose.
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel strip = Adafruit_NeoPixel(5, PIN, NEO_GRB + NEO_KHZ800);
Below is our setup function. It sets pin 3 to read from our pushbutton switch, which is used to change operating mode anytime. Serial monitor is used, however we can omit this for production code. Then we initialise our random number generator, and turn all the LEDs off.
// sets digital pin 3 as input to
// read mode button
pinMode(ModePin, INPUT);
attachInterrupt(digitalPinToInterrupt(ModePin), SetMode, FALLING);
Serial.begin(115200);
while (!Serial) { ; }
Serial.println("Running...");
// init random number generator
randomSeed(analogRead(0));
strip.begin();
// Initialize all pixels to ‘off’
strip.show();
Looking through the code, you’ll notice we have created seven different lighting modes. The momentary pushbutton cycles through each of the modes. Following is a simple switch function to roll through to the next one each time the button is pushed.
switch (Mode)
{
case 1:
Serial.println("Mode 1 - ZoneOut()");
ZoneOut();
break;
/*** lines skipped for clarity ***/
case 7:
Serial.println("Mode 7 - colour wipe
blue");
GetBness();
colorWipe(strip.Color(0, 0, 255 / bness),
100 * rate);
GetBness();
colorWipe(strip.Color(0, 0, 0),
100 * rate);
break;
}
This is GetBness(). It uses analogRead() to determine the value of the brightness pot and converts its value to a range of 1 to 20, where 1 is brightest. It also reads the rate pot and converts its value to a range of 1 to 5 where 1 is fastest.
bness = analogRead(BnessPin) / (1024 /
numlevels) + 1;
// gives value of 1 to 20, 1 = bright 20 = dim
rate = analogRead(RatePin);
// Any value > 800 will be regarded as
// 800 or highest rate
if (rate > 800) rate = 800;
// gives value of 1 to 5,
// where 1 is fast and 5 is slow
rate = rate / 200;
rate += 1;
This is colorWipe(), a function from the NeoPixel library. It sets the colour of the LEDs one after the other. It looks great.
for (uint16_t i = 0; i < strip.numPixels();
i++)
{
// i = which pixel, c = colour
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
Take a good look through the code and you will understand how each one works. You can compile the sketch onto your Arduino. It’s fairly straight forward and provided you have power to your LED strips, you should see your first pattern on the LED strip appear.
WHERE TO FROM HERE?
There are loads of patterns and ways to change the colour modes. Experiment, play, and see what you like!
It’s also possible to make something much bigger and more impressive. We wanted to create a springboard project that gets you working with addressable LEDs, and thinking in a more creative way for execution. Stay tuned for that one!