This was a fun project to try to make some flashing lights. Of course, it needed to be a bit more complex than that so a Raspberry Pi was used for Internet connectivity, and some analog circuitry was used to generate multiple PWM outputs to drive strings of lamps. Everything can be dimmed or particular patterns selected from any web browser. For a holiday look, the lamps were enclosed in star-shaped laser-cut acrylic. All the steps are detailed here if you wish to build something similar.


The controller board was built in two evenings after work, and the strings of lamps can take a few hours to assemble; so this could be a weekend project.

Even if you’ve already have your holiday lights arranged by now, this post may be useful for the following information:

•    Using 555 timers

•    Controlling a DAC using the Raspberry Pi

•    Controlling hardware using MOSFETs

The source code is also useful if you have other requirements for controlling or retrieving status information from software or hardware using a web browser.


The project uses low voltage lighting for safety and hardware PWM to greatly simplify the software. The software is simplified further by utilizing JavaScript as the main programming language; the entire project occupies just three small files.


The plastic parts are possible from most laser cutting services; however if you contact Problemchild he has the design files and can supply a very good quote for these shapes in various translucent colors. The plastic shapes in this post used John’s laser cutting service.

Here is a video of it in action running one of the patterns (it can handle multiple patterns all controllable via the web browser including pattern speed):


This is the actual controller board (it was stacked under the Raspberry Pi in the earlier photo):



Solution Overview

The diagram here shows how it all works. The user controls the whole thing from a web browser. The controller board powers four channels of lighting. The light strings can total 12V or 24V for flexibility and can be powered with a small mains adapter. These low voltages mean that the project is safe.


The project here used 5V lamps and chained five of them in series for each channel, i.e. totalling 20 lamps run from 24V. It is also possible to drive lamps in parallel if desired, if longer lengths of lighting need to be driven.


The project can be split into two halves; Part of it is software, and part of it is in hardware. You can skip the design descriptions below and go straight to the build if desired.


Software Design Overview

The software needs to do a few things; serve up and handle web page interaction, implement a lighting patterns using some sort of timer for animation, and to drive some of the pins on the RPI (general purpose I/O pins) to control the hardware which will drive the lights.


There are many ways to achieve these tasks; in this case, a software platform called Node.js was predominantly used (thanks fustini ). It allows most of the software to be written in JavaScript, and also eliminates the need to install a heavy web server such as Apache, because a lightweight web server is available for Node.js. It reduces the need to use another programming language; the code that will be written to run on the RPI will be in the same language as the software that will run in the web browser as coded in the HTML file.


Note that a very tiny piece of software is written in C; that bit of code is the interface to GPIO.


To summarise, just three files are needed; the Node.js program (written in JavaScript), the HTML file and the C program that will write to the controller board over GPIO. These three files are attached in the zip file at the end of this post.


The small C program is called ‘dac’ (predictably it is used to control a DAC on the controller board which adjusts the channel brightness as will be seen later). The program can be executed from the command line using:

./dac <chan> <value>

where the first parameter corresponds to a channel between 1 and 4, and the second parameter sets the brightness value between 0 and 255. In our case, the Node.js program software directly calls the dac program.


The diagram here shows a graphic view of the software components that will be running inside the RPI. The three software files are shown in green (index.js JavaScript file), blue (index.html file) and red (the dac.c program). It is all fairly self-explanatory if you view and compare it with the code.


Hardware Overview

There are many ways to generate PWM; the design here uses a 555 timer chip to create a fixed-frequency sawtooth waveform that is continually compared to an adjustable voltage from a DAC. Whenever this DAC adjustable voltage exceeds the sawtooth level, the string of lamps is switched on using a MOSFET. By using quad DAC and quad comparator ICs, the circuit allows for 4 channels to be independently controlled (just one channel is shown in the diagram below for simplicity).



Building the Circuit

The circuit can be built in 4 portions (5V regulator, sawtooth generator, comparators+MOSFETs and DAC) with each part tested before moving to the next part. No special equipment is needed to test; a multimeter and a pair of headphones are sufficient.


The circuit was created on prototyping board of the circular ring variety (sometimes known as perfboard), but stripboard could be used too if preferred. With the circular ring type board, the components are soldered in position and then very thin bare wire can be used to make traces on the underside (other ways are possible too).


The photo below shows the mapping of the bits of circuit;

Blue: regulator circuit

Green: sawtooth generator

Red: comparator

Purple: MOSFET outputs

Yellow: DAC



Physical Layout Diagram

The entire layout is shown here and can be used as-is, or if you want the boards to stack then a minor change is that a couple of parts need to move slightly to accommodate the screw holes that need to be created in the prototyping board.


As mentioned, most of the wiring occurs on the underside of the board using thin bare wire. Note that capacitors C6 and C9 are soldered on the underside too, to keep wire lengths short. Each portion of the build is described in detail below but refer to the physical layout diagram above as you are building each portion.


The first step is to drill holes if you desire the boards to stack:


At this stage it is worth attempting to assemble the RPI on top to ensure that the holes are in the correct position before proceeding further.


5V Supply

Most of the circuit operates from 5V, but the lamps require a higher voltage since they will be chained together. A 78L05 voltage regulator circuit was built, and then tested with a multimeter before proceeding further. The 78xx series regulators are extremely common and used in a lot of projects. The ‘L’ variant is used for low power applications. The DC socket J1 is available in thin and fat center pin variants and usually the correct one is needed to match the power supply. To save headache, use the recommended socket which has a compressible diameter center pin that can handle both thicknesses of the mating plug.


Once you have built up the regulator circuit, check with a multimeter on the unpowered circuit to ensure there are no obvious faults like a short circuit between the +24V, +5V and 0V wires. Once this is done, power it up and confirm that you can successfully see the 5V output.


Sawtooth Generator

The sawtooth generator consists of a 555 oscillator chip combined with a single transistor constant current source. The sawtooth waveform is taken from the capacitor, instead of pin 3 of the 555. The 555 is an extremely popular chip – see here for fifty more ideas.


With the two capacitors C3 and C4 as shown in the circuit diagram, the frequency of oscillation is quite low (a few kHz) so that it is possible to test the circuit easily without requiring an oscilloscope, before proceeding further.


To test the circuit, connect up a low cost pair of headphones to pin 3 of the 555 and to ground in series with a small capacitor (100nF is fine). You should hear a high-pitched tone. If this is successful then the circuit so far works well. The test is complete! Unsolder or cut out the C4 capacitor to increase the frequency to a usable level for the project. The frequency will now be approximately 15kHz.

The diagram here shows the generated waveform.


PWM Generator and Output Circuit

The PWM signal is created using a comparator chip. As the name suggests, such a device can compare two inputs and the output becomes high or low depending on which input is higher than the other. By supplying a fixed frequency sawtooth as one input to the comparator, it is possible to generate any pulse width (up to the period of the sawtooth) by adjusting a voltage level on the other input of the comparator. If you want to see this as an animation, click here (java needs to be installed).

You will see a screen similar to the one below. By adjusting the slider at the bottom-right, the PWM level can be adjusted and is reflected in the animated waveform displays. Note that this simulator is useful for testing out other circuits too.


The actual circuit is shown below. The output of the comparator is known as ‘open drain’ which allows it to be connected up to a higher voltage. Five lamps are connected in series (each one is rated for 5V), which is ideal for powering from a small 24V mains adapter. The circuit is repeated four times so that multiple channels of lights can be controlled. Refer to the table to the left of the circuit below for the pinout for the LM2901 chip which contains 4 comparators inside.


Once this part of the circuit is assembled, it is possible to test by applying a controlling voltage (using a variable resistor) to pin 7,5, 9 or 11 of the LM2901 IC and observe the dimming action of the lights. If the lights have not been assembled, you can use a single LED in series with a 2.2k resistor.


The traces below show the signals probing at various points in the circuit. As the controlling voltage is varied, the width of the blue and purple pulses will change.pwm-waveforms-annotated.png

DAC Circuit

The final part of the circuit is the quad DAC implementation that will interface between the Raspberry Pi and the comparators. A reference voltage of about 3.8V is created using resistors R14 and R15 (potential divider circuit). This provides a fraction less than 8 bits of resolution for the lamp dimming action – it is more than sufficient for this use-case. The IC has four analog outputs, one for each comparator. The IC is loaded with the desired levels using a three-pin interface consisting of CLK, LOAD and LDAC pins. These are manipulated using software.



Hardware Checks

Run a few checks on the circuit to confirm all is well. For all these tests, do not connect up the board to the RPI.

1. With power off, confirm no short between +24V, +5V and 0V lines with a multimeter

2. Confirm that the +5V connection on the DC connector J1 is connected to the power pins on the three ICs

3. Confirm that the 0V connection on J1 is connected to the 0V pins on the three ICs and to the MOSFET source pins

4. Now power up, and confirm with a multimeter that the regulator delivers 5V, and confirm that the regulator is not hot - it should be between cold and about body temperature if all is working well

5. If you did not do it earlier, confirm with headphones and a 100nF capacitor in series that you can hear a tone as described earlier. Once this is confirmed, snip or desolder the C4 capacitor.

6. Place a 10k resistor between the DATA pin of the DAC and 0V (this is easy to do by pushing the resistor into the jumper cable socket that will connect the controller board to the RPI. Place a multimeter across the resistor and confirm that you see 0V. Repeat for the other two signals that will connect the two boards together.


Software Installation Details

The steps at this site were used to install node.js, modified slightly:

From the home directory (/home/pi):

mkdir –p development/light
mkdir mytemp
cd mytemp
tar xvzf node-v0.10.21-linux-arm-pi.tar.gz
sudo cp -r node-v0.10.21-linux-arm-pi/* /opt/node

The above will result in the node executable being placed at /opt/node/bin being installed.


The /etc/profile file needs two lines added before the line that says ‘export PATH’. To do this, type

sudo vi /etc/profile

(assuming you know how to use vi; otherwise use an alternate editor). These are the two lines to be added:


Then, reboot the RPI:

sudo reboot


Once it comes back alive, the next step is to install socket.IO:

cd ~/development/light
npm install

The above command will take about 5 minutes to complete.


Now, In the mytemp folder, type the following to install an excellent GPIO library by Gordon (unfortunately I don't know the last name):

cd ~/mytemp
git clone git://
cd wiringPi

The above will download, compile and install the wiringPi library into /usr/local/lib.


Place the dac.c file that is attached to this post into the development/light folder (and also the index.js and index.html files while you are at it), and compile it as shown here:

gcc -o dac -lwiringPi dac.c


The software part is now complete. As a simple test, connect up the controller board to the RPI, plug in the 24V supply (you don’t need to worry about any power-up sequence) and use the command below then confirm with a multimeter that the DAC output pin 12 goes to about 3.7V.

sudo ./dac 0 255

The first parameter was the channel number (0-3). If any lights were connected to channel 0, then they would now be lit up (We still need to make the lights, they are described further below).

The lights on channel 0 can be dimmed to any value, such as:

sudo ./dac 0 128

To turn the light off:

sudo ./dac 0 0

You should see the DAC output on pin 12 vary accordingly as the commands above are entered.


Constructing the lights

Depending on your needs you could construct the chains of lamps in different ways. A general topology is shown in the diagram here.


The four chains can be bundled together and secured with a small piece of clear heatshrink tube or glue or tape (or twisted together). As expected, the chains are staggered so that light ripple effects run across the bundle. For a thinner bundle although four return wires are shown, they could be reduced to a single wire going to the +24V supply that is common to all four channels.


Since this is a custom design you may wish to adjust the lamp spacing for the exact perfect length. There is an excel spreadsheet attached to this post that lets you enter in parameters, and it will calculate the lengths of all the wires (but do add an additional centimetre to the drop length, to allow for wire stripping).

You also need plastic shapes (here are some common translucent colors).


The steps to assemble each lamp are described in the sketch here but also in the photographs further below. The clear or colored translucent plastic shapes can be built up to the desired thickness by securing with clear tape along a couple of edges. This means it can be changed the following year if you want a different color scheme.


The lamp assembly is surprisingly fast – just make a couple of holes in the sticky feet (just by hand with a 0.8mm drill bit – no need for a tool), push in the wires, strip the wires about 8mm, twist the lamp onto the wires, optionally solder it, and then attach the sticky feet to the plastic shape with a bit of glue. The wire ends will be kept apart because they automatically fit in between some of the ridges in the plastic shape hole, so no extreme care needs to be taken during assembly (the shaped hole also serves as a lens and to hold the lamp centered).


The resistance of each string of lights will be about 23 ohms with the recommended lamps.

This is the final result when lit:



Using the system

Once you have the lights connected up to the board, power it up and go to the development/light folder where the code was placed and enter the following command to start up the program:

node index.js


Now you can traverse to the web page http://xx.xx.xx.xx:8081/index.html using any web  browser and you should see a lights control panel view like the one shown below. Pressing any button to explore the commands available. There are only two patterns for now but more can be easily added if desired. Pattern speed is adjustable. The status bar will indicate when the RPI has received and processed the commands.




The lights controller described here allows for 4 channels of dimming and full control from a web browser. Hopefully it can provide further ideas. The software structure based on a Node.js platform can be reused whenever you need to control or monitor hardware remotely via a web browser. The DAC control program, and TI’s 4-channel TLC5620 DAC are ideal for whenever you need a computer-controlled, adjustable voltage for controlling external devices. The MOSFET control described here was fairly simple but is ideal for whenever you want to switch a few hundred milliamps without relays. Portions of the analog circuit were simulated before construction and it is worth getting to know the simulator for trying things out. The actual traces in this post were taken with a Tektronix MSO2024B oscilloscope. The quality of the laser-cut shapes from Problemchild's service was spectacular so I’m looking forward to actually using these lights now. If you are interested in constructing something similar, a parts list is below and the attached zip file contains all the code.



Parts List

ID Description Quantity Farnell Part Code

C1 Capacitor 220nF  1 1692301

C2 Capacitor 22uF 50V 1 8766835

C3 Capacitor 10nF 1 1902262

C4, C5, C7, C8 Capacitor 100nF 4 1141777

C6, C9 Capacitor 100nF Axial 2 1902254

IC1 Quad Comparator LM2901N 1 9487697

IC2 Timer NE555P 1 9589899

IC3 TI Quad DAC TLC5620 1 8454493

IC4 Regulator 5V KA78L05AZ 1 1014073

J1 DC Connector 2.1-2.5mm 1 1854512

LMP1-20 Lamp T-1 5V 120mA 20 1139298

Q1-Q4 BS270 N-channel MOSFET 4 1017689

Q5 BC557 NPN BJT 1 9558527

R1 Resistor 2.7k 1 2329509

R2, R4-R7, R15 Resistor 10k 6 9339060

R3 Resistor 1k 1 9339051

R8-R11 Resistor 33k 4 2329515

R12, R13, R16, R17 Resistor 10R 4 9339035

R14 Resistor 3.3k 1 2329522


DIL IC socket 8-pin 1 1077344

DIL IC socket 14-pin 2 1077311

Header 40way 2row (cut to 26way) 1 1319210

Proto board (Perfboard) 100mmx160mm 1 1221144

3M ‘Bumpon’ clear feet 12.7mm diax3.5mm 1 2314565

24V 1.25A Power Supply 1 1354829

Terminal block PCB mount 6 way 5.08mm 1 2008008

Wire white 1mm ext. dia. 7 strand 1 1177586

Wire bare 30AWG 1 2290921

Nylon standoff 15mm M3 2 1336157

M3 screw black 6mm 4 1420015

Plastic shapes – order directly by contacting John Alexander

Impact adhesive (UHU or Bostik for example)

Clear tape



Zip file here.