RGB LED controller

Post date: Jan 13, 2017 7:17:12 PM

Residential accent light

Here is a holidays 2016 project. I concluded that market lacks a practical budget LED controller. Numerous market propositions for an RGB LED controller have been analyzed. A couple of controllers have been purchased and tested. They left to wish more. My two killer apps would be: a) colored light with automatic daytime or night accents, b) light control via conventional wall-mounted light switches. A long story ended up with the maxim "if you want to do it right, then DIY."

My final LED controller design makes following features available:

1. light with chosen color and light intensity

1.1 color selection via rolling rainbow (two-color cycle and 2 variants for three-color cycles)

1.2 rolling intensity selection (luminosity range 90 - 2500 mcd/LED)

2. push-button instant white light

3. day/night mode (automatically controlled by a build-in clock)

4. direct LED strip application for up to 100W

Controller architecture

    1. user interface unit: one power on/off switch, one function switch, one reset button.

    2. control unit: AVR uC ATtiny85 packaged as a Digispark, DS3231 timer packaged as an Arduino shield.

    3. light unit: light emitter RGB SMD5050 packaged as a common-anode RGB LED strip, and 3 channels PWM power driver.


The strip has 60 LEDs per meter, totaling 14W power consumption per meter if all LEDs are fully loaded. The proposed circuit allows up to 36W per channel, 100W total power on passive cooling. The controller would be enough for up to 7 meters LED strip. More demanding installations should deploy LED amplifiers. Alternatively the MOSFET power drivers IRLR2904 could be actively cooled to increase load or they can be replaced by devices with better characteristics.

The micro-controller ATtiney can be found in many RGB LED controllers. It is cheap and easy to use. The Digispark board adds upon a simple programming interface via USB. It utilizes Arduino IDE (Here v1.6.7 with Digispark add-ons). The issues with ATtiney:

A) the number and functionality of its pins is limited. If one wants to modulate 3 LED channels, and deploy 1-wire interface (I2C occupies actually two pins), and do use a push-button UI, then at least 6 universal pins are required. There are exactly 6 pins available. There is no universality of the pins in ATtiny85. Some of the Digispark pins have already dedicated functions. So at the end the engineering task is complex, but solvable. The resolution comes with pins multi-functionality. Both hardware and software had to be stretched and will probably require a tuning.

In particular, the hardware sets various logical levels for different functions on the same pins. So the values of the soldered elements have to be strictly followed. For the majority of replicas it would be enough. Though, depending on the quality of your power supply unit and on the dynamic range of your load (in practical terms it would be the total length of attached LED strips), the PSU output voltage may deviate from nominal value and the logical levels may significantly fluctuate while light intensity changes. Then the pull-down resistors may require an adjustment. And the code should associate user commands with more appropriate voltage levels.

Here is a realization on a 2x8cm breadboard. From left to right: the timer shield, a Digispark clone, the row of 3 power drivers, a reset button. Red and blue drivers have passive radiators applied. The timer battery CS2032 is recommended to replace with a rechargeable LIR2032. The shield has appropriate circuit to recharge it. It is useful to increase service period for the device. With CS2032 the service period is 8 years.

final board
back side of the board

B) ROM is limited. The software deploys additional code to distinguish multiple functions on the pins. Various functionality at different pins also requires libraries, which take a lot of ROM. The space in Digispark compared to bare ATtiny85 is additionally reduced by micronucleus. The remaining 6kB is meager. The productive method was to strip down libraries to the essentials. Therefore some library snippets are transferred into the sketch. Such libraries are excluded for the declaration list.

Following libraries helped to realize the project:

    1. VirtualWire - handles interrupt for software PWM on all 3 channels. Three hardware PWM on pins 1,3,4 is hard to apply in Digispark since timer1 is in use by micronucleus. The commonly available hardware PWM code doesn't work. The VW library takes approx. 11% of Digispark memmory. The project uses only two external functions from the library. Clipping it reduces ROM usage by 8%.

    2. TinySoftPwm - handles pulse wide modulation. PWM manipulates amount of light emitted by red, green and blue components, which mix to produce distinct colors.

    3. avr/eeprom - stores settings in energy independent memory. It eliminates the common LED controller misconception - forgetting settings after power-off. The forgetting makes many controllers unusable in simple residential applications. The library can be excluded from the sketch to save about 11% ROM. EEPROM operations can be handled by TinyWire library if you utilize EEPROM bank in the DS3231 instead of internal ATtiny bank.

    4. TinyWireM - communication via I2C bus, where uC works as master. It enables to use DS3231 timer (I2C slave). The timer is a precision clock with thermal compensation. It is energy independent and runs while LED controller is powered off.

    5. TinyRTClib - reads timer registers and sets clock. The library takes much space while only three external functions are required. Clipping them reduces ROM usage by 6%.

The sketch code is available in the files repository below. Its comments are fair to understand and improve the code for a solid Arduino software developer.

The sketch has a commented line in the function setup(). The line initializes the clock module at its first deployment. The sketch has to be uploaded to the micro-controller for the first time after PCB assembly is finished. I this case the line has to be uncommented with time parameters set correctly. The sketch would be uploaded and immediately run once. After that the sketch has to be uploaded once again with the line commented out. Since the Digispark ROM utilization by the sketch is 99%, uncommenting the line writing to the timer requires commenting out another instruction. The line that reads values from timer would fit the task.

An operational controller

It should be installed in a serviceable box. It should be attached to:

    1. an appropriately powered 12V PSU,

    2. a LED strip, and

    3. a wall-mounted two latch switch.

An additional wall-mounted switch can be applied as a general power on/off, to cut PSU off AC supply. In this case a micronucleus update is required to eliminate 5 sec boot-loader delay. Digispark enters programming mode for 5 sec after reset button is pushed with micronucleus-1.11-entry-ext-reset-upgrade.hex. Accented light starts immediately after general power switch is turned on.

RGB controller installation example

The typical use cases are depicted below. By default the controller drives RGB strip into color accent after it's switched on. A straight white color can be seen at the same intensity level as accent, if the control button is clicked on and off. The controller starts with accented light again after power off. More functions could be read from the control diagram in the attachment.

user scenarios

Bonus idea

At the end I've opened up a couple of commercially sold controllers. It seems, they do indeed utilize AVR uC. At least they have the 8 pin controllers. The available in the controllers LED PWM drivers a fully functional. Soldering a DIP8 IC socket on such commercial PCB may allow construction of the better controller with minimal soldering and in a decent housing.