Color LED strips are now available at low cost in all sorts of types and sizes. With the controller circuit described here, you can set your own colors and even configure and run complete lighting programs. The controller is battery powered, so it can be used in places where AC power is not readily available.
This circuit was originally developed to drive color LED strips from a well-known Swedish chain of home furnishing stores. These color LED strips come with a simple controller, which allows you to manually select a limited number of colors. This restriction stimulated the author to develop a DIY controller with more capabilities. The resulting ‘ambience lighting controller’ is suitable for all RGB LEDs and LED strips that can operate from a 12 V supply voltage with a series resistor for current limiting. In the author’s intended application it was not possible to power the LED strips from the AC line, so the controller is designed to operate from a 12 V gel-cell battery. The basic features of the circuit are described in the inset.
As you can see from the schematic in Figure 1, the circuit is fairly simple. The author chose a PIC16F887 for the microcontroller on account of its integrated EEPROM (for convenient storage of lighting programs), extensive I/O capacity and integrated ADC. Although the PIC16F877A is more popular, a sibling device was selected for this application because its ADC configuration allows the ADC inputs on RA0 and RA1 to be used without requiring any reference voltage input on RA2 or RA3. Here RC3 is connected to switch S1, which allows the battery charge state to be shown on the LCD module in two different ways. Connector K6 is the ICSP port for in-circuit programming of the microcontroller. The microcontroller is clocked at 20 MHz by crystal X1. This relatively high clock frequency is necessary because the clock signal is divided by 4 inside the microcontroller. The resulting 5 MHz signal is essential for the PWM control function implemented in software.
The display module, a standard type with two lines of 16 characters (which is available in the Elektor Shop), is connected to port RB. If you use a different type of LCD, the polarity of the supply voltage for the backlight can be changed (if necessary) using jumpers in positions J1 and J2. Transistor T2 switches off the backlight after 10 seconds with no user input. The contrast can be adjusted with trimpot P1. Unlike most circuits with an LCD module, here the LCD is driven in 8-bit mode instead of 4-bit mode. This simply represents a design choice, since the microcontroller has enough I/O pins available.
The color intensity of the connected LEDs is determined by pulse width modulation. Although the microcontroller has enough PWM outputs available for this purpose, the author decided not to use them in order to simplify the routing of the prototype circuit board. For this reason, the PWM function is programmed in software. The LEDs are driven by the power MOSFETs T3, T4 and T5, which are designed to operated from TTL-level signals. The RGB LED strips (maximum 4) are connected to connectors K2 to K5. Each of the MOSFETs can easily supply several amps without extra cooling. Bz1 is a buzzer with a built-in oscillator, so you only need to apply the supply voltage to get a penetrating acoustic tone. The control elements consist of three rotary encoders with built-in pushbuttons. The RA0 and RA1 leads of the microcontroller are used as A/D converter inputs. The RA0 input measures the battery voltage, while the RA1 input detects whether a battery charger with a supply voltage above 14 V or so is connected. Voltage dividers R5/R4 and R6/R7 reduce the sensed voltages so they fall within the measuring range of the microcontroller. Capacitors C8 and C9 decouple any ripple voltage on the sense lines. The schematic also includes a serial to USB converter module (Elektor BOB, order no. 110553-91 ), which can be used for linking to a PC if so desired. The circuit can be controlled remotely using a number of commands in a terminal emulator program. For more information about this, see the user guide (free download ).
The supply voltage is regulated by a conventional 7805 together with a few capacitors (IC1, C1–C4) and a diode (D2) for polarity protection. The value of fuse F1 in the power supply stage depends on the load. A 2-A slow blow fuse should be adequate with 6.5-ft (2-meter) LED strips, but to be on the safe side you should measure the load current in the actual application. Naturally, you should do this with all colors set to maximum intensity. Connector K7 is the power input connector for a gel-cell battery, and an AC adapter with an output voltage of approximately 15 V at 2 A or more can be connected to K1. Transistor T1 drives relay RE1, which in turn shorts out resistor R1 when the battery has to be charged. The relay type is not critical—as long as the contacts can switch 2 A and the coil voltage is 12 V. See “Operation” for more information about the relay. The circuit draws only 25 mA or so in operation, or approximately 50 mA with the backlight on.
PCB Figure 2 shows the PCB layout designed at Elektor Labs for this lighting controller. Only leaded components are used, so board assembly is easy even if you don’t have a lot of soldering experience. All components are fitted on the side with the component overlay. Using flat-jawed pliers, bend the leads of the voltage regulator and the MOSFETs at a right angle before fitting them to the board, so that they lie flat on the board after they are soldered. These components do not need heat sinks for normal use. The microcontroller (optionally available preprogrammed) should be fitted in a socket. If you want to use a serial link to a PC, you should install the Elektor USB FT232R breakout board. It can be fitted directly on the PCB, or you can use a pair of 9-pin SIL socket strips.
The program for this circuit was written in ANSI C using MPLAB and compiled using a full-function Hi-Tech C compiler running in evaluation mode (45-day trial license). The “lite” version of this compiler is not suitable in this case because it does not provide sufficient optimization, with the result that the executable code is too large for the 8 KB of program memory in the microcontroller. The source code and hex code, as well as the PCB layout, are available on the Elektor website  for free download. As usual, you can order a pre-programmed microcontroller in the Elektor Shop. The key component of the software is the interrupt service routine (ISR). This routine was optimized using the stopwatch function of MPLAB to minimize its execution time. The ISR is divided into several subroutines that can be executed every 100 µs, 5 ms, 100 ms or 1 s. The ISR is called every 100 µs, and it uses counters to ensure that the subroutines are executed at the previously mentioned intervals. To reduce memory usage, a counter was initially used to determine the 1-ms and 100-ms intervals. A modulus calculation (which yields the remainder of a division operation) was performed each time the interrupt was called (every 100 µs), and if the remainder was zero, a 1 ms interval had expired. During debugging with the stopwatch function it turned out that this modulus calculation took so much time that it would be better to use the second counter to determine the 1 ms intervals.
The automatic light level control works as follows. The nominal PWM clock frequency is 100 Hz at 11 V. If the battery voltage is higher than 11 V, the LEDs will be brighter if the duty cycle remains the same. If the duty cycle is adjusted according to the battery voltage, a new duty cycle has to be calculated for each color. A much simpler method is to leave the ‘on’ time the same and reduce the PWM clock frequency as the voltage rises. This means that the calculation only has to be performed once to obtain the same result.
The difference between PWM clock frequencies of 100 Hz and 90 Hz is not visually noticeable. Another bit of software that caused headaches for the programmer with the code for the color transitions. The calculation is very simple in principle: take the PWM value for each color, calculate the difference between this value and the next value, and spread the result over the transition time. Then raise or lower the PWM value for each color at each step during the transition interval (here the transition interval is given in increments of 100 ms). The result of the division is typically a decimal fraction, which means that floating point variables have to be used for the calculation and for storing the values. The PIC16F microcontrollers are simple 8-bit devices, and the compiler had a lot of trouble handling these “big” floating-point variables. This led to timing problems and errors in the compiled code. The solution to this problem was relatively simple. Multiplying and dividing integers takes less time and memory than working with floating point numbers. Accordingly, the difference between the PWM values for each color is first multiplied by 100 and then divided by the transition time, as shown in the following code segment (Listing1). At every step during the transition interval (every 100 ms), the current PWM value is calculated and then divided by 100. The result is an integer “rounded off” to two decimal points, rather than a decimal number (Listing 2). With this approach, an 8-bit microcontroller can handle color transitions without significant performance problems.
After the controller is switched on, it first shows a welcome message on the display consisting of its name and version number. The menu becomes available 1 second later. Operation of the controller is self-explanatory, but an extensive User Guide is also available as a free download . You can scroll through the menu using rotary encoder ENC1. First you see the three options Run Program (where x is 1, 2 or 3) for running one of the defined programs. Select one of the three programs and press Enter (the pushbutton of ENC2). To return to the menu, press Back (the pushbutton of ENC3). The menu option Charge Battery selects monitored battery charging mode. First connect a 15-V battery charger, and then select this option. In this mode the relay is energized and shorts out resistor R1, so that more current can flow into the battery. The color LED strips are switched off to prevent potential damage from the higher than usual input voltage. When the battery voltage reaches 13.8 V, the relay is released. This reduces the battery charging current to the trickle charge level, and the color LEDs are switched on again. The Battery Charge option shows the charge level of the battery in steps of 10%. The value is determined by measuring the battery voltage and expressing it as a percentage, where 0% corresponds to 0% and 13.8 V corresponds to 100%. LED D5 indicates the charge state of the battery. The LED is lit constantly when the battery is fully charged (13.2 V). When the battery starts to get low, it blinks for one second with a duty cycle that depends on the remaining battery charge. If the battery is nearly empty, the LED lights up very briefly. When the battery is so low that the color LEDs must be switched off, the buzzer start beeping.
Switch S2 provides a Child Lock function. When it is closed, the Edit Program and Edit menu options are not available. To adjust a color setting, select Edit , press Enter, and use the rotary encoders to set the red, green and blue levels over the range of 0 to 100%, in steps of 1%. Press Enter to save the new settings, or press Back to return to the menu without saving the new settings. To configure a program, first select Edit Program and then press Enter. Then use rotary encoder ENC1 to select the color, rotary encoder ENC2 to set the Hold time, and rotary encoder ENC3 to set the transition time.
Internet Links www.elektor.com/110553  www.elektor.com/110406