Driver for Cheap LED Christmas Lights
by arpruss in Living > Christmas
21 Views, 0 Favorites, 0 Comments
Driver for Cheap LED Christmas Lights
On Amazon, there are lots of LED Christmas lights that are USB or battery powered and have eight different lighting functions. The last of these functions is the steady-on function which is what we actually wanted for our Christmas tree. This means that each time we turned on the strand of lights, we would have to press the function button eight times. And I wanted three strands for the tree, so that would be 24 button presses! Moreover, the lights turn off automatically after six hours, which really doesn't for indoor use where we want the Christmas tree lights on all day. I saw that there are some newer models that remember which function you chose, but you still have to reactivate them after six hours.
What an annoying user interface! We would have been happy with simple lights you plug in and which stay on, glowing steadily, until you unplug them. Of course, there are standard AC-powered Christmas lights, either LED or incandescent. But they run AC through the light wires, and our cat was chewing on the wires, and we didn't want her to get electrocuted. So USB or battery was the way to go. And as far as I can tell, for 5V lights they all come with the six hour timer.
I ended up making a custom controller with an Arduino-compatible microcontroller and a DRV8833 motor driver board. I used an stm32f103c8t6 blue pill as I have a lot of them in my parts collection, but you can use pretty much any Arduino-compatible controller, either 3.3V or 5V. The initial version of the controller just ran the lights in steady mode all the time. So the user interface was: unplug for the night and plug in in the morning. But pretty quickly I decided to get a little fancier. So I added a button. The first night of installation, one pushes the button when going to bed. The controller now remembers the time, turns off the lights for seven hours, turns them back on, and repeats the cycle every 24 hours. Pressing the button once when the lights are off, or unplugging the lights, clears the cycle and goes back to always-on mode.
Since the DRV8833 is rated up to 1.5A, and each set of 100 lights draws 70mA in steady mode with the stock controller, one can have one controller run several strands. I ended up running three strands from mine.
Supplies
- Arduino-compatible microcontroller, either 3.3V or 5V (I used stm32f103c8t6, but Uno, Mega, Micro, PI Pico should all work)
- DRV8833 board
- (optional) pushbutton
The Original Controller and Replacement Design
The first picture is the original controller taken apart, with the battery holder replaced by a USB cord (my first set of improvements).
Playing around with a volt meter and oscilloscope revealed:
- The LEDs are all in parallel or anti-parallel.
- The warm colors (yellow and red) are in parallel with one polarity and the cool colors (blue and green) are in parallel with the opposite polarity.
- For steady lighting, the controller runs a 100 Hz square wave from -2.8V to +2.8V to the lights between the two pins I labeled "Light". On positive, one half of the lights turn on and on negative the other half do.
- The controller does this by connecting the two sides of the LED ladder to two pins: when one pin is positive, the other is ground, and vice versa.
- For fancier modes, the relative duty cycles of the positive and negative parts of the wave are varied.
- The controller running a strand of 100 lights in steady mode draws only 70 mA (including the controller current).
So, a simple controller just needs to generate a 100 Hz full square wave going from minus to plus. One could do this with a microcontroller and some transistors, but I think they'd have to be PNPs and I only had one of those in my parts collection. One could doubtless do it with a 555 and some transistors, too. But what I did have is a lot of microcontrollers and one DRV8833 board not in current use. The DRV8833 boards are normally used to drive a DC motor, and because they can drive it in both directions, they can reverse polarity nicely.
To reduce flicker, too, one might as well up the frequency, since that costs nothing. I ended up going with 1000 Hz.
Design and Connection
I am running the DRV8833 on the microcontroller's 5V power supply to generate a wave going from -5V to +5V (currently at 1000Hz), with a portion of the cycle at zero, using three 100 LED strands. The DRV8833 limits current to 1.5A, so with three strands of 100 LEDs, and 50 of them on at one time, each LED should average to at most 10mA, and only for 30% of the cycle. (I don't know the current ratings on these LEDs). In any case, I measured and the whole project draws only about 300 mA, so each LED is getting on average 2 mA, and we should be fine (though, granted, some probably draw more than others).
Take apart the LED controller and desolder the light strands. The DRV8833 has two input pairs and two output pairs of pins. The pinout is here. Connect:
- DRV8833 VCC to microcontroller 5V supply
- DRV8833 ground to microcontroller ground
- one pair of DRV8833 input pins (either IN1/IN2 or IN3/IN4) to any pair of digital pins on your microcontroller
- the corresponding pair of DRV8833 output pins to the two light strands
- (optional) ground to one end of a push button (e.g., a tact switch) and a microcontroller input pin to the other (depending on how you mount it, you may need to line up the project box first).
I have successfully hooked up three light strands to the same pair of DRV8833 output pins.
Using my blue pill and a strip board for the project, I put the DRV8833 and the blue pill side by side in such a way that IN3 and IN4 lined up with B8 and B7, respectively, and VCC lined up with 5V. I then used a tiny jumper to bridge the two grounds. I used A1 for the tact switch. And of course I deeply cut all the unnecessary connections on the stripboard with box cutters (in doing so, I also cut the VCC and 5V connection accidentally, so I bridged that with solder).
Check for shorts and double-check connections.
Software
Get my Arduino sketch from here. Change drv1 and drv2 to be the two pins you connected on the microcontroller to the DRV8833 inputs. Change buttonPin to be the pin you want.
You can adjust the duty cycle for each LED in the dutyCycle line to be anywhere between 2 and 50, inclusive. I wouldn't do 50, as the +5V square wave would drive the LEDs with an average of 2.5V, which is a bit too high. I settled on 30, for a balance between brightness and the DRV8833 chip getting hot. You can up the frequency (I tested up to 10kHz) if you like.
If you want to change the timer-off time, you can change offTimeHours to something other than my 7 hours.
My Box
Normally, my project boxes are 3D printed or lasercut, but I was in a hurry, and I had a nice plastic box from screws. I drilled some ventilation holes, as well as holes for a USB cable and for the LED strands. I printed some standoffs for the board, and mounted everything, and protected the LED strand connections with a glue gun. Doesn't look super professional, but it works fine.