Sunday, November 25, 2018

Update for the LED strip driver

After testing the LED strip driver for a few weeks, I found some issues that need to be corrected. The first one is that due to mains hum / noise picked up by the LDR's long wire (I needed to put it closer to the window so it senses the light properly), the ADC value for the light intensity was a bit jumpy, even with all the averaging. This led to some flickering from time to time. Also the potentiometer was quite sensitive to changes, even small vibrations could make the intensity vary. To counter this, the intensity setting now has 11 steps (0 to 10) instead of 255, making it much easier to set.

So far the plants are doing fine
Another thing was that the controller oscillated quite a bit during the transition between the on  and off states. Since the light intensity outdoors changes very slowly during sunrise and sunset, the annoying on / off could last for minutes. This was fixed by increasing the hysteresis to a bigger value. Everything works perfectly now, the instability has completely vanished.

You can find the updated code at the link below (link updated in the old post as well):

Monday, October 22, 2018

A simple driver for LED strips

It's the middle of October and the weather is slowly getting colder and colder outside. I'm not too bothered by this because of the coming winter holiday season, but my plants don't seem to share the same fondness toward the changing weather. It would be a shame to leave them outside to freeze, so I was thinking to bring them inside the house. There is one issue though (besides the limited space) - they will see very little light so they might wither.

To solve this, I googled around a bit and found out that people use these "full spectrum" grow bulbs or LED strips which emit a red / blue light that the plants seem to love. In my case, the plants will sit on a metal rack (Arakit 4) so LED strips seem a better choice (not to mention they are less risky to work with because they run at 12V unlike the bulbs which run at mains voltage).

At ~ $7 USD delivered, this was quite a bargain

LEDs in 5050 footprint, each with current limiting resistor
I got one of these strips from e-bay for around $7 delivered which is really cheap. It's 5 meters in length and uses SMD leds, each LED with its own series resistor. The arrangement I opted for is 3 red leds to 1 blue.

3 red leds to 1 blue
After receiving the strip, I tested it with a switching supply (laptop power brick) which outputs 12V at maximum 5A. Without any current limiting mechanism (besides the built-in resistors), the LEDs draw about 4A and they are extremely bright (and are getting hot quickly). If they were to run during the night time at full brightness, not only they would be disturbing my sleep, but they'd probably have a short lifespan because of all the generated heat. Even if a beefy series resistor was added (bad idea because of wasted power), another inconvenience of running the strip directly with the power brick would be the need to turn the light off and on manually, each day.

A simple LED strip driver was needed in my case, one that could:
  • Automatically turn the LED strip on and off depending the light level in the room
  • Have adjustable trigger point and use PWM for output (which would make it more versatile and reduce wasted power)
  • Not get hot (heat = wasted power)
  • Use only cheap and easy to find parts
Considering all of the above conditions, I designed the following driver based on an ATTINY13 microcontroller.

LED strip driver schematic

Circuit description:

The whole driver is centered around an ATTINY13 MCU, a power N-channel MOSFET (IRF1010E) with low RDS(on) and a cheap LDR (a.k.a. photocell). The MCU has 4 ADC channels, 2 PWM channels, 64B of SRAM and 1 KB of flash memory, more than enough for the task at hand. The voltage is lowered for the MCU from 12V to 5V with the help of a 78L05 linear regulator. The inputs for the intensity (led brightness) and trigger point are made with 2 potentiometers acting as potential dividers and the light level is measured with a generic LDR. These inputs are read with the ADC in 10-bit mode then, depending on the potentiometers, a PWM square wave is outputted on the OC0A pin. The frequency is about 585 Hz.

Q1, Q2, D2 and R4 are used to translate the voltage level of the square wave from 5V to 12V because the main switching transistor, IRF1010E is a power MOSFET, not a logic level one. To make it turn ON completely and minimize the power wasted in it, its gate is driven at 10V. The pulse width (duty cycle) is set by the 'Intensity' potentiometer while the 'Trigger' potentiometer sets the light level at which the LEDs should be turned on.

To keep things simple, some corners were cut in the development:
  • There is no reverse polarity protection. Use barrel jacks to circumvent this.
  • There is no fuse on the PCB. A fuse should be added in series with the 12V input.
  • There is no ISP connector on the PCB. The MCU needs to be programmed externally (on a breadboard for example)

Code description

There is not much to the code. The 2 potentiometers and the LDR are configured as voltage dividers that are read by the ADC. To eliminate noise, 10 readings are averaged for each channel. When the light detected by the LDR is stronger than the trigger point, the MOSFET gate control pin PB0 is configured as normal port operation and is set high (because the logic is inverted due to the level translator circuit) thus Q3 (and the output) is off.

If the detected light is lower than the trigger point, PB0 is configured as PWM output and the duty cycle is set to the level of the Intensity potentiometer. Instability (oscillation between on-off states under certain lighting conditions) is reduced by employing a simple form of hysteresis.

The source code is written in C and can be compiled with avr-gcc. It expects the CKDIV8 fuse bit enabled (clock of 1.2 MHz). Source and HEX files can be downloaded from the end of the article.


I have put the circuit inside a plastic box. Q2 was mounted on a small heatsink, however due to the low internal resistance it didn't heat up at all when drawing up to 4A from the circuit. The heatsink would need to be bigger and adequate ventilation is to be provided if sourcing more than a few amps.

Everything inside a small plastic box. The LDR is soldered to a RCA jack.
A test showing the controller in action

The project files (source, binary HEX file, schematic and PCB) can be downloaded from the following link:


[Edit 25.11.2018]

Project updated, see here for more details: