This project builds an automated holiday lighting system that combines lights and music through a free software package called "Vixen Lights." Vixen Lights is a sophisticated package that allows the user to choreograph a holiday light show. The user defines the lighting elements, chooses the music, and coordinates the two through a simple sequencing interface. Vixen runs on a PC and sends out serial data carrying the information that defines the states of the lighting elements. This data is the input for lighting driver boards (controllers) based on the Arduino.
Six types of lights are used in this project:
- Individually Addressable LED light Strips
- RGB lights (LED Strip Lights)
- Four wire RGB fairy light strings
- Bipolar Light Strings
- Low voltage DC elements
- 120 VAC operated elements
As seen in the video, the elements used in this project involved short strips or strings of lights. These strings or strips were cut to the exact length required for the particular element. For instance, the side ribs of the aircraft are approximately three feet long. Each side rib has a wash light strip on the inside and a fairy light string on the outside. Each of these elements is individually controllable. Thus, the fairy light string on a rib is controlled independently of the wash light strip on the rib. Each rib is its own element. The perimeter lights were cut from a long string of lights to the lengths required. Each string had an appropriately sized series resistor. And once again, each string was individually controllable. The following discussion details how this was accomplished.
Individually Addressable LEDsEach light type requires a different type of drive circuit. The simplest are the individually addressable LEDs. In this type of strip, each individual LED can be accessed and controlled. Three lines are connected to the strip; power, ground, and data. The data line accepts serialized data in RGB format, 8 bits for each color. At the location of each LED is an IC (WS2812B), and a three color LED (5050). The IC is clever in that it strips off the first three bytes of data and forwards the rest to the next device in the line. Each device in series strips off it's data and sends the rest on until no data remains. If the strip is longer than the amount of data, the LEDs at the end of the strip will remain unlit.
To address this type of light, one only needs the Arduino to accept serial data from Vixen and then send it along to the LED strip. The data rate to the LEDs is controlled by a library designed for the purpose and is about 400KHz. This sets the limit on the amount of data that can be sent. So, if you have 100 lights, each will take 24 bits for a total of 2400 bits. That means the the entire string of lights can be refreshed in 2400/400, 000 secs or 6 milliseconds. But, you must get the data from Vixen. I've found that I can reliably get Vixen's serial data at 115, 200 baud. Serial data is transmitted with a stop and start bit, so it's 10 bits per bit, lowering the serial data rate to 92160 bits per second. So the time to receive data for 100 lights is now 2400/92160 or 26 milliseconds. Since the Arduino doesn't multitask, the combined time to receive data from Vixen and then send it to the string is 32 milliseconds or about 30 updates per second. This is just on the edge of the eye's ability to perceive the data update.
A consideration in setting up your lights will be how fast they can be updated. From experience, a 100 pixel strip is not that many lights. For my application, in one portion, I used over 2000 lights lowering the update speed by a factor of 20, or close to.6 seconds.
RGB LED StripsThese strips are similar in appearance to the individually addressable ones described above. Here though, the WS2812B is eliminated. Instead, the 5050 tricolor LEDs are connected to 12 Volt power (four in series) and each color is controlled by a shared red, green, or blue control line. To power the red LED, the red line is grounded. As you might suspect, if the red line is grounded, all the LEDs in the strip turn red. So, the entire strip can display 24 bit colors, but all LEDs will be the same color.
These LEDs operate with a driver that can pull down the color lines. Depending upon the length of the strip, the power draw can be significant and obviously must be recognized and anticipated.
Four wire RGB fairy light stringsYou may have come across this type of fairy light. Not all are the same. Here you are specifically looking for a string with four wires. To avoid getting the wrong lights, be aware that similar RGB strings exist with only three wires. I chose not to use these because they require a bit more sophistication in the circuitry to operate. The four wire strings are just like the RGB LED Strips described above except that these are not a silicone rubber encased set of 5050 LEDs, but individually encapsulated tricolor LEDs connected together by a durable copper/silver alloy coated wire. They are surprisingly robust.
The four wires allow you to access the red, green and blue LEDs individually. Of course, if you actuate the blue line, all the LEDs in the string will light blue. The fourth line is for power. Grounding the color line actuates that color. You will also notice that there is an extra wire. This wire brings power to the tail end of the string to reduce the voltage drop along the string. For my project, I needed short strings, typically less than four feet long. To obtain these, I cut the string in multiple positions. I threw out the controller that came with the string. The wires are coated with a polymer which I removed with a torch. I powered each string with a 5 volt supply. To do so, you need a series resistor sized to match the current draw of the number of LEDs in your string section. The original string was designed for low current draw; somewhere less than 1 ma. I drove my at 2 ma for several days without failures. They were quite bright.
These fairy lights are controlled using the same circuitry as that used for the RGB LED Strips.
Bipolar Light StringsThese strings or four color lights often carry the "fairy light" moniker. But they are not the same. Here, each LED has its own inherent color. Typically they are red, green, yellow, and blue. The four colors are repeated in order down the string. Each string is typically hundreds of feet long. They are fairy lights in the sense that they are very low power LEDs. Of course, they are also low brightness.
I call these bipolar strings because if voltage is applied in one polarity, the blue and green LEDs will illuminate. If the opposite polarity is applied, the red and yellow LEDs will illuminate. You can make it appear that all the LEDs are illuminated by rapidly reversing the polarity.
To drive these LED strings a circuit is needed that can switch the polarity of the power applied to the string.
For strings purchased for this project, the red and yellow light shine with one polarity and the green and blue lights shine with the other polarity. I never used the controller that comes with these strings, and I typically cut the stings into lengths to match my projects needs.
As delivered, the driver provides 50 ma @ 30V for 200 LED string, where only 100 bulbs are on at a time. This current flows through 10 LEDs. Therefore, there are 10 sections each at about 3 volts. So each LED is 5 ma. The strip is 66 ft long; each section is 6.6 ft or about 2 M (therefore 5 LEDs of each polarity per meter). Keep in mind that each color has a different forward voltage drop with red/yellow is approximately 2 volts and blue/green is approximately 3 volts.
When the string is dismantled and cut into short sections, you will need to be aware of the fact that the string is configured as described above. That means that you will find a section of 20 LEDs all in parallel (10 blue/green and 10 red/yellow). A single ground wire runs the whole length of the string. So at 5 V, we will need to supply 5 ma per LED. To control the current at 5 ma per LED, we need to add a series resistance. Since the diode forward voltage drop for blue/green is about 3 volts, the resistor will drop about 2 volts. So to get 5 ma per LED, R = 2 volts / (5 ma * #LEDs of one polarity).
Net LightsThese net lights are similar to the bipolar lights described above in that half will turn on under one polarity and the other half will turn on with the opposite polarity. These lights are a bit trickier to figure out than the bipolar Mini String Lights. The net is composed of a set of parallel LED strings each with around 10 LEDs wired in series. The series is powered with a 30 v supply through a series resistor. To customize the net size to my projects needs, I determined first how the string is configure. Not all have the same configuration. This is a probing and trial and error process. Once I determined the configuration, I cut the net in such a way that powering two wires would light a the portion of the net I cut out. Of course, each polarity lit half the lights. For nets, the series resistor is built into each LED node. Therefore, no additional resistor is required but you must actuate the sub net with 30 Volts.
Low Voltage DC ElementsOften, you may want to turn on a single element which operates at a low DC voltage. You will find that ornamental figures are often a single color and at actuated with a 30 Volt supply. These are typical of what I am calling Low Voltage DC Elements.
120 VAC Operated ElementsIf you plug it into the wall outlet, it falls into this category. Here your only control is turning it on or off. To operate these elements, I use a relay controlled by an Arduino.
Controller DesignAlthough we have six types of lighting elements, we only need three types of controllers. Counterintuitively, the simplest is the individual addressable LED strip controller, which can be controlled directly by an Arduino. The two other required controllers are used broadly for bipolar lights and for low voltage elements.
- Individually Addressable Controller
The individually Addressable LED Strip (or others) uses a three wire interface comprising power and ground lines, and a data line. A 5 Volt supply with high current (10s of Amps) is needed for any strip of reasonable length. The Arduino supplies the needed signal for the data line.
For a really good writeup on how to use an Arduino and Vixen Lights to control individually addressable LED strips see Victor Aguilar. Victor's explanation of the interface between Vixen Lights and the Arduino is exactly what is needed to implement the controllers for bipolar and low voltage elements as well with minor adjustments. Please read Victor's project before continuing.
For the Arduino code, you can find lots of examples on the web. Victor's solution follows the same basic scheme that you will find elsewhere and that I used. In brief, using either fastLED or Adafruit libraries, the software first collects all the data from Vixen through a serial port and then sends it out to the LEDs. Typically, folks are operating the serial port at 115200 baud. As previously indicated, the data rate to the strip is 400 KHz. Be aware that there is a high likelihood that your code will miss a data stream.
- Bipolar Controller
The purpose of this controller is to collect data from Vixen Lights and use it to control the bipolar lights. To accomplish this, the controller must be capable of changing the polarity of the signal sent to the bipolar string. This is accomplished with a pair of Class AB Amplifiers. A second required function is to control the intensity of the LEDs. This is accomplished through pulse width modulation. As it turns out, using individual pulse width modulators is expensive and inefficient. Fortunately, a great solution is achieved using an NXP Semiconductors PCA9955 16-channel Constant Current LED Driver. While this device is meant to provide current to LED arrays, it can only source 57 ma. But, in fact, we only really need the pulse width modulators. Therefore, the current capacity of the device is not an issue.
This controller therefore can control the brightness of the LEDs of either polarity. In addition, within the Arduino code is a function that implements an all on function by alternating polarities for each cycle through the main loop. Thus, we have three states, polarity 1, polarity 2, and all on. Vixen has not implemented such a string. To overcome this limitation, the Arduino recognizes three colors to match these three states. So, if red, then polarity 1. If green, the polarity 2. If blue, then all on. In all states, the intensity is controllable.
For bipolar lights, you will need two PCA9955 channels per string. With 16 total channels, eight strings can be intensity controlled. Since the output of the PCA9955 is a current sink, each output has a pull-up resistor followed by an NPN transistor which provides input to the Class AB amplifier.
The Arduino collects data from Vixen Lights and communicates with the PCA9955 through an I2C interface. This means that all outputs can be controlled through a two wire interface leaving significant I/O capacity available. The circuit uses two outputs for chip select and reset lines. The rest of the I/O is used to monitor the output of the Class AB amplifiers. This functionality is not exploited in my code. Instead, I monitored the outputs using the attached on-board LEDs.
The circuit board also contains a set of jumpers that allow the selection of an address for the I2C interface. The PCA9955 probes these jumpers upon startup and sets the I2C address internally.
You will notice that the supply for the Arduino and the Class AB amplifiers are separated. This allows one to drive the outputs at 30 Volts, for instance, while providing only 9 Volts to the Arduino. A jumper will allow the connection of these two supply lines so that only a single supply is needed.
Three prototyping areas are included on the board. I used these for three different functions. In one, I placed a USB to serial interface. There are many versions available from Amazon. What is important is that you spend a bit more money to make sure you get a genuine FT232RL from FTDI. The inexpensive devices use a Chinese knock-off which does not include the eePROM or individual serialization. If you intend to use more than one of these knock-offs, you will find that your PC will not be able to distinguish between them. Thus, if you try to assign a different port to each, the PC won't be able to reproducibly assign the same port number upon reboots. This is a major problem when using Vixen Lights to control your lights. I discovered this after buying tens of these devices for my implementation. To overcome this issue, I purchased the FTDI chips from Mouser and removed and replaced the ones on the Chinese parts.
The two other prototyping areas were used for power supplies, one for the Arduino and the other for the output. I preferred keeping these supplies separate because it allowed the adjustment of the brightness of the LEDs simply by adjusting the output supply voltage.
- Low Voltage Element Controller (Fairy Board)
This controller was originally designed to drive four wire fairy lights. provides sixteen pulse with modulated outputs using the PCA9955 as its base. Only fifteen of these outputs are used to drive five fairy light strings.
This board shares many of the features of the bipolar controller. Here though, the output is a simple Class A amplifier. You will note that in the schematic, there are two output transistors per channel. Only one will be installed depending on the output current requirements. I used 2n2222s for low current requirements and BD139 NPN transistors for high current applications (wash lights).
The board is designed to be stackable, a feature I used with five boards per stack. If stacked, only a single power supply and single serial interface is needed. Here, the headers for I2C addresses are set so that each board in the stack has its own address. Naturally, the power supply, I2C, and serial interfaces are connected through the stack.
You will also note that the remaining I/O on the Arduino are brought out through headers. These can be used to control relays, or simple on/off devices. The Arduino code provides 16 channels for low voltage elements and 8 relay channels.
Each of these boards will drive 5 fairy light strings, 5 5050 LED strips, or 16 single element lights. I used both solid state relays, for 120 VAC elements and 5v mechanical relays which were controlled by the 8 digital I/O lines.
Patch BoardsTo make it convenient to connect and disconnect elements, I created patch boards for the two types of controllers. These boards supports 25 RJ45 sockets. I used RJ45 jacks because they are reliable and quick to connect and disconnect.
AssembliesThe photograph below shows a portion of the control box where the single element controller was located. As already stated, the same controller that drives the fairy lights and the wash lights (5050 strip), also serves as a controller to drive single elements. If you watched the video at the beginning of this story, you saw that the final completed boat/airplane had three propellers and a snow bird with flapping wings. The lights on the snowbird body were the only driven at 120 VAC. These could be turned and off using the single element controller. The three propellers had a spinner that housed a drive motor and an Arduino used to create the spinner light display (individually addressable LEDs). These could be powered or not using this single element controller and mechanical relays. Finally, the brightness of the lights on each propeller blade (two per propeller) and the snowbirds wings and sunglasses were controlled by the single element controller.
Looking closely at the photo you can see that four 8 wire ribbon cables span the gap between the controller and the patch board. These connect to the RJ45 jacks on the patch board each associated with outputs for four elements. For this project, only nine of the sixteen available outputs were used.
From the beginning of the project, it was understood that the fairy boards (individual element controllers) would/could be stacked. It should also be noted that because the wash lights (5050 LED strips) require a 12 Volt supply and the Arduinos prefer a supply greater than 5 Volts and because providing the ability to adjust the supply voltage at individual controllers was advantageous, all the electronics inside the box was powered by a single 20 Amp 12 Volt supply. At each board or stack, a buck supply was used to reduce the voltage to a level appropriate. Rather than consume fairy board space for the supply (and the USB to Serial Converter), these were mounted on 5x7 cm proto boards. Each stack had a single proto board.
In the photo below, we see two fairy board stacks driving fifty fairy strings. Five ribbon cables from each stack are directed to the patch board. All the RJ45 jacks are connected. Each jack supports two fairy strings.
To operate the wash lights (5050 LED strips), three fairy light boards were stacked as shown in the figure below. Out of a abundance of caution, buck supplies were used to reduce the drive voltage of the boards. The temperature of the transistors was monitored to make sure that they remained cool. The wash lights were 5050 LED strips each about 1 meter long and meter drawing over 1 Amp when lit white. The transistors used on these boards were BD139, each capable of sinking up to 1.5 Amps.
In the photo below is a stack of bipolar boards (controllers). Each communicates with its own OLED display seen on the extreme left. The three prototyping areas on the board are used to house components that are readily available. Home brew cables connect the outputs to the patch board. Each RJ45 jack supports four bipolar strings. Each board supports eight bipolar strings. The top board operates at 30 Volts and drives the potentially eight nets (only six were needed). The lower boards operate at 5 Volts and drive potentially 32 bipolar strings. Each board has its own USB to RS232 interface. This is not necessary. One could modify the bipolar drive software to mimic the fairy light drive board and drive all boards from one NANO. Once rewritten, a cable would have to be constructed to carry the I2C signal to all boards.
Comments