My first attempt at an LED Aquarium Light V1 started as an excuse to buy some of those LED light strips off of eBay. I gutted the old 18″ fluorescent fixtures and soldered together row after row of 18″ RGB LED strips. They mounted to a thin aluminum plate I screwed into the old light housings Aquarium Light V1. I mounted one of those remote-controlled RGB LED controllers in there with a 12V 5A power brick. The remote control let us change the colors, and had a few blinky light modes that I’m sure the fish didn’t appreciate too much. My wife loved it, which is all that really matters.
I wasn’t happy with the overall build – the fixture was fairly hot and the adhesive backing on the LED strips was worthless. I eventually had to encapsulate the LED strips with a sheet of polycarbonate on the front to keep them from falling off, which made everything even hotter. The project died one day when the combined heat of the LEDs and the power brick melted a big smelly hole right through the brick’s black plastic housing. I wasn’t home so I can’t say whether any flames were involved, but the polyurethane coating encapsulating the LEDs was browned in several places. We were pretty lucky nothing fell into the water and poisoned the fish.
At this point I was ready to drop $150 on some aquarium light from Amazon, but my wife loved the ambiance of the RGB LEDs so much she convinced me to make a better one. I coiled a white LED strip on top of the aquarium without a housing. It looked pretty bad but that way it wouldn’t get so hot and the fish wouldn’t be left in the dark while I figured things out.
I knew heat was my biggest enemy, yet I wanted to make something significantly brighter than the old LED strips could achieve. I read all about the intensity of light at sea level and what kind of lighting a planted aquarium might require. Eventually I decided to go with six 30W RGB LEDs, which I could find on eBay for about 12 dollars each. That’s a total of 180W of heat that the fixture would need to dissipate.
I spent a few weeks searching the internet for an appropriate housing. Eventually I found a website called gkphotonics.com which sells extruded aluminum project boxes of various shapes and lengths. The 4″ wide profile looked great and was the perfect size for my aquarium. It also had grooves on the inside which could hold a circuit board. I contacted the owner and he was able to make me a 48″ long piece anodized black. It took a few weeks, but it eventually arrived in good condition and for less than $100 including shipping.
To help dissipate the heat, I added a fan to one end of the extrusion. It pulls air in from the area where the LEDs are mounted and pushes the air through the extrusion and out of the other end. The opposite end cap was raised off the extrusion by a few millimeters to allow the air to escape. Small aluminum U-channels were screwed into the bottom edges to make space for the LEDs to mount underneath. I had to cut a few slots in them to avoid interference with the Aquarium’s hood pieces.
Driving the LEDs
I needed a power supply and driver circuits to power 18 LEDs at 300-350ma each. It also needed to power the cooling fan and the Arduino. The Green and Blue LEDs run at 32V nominal, while the Red LEDs run closer to 24V. Surfing around eBay I found 36V open frame power supplies with 10 A current rating could be purchased for around $35. I decided to go with a single 36V supply for everything. The first one that came was DOA, but I contacted the seller on eBay and they promptly sent a replacement which worked. The power supply would be external to the aluminum extrusion, mounting somewhere underneath the tank. Finding a power cord was not a problem, as I have a whole box of cords which have been harvested from broken appliances over many years.
I considered using series resistors to regulate the LED current, but that would only provide 3-4V drop across the Blue and Green LED resistors, which probably wouldn’t be enough to prevent thermal runaway. In my search for constant current regulators I came across a circuit which uses a MOSFET transistor as an LDO current regulator. To achieve current regulation, one current sense resistor and one NPN transistor are required. The MOSFET is normally held in an On state by a pullup resistor, allowing current to flow through the LED. As the current through the current sense resistor increases, the voltage at the base of the NPN transistor increases. At around 0.6V, the NPN transistor turns on and pulls the MOSFET gate voltage down to ground. This decreases the current flowing in the circuit, until the base of the NPN transistor is back to 0.6V. By selecting a current sense resistor of 1.8 ohms, the circuit will maintain 333ma of current. One benefit of using a MOSFET is that they typically can withstand 175C junction temperatures, whereas most standard LDO regulators can only handle 125C. By adding an extra PNP transistor between the MOSFET gate and ground, I could turn the circuit on and off with a micro-controller.
I still needed to use an LED series resistor in the circuit, since the MOSFET would burn itself up if it tried to absorb the entire 333 ma at 12V drop needed for the Red LED. I ordered one LED from eBay and played with it until I figured out what size of series resistors would be needed to minimize the dissipation within the MOSFET. The Blue and Green LEDs were so close that the same resistor value could be used, but the Red LED required a much higher value. The power dissipated in the Red LED series resistor would be nearly 4W at full power, so I decided to use 10W sandstone types for all of them.
I designed the two-sided circuit board in Eagle. One PCB would handle 6 LED channels, so a total of 3 PCBs would need to be made. I tried to leave as much copper as possible to aid with heat dissipation. I used the toner transfer method with lots of ironing to transfer the traces onto the copper clad board. The boards were etched in muriatic acid and hydrogen peroxide.
Connections to the LEDs were made using 4 conductor telephone wire with a bright yellow jacket. Since the LEDs mount on the outside, I potted the exposed LED tabs with epoxy after soldering the wires on to prevent shorts. I used screw terminals for all the high current connections at the PCB. Pin headers and 6 conductor Dupont cables connect the LED driver boards with the Arduino.
I started off using small SOT223 LDO regulators to step the 36V supply down to 12V to power the cooling fan, drive the MOSFET gates, and power the Arduino. After testing for a few minutes, groups of LEDs would shut off, and pretty soon the whole thing would stop working. I eventually figured out that I hadn’t sized the regulators to handle the load and they were going into thermal shut-down. I began looking at switching regulators and found the LM2576 datasheet. I ordered the switcher and a few caps and coils from Digikey and built the regulator on a piece of perf board. After installing the new regulator all of the thermal shutdown events went away.
By the time all of the boards were wired up to each other, there was quite a rats nest of wiring to deal with. I spent too much time twisting and bundling the wires together so they wouldn’t hang up on each other when sliding all the boards in. The Arduino was the last board to slide in, so that the USB port would be accessible from the outside for reprogramming. I desoldered the barrel jack from the Arduino to avoid making extra holes in the end plate.
Controlling the LEDs
While version 0 could only produce one color at a time, I wanted to be able to generate any kind of rainbow light show I could imagine, or even simulate the shadows of clouds passing by overhead. That meant I needed to control all 18 LED channels independently. I also wanted a potentiometer to control the overall brightness of the light, and a button so I could put it into different light modes. With the addition of an RTC, I could have a light that would automatically run different modes at different times of day, eliminating the noisy mechanical timer sitting in the cabinet below the tank. The blower fan which keeps everything cool was just a little bit too noisy at full speed, but I found that I could PWM its supply voltage at certain frequencies to control the speed and reduce the noise. I added a temperature sensor close to one of the LEDs so that I could turn up the fan speed if the LEDs became too hot.
By far the biggest challenge was figuring out how to PWM 18 channels. The Arduino Mega can support up to 16 channels of PWM, which wasn’t enough. I started playing around with bit-banging PWM signals to see if that might do the trick. I figured I wanted to keep at least 8 bit resolution, and I needed at least 120 Hz to 180 Hz to avoid any strobe effects when the fish swim around. After reading a lot about direct port access, I was able to put together some code that could bit-bang PWM 18 channels at around 200 Hz. Once everything was built and I began testing, I noticed that even 200 Hz wasn’t sufficient to prevent the air bubbles from looking like a strobe. I went all out timing every single line of code and optimizing everything until I had the PWM loop running at 1000 Hz while maintaining 256 steps. The result is fairly simple, but I tried dozens of different things before I was happy.
Bit-Banging 18 Channels at 1000 Hz