A Guide to LED lighting for Plants

This post is meant as a rough guide to building your own high powered LED lights. These lights are fairly versatile, not too complicated and provide a reasonably cheap option for a number of different plant growing situations.

This guide will focus on a light fixture that has three strings of LED’s: Blue, Red and a combo of White. They will be on/off with no dimming available – but I am planning to write up a guide to dimmable LED’s shortly (I’m waiting on new LED drivers to be delivered.).

Once built, we can use these lights by adding a main switch and turning on all the LEDs, make a switch for each string of LEDs or hook all or individual strings up to a set of relays connected to a microcontroller like an arduino. In the next lighting guide, we’ll get into the wiring and code to connect the lighting fixture to an ESP32 for PWM (Pulse Width Modulation) dimming.

This project will require you to work with mains voltage – which is the power that comes from your home wall outlets. In North America, that is 110-120 V. This can kill or seriously harm you.

Being careful, triple check your work, use a functional multimeter, and not drinking BL Limes while working will save you a lot of pain. Please be careful.

What you will need:

  • 1,3 or 5w LED mounted on starboard aluminum heat sinks
    • I purchased 3w LED’s in 4500k (warm white), 6500k (Cool White), Deep Red, and Blue. I purchased them from AliExpress. 20 of each came to about $25 CAD.
  • 3 Constant Current Drivers of various forward voltages.
  • 22 AWG Hook-up wire
  • Thermal Paste
  • Nylon screws, nuts and rubber washers
  • Aluminum angle stock
  • Hacksaw
  • 1/2″ bolts + nuts
  • Soldering iron, solder and associated tools
  • Drill with bits for metal work

Concepts to know:

  1. Your LED’s should have a datasheet available somewhere. For me, I found it on the AliExpress page where I purchased the LED’s.
    Check the datasheet for two important numbers:

    1. The current requirements. It should be something like 600mA or 1000mA. This is the maximum amount of current that can be handled by the LED. The higher the number the brighter the light.
    2. The forward voltage. This is often expressed as something like 3.4vdc.
  2. Drivers are specialized power units that ‘drive’ the LED’s. When selecting a driver we need to balance our voltage needs with the current needs. Our LED’s want a constant current, so that means that the driver will be constantly compensating the voltage in order to supply a consistent current across an unspecified number of LEDs.
    1. We should look for a Constant Current driver with a current rating appropriate for our LEDs. My LED’s are rated for 700mA, so I purchased a driver that was good for up to 600mA, but 700mA would have worked.
    2. Secondly, the driver will have a max voltage rating. Let’s say the max voltage is 60Vdc – well, we don’t want to run it at full power because that’s unsafe, so let’s say 55vdc. Now we can divide 55vdc by the forward voltage of the individual LED, which for the warm white, cool white and blue LED’s is 3.4vdc: 55/3.4 = 16.18
    3. So we can have 16 LED’s running on one driver.
    4. The Red LED’s have a lower forward voltage, their vdc is 2.4, so we can again divide 55 by 2.4 for a total of 22.91, so 22 LEDs. This is why you need to check the datasheet of the LED’s.
  3. Running LEDs in series vs parallel.
    1. We are going to be running our LED’s in a series. This means that we feed the positive lead to the positive side of the LED, the negative side of the LED then goes to the positive contact of the next LED. The last negative contact of the last LED in the string will connect to the negative lead of the driver. It should make one big loop starting and ending at the driver.
  4. Heat Diffusion:
    1. LED’s are very efficient, but they will lose energy through heat. The extent to which they generate heat depends on a few factors, but regardless – you should figure out a way to dissipate the heat because this is a main reason why LED’s burn out or operate at low efficiencies.
    2. This is why we are going to use aluminum angle stock – aluminum is a good conductor of heat. We’re also going to use thermal paste to make a highly conductive bridge between the LED and the Aluminum.
    3. You can also buy aluminum or copper heat sinks that have numerous skinny tines to dissipate the heat more effectively but I found these prohibitively expensive and now, having built the fixture, realize they were unnecessary anyway. More LED’s, a tight fitting enclosure or other factors may necessitate a proper heat sink.
      1. I am however, constantly on the look-out now for scrap aluminum or copper that could be used as a heat sink.

Plant Science:

  • In the past, aquarists used watts per gallon to figure out their lighting needs. As technology has progressed, this has become more and more outdated and ineffective. For one, lighting has become more efficient, so 1 watt of light from an incandescent bulb literally pales in comparison to a watt of light from an LED. For two, wattage only tells how much power is running through the light – not what spectrum of light you are getting. An older incandescent bulb will burn warm yellow, while some florescents will appear clinical blue/white. Not only will the amount of visible light differ between these technologies, the light spectrum being outputted will also differ.

  • Many people now focus on PAR, which is an acronym for Photosynthetic Available Radiation – which means, how much light is available for plants to use in photosynthesis. You can purchase a PAR sensor, but they are very expensive. We can also use Lumens as a unit – lumens should be included on the LED datasheet.
  • Plants use light to photosynthesize energy to grow. For most of history, plants grew outside and under the sun. Our sun gives off a massive amount of light…obviously. It is full spectrum white light – which means, it is comprised of all of the colours of the visible light spectrum, but to various amounts. Plants use different parts of the light spectrum for different things and use some parts more than others. This also changes depending on species.
    • For instance – plants tend to use a lot of the blue and red parts of the spectrum. They use very little green – this is why a lot of foliage is perceived as green. Because the leaves don’t absorb much of the green spectrum, it is bounced back and absorbed by the cones in our eyes.
    • This is also why high tech indoor growing facilities often use fusia or pink-ish lights (a combination of blue and red spectrums). Since the cost of energy is such a big factor in indoor growing, they prioritize the light that has the most impact on plant grow and leave out parts of the spectrum that add little benefit.
  • In our light fixture, we’re going to use red and blue LED’s to make sure these spectrums are strongly present, while using warm white and cool white to round out the spectrum and provide something that doesn’t look like a grade 12 acid trip disco lounge.


New Fish

Long overdue update – the tank is going well, but there are a number of obstacles I’m currently trying to navigate.

The good news, finally purchased a pair of Apistogramma Caucatoides Double Reds. They are beautiful fish and I’m loving them so far.

The problems, in no particular order:

  • Covid-19 has really thrown a wrench into the tank – among other things.
  • I recently installed a Raspberry Pi running Node-Red and a Mosquitto MQTT broker. This acts as the main hub now. All of my esp8266 and esp32 boards communicate with Node-Red on the Pi. Fantastic system.
    • The problem is that there is something fishy going on – I am not sure if the Pi is overheating or if something is causing esp32 that run the lighting system to falter, but the automations stop after a day or so. Ordinarily, I would be home to trouble shoot, but with the pandemic still flared high, I am staying with my partner at her house and can’t be home to problem solve.
    • I am fairly certain the problem has something to do with the Micropython code I wrote. I’ve been learning more about try & except statements and it seems like this could be the culprit. Essentially, something in the program periodically throws an error which stalls the program.

  • A follow up problem to this issue with Node-Red umqtt automations is that it will fail with, obviously, the lights on or the lights off. So either the tank experiences 48 hours of blasting light or 48 hours of darkness. I’ve been stopping by my house every two days to check in (safely).
  • This, in turn, has kicked off some serious algae growth. Nothing too crazy yet, but without vigilant monitoring, I’m having trouble both understanding what is happening as well as well as fixing it.
  • As stated in previous posts, my naturally hard water is probably not making it any easier. I have added Indian Almond leaves, but I think CO2 is necessary. I purchased one of those cheap DIY baking soda/citric acid reactors, but it is not working very well. Depending on how the future shakes out with everything, I am seriously debating purchasing a proper regulator and pressurized co2 cylinder.
  • Also, due to Covid-19, I haven’t made it out to any pet stores recently to restock on food. The new cichlid don’t love the cheap flake food the guppies eat and I just ran out of frozen blood worms. I’ve been digging up earth worms for the Apistos, but I am not sure if they are big enough yet to go after earth worms.
  • I’ll be receiving a package of frozen food today, along with a few new aquatic plants (because why not) and some brine shrimp eggs. I’m going to try raising some baby brine shrimp and see how they do in terms of food for the Cichlids.

On another note, my lights are up and working. As of now, they are triggered by a MQTT message from Node-Red on the Pi. Its okay… but not cool enough, so I’ve order a pcb with 5 Meanwell LDD 700 PWM drivers. I’ll be using this to control the lights eventually. The advantage to this is that you can control the duty cycle on the LEDs with the drivers and thus the dimming/brightness of each LED string. So essentially, colour mixing with Red, Blue, Cool White and Warm White. I have to figure out what to do with the 5th driver.

I’ve written a code that can be triggered by MQTT and run transition fades from one duty cycle value to another. You would have to call these functions within the section listening for messages from the MQTT broker.

from machine import Pin, PWM import utime # This is still in BETA testing.  # The below light() function transtions between start value and stop values by increments as stated in the increase_X = variable.  # Still need to develop all of the various transitions and write the MQTT stuff.  r = PWM(Pin(16)) b = PWM(Pin(17)) ww = PWM(Pin(18))  cw = PWM(Pin(19)) def dark_sunrise():     red = 0     blue = 0     cool = 0     warm = 0     increase_r = 1     increase_b = 2     increase_cw = 3     increase_ww = 4          while True:         utime.sleep_ms(30)         while r.duty(red) != (1000):             if red > 300:                 print(str(r.duty()) + ' r.duty') # print() statements are for testing                 print(str(red) + ' red lights')                 break             else:                 print(str(r.duty()) + ' r.duty')                  print(str(red) + ' red lights')                  red += increase_r             break         while b.duty(blue) != (1000):             if blue > 300:                 print(str(b.duty()) + ' b.duty')                 print(str(blue) + ' blue lights')             else:                     print(str(b.duty()) + ' b.duty')                 print(str(blue) + ' blue lights')                 blue += increase_b             break         while cw.duty(cool) != (1000):             if cool > 300:                 print(str(cw.duty()) + ' cw.duty') # print() statements are for testing                 print(str(cool) + ' Cool White')                 break             else:                 print(str(cw.duty()) + ' cw.duty')                  print(str(cool) + ' Cool White')                  cool += increase_cw             break         while ww.duty(warm) != (1000):             if warm > 600:                 print(str(ww.duty()) + ' ww.duty') # print() statements are for testing                 print(str(warm) + ' Warm White')                 break             else:                 print(str(ww.duty()) + ' ww.duty')                  print(str(warm) + ' Warm White')                  warm += increase_ww             break         if red > 300 and blue > 300 and cool > 300 and warm > 600:             break

‘We are all broken, that’s how the light gets in.’ – Ernest Hemingway

New lights are in Titan Phase.

I’ve built a mostly working version of the networked high powered LED lights.

The Lights:

  • Three arrays of 3W LED’s.
  • There are an assortment of 25 or so white LED’s ranging from 4500-12000 kelvin
  • Eight Red at 660nm
  • Eight Blue at 445nm
  • Each array can be powered individually
  • Led’s mounted on aluminum one inch angle stock for heat dissipation.


  • ESP32 hooked up to 4 relay module
  • Programmed with micropython. Connects to a mqtt broker on a raspberry pi running Node-Red to schedule the lights (This might sound like overkill if you’re not home-automation adjacent like myself, but if you are at all interested in IoT stuff, running Node-Red on a Pi is a gamechanger and I wish I did this way earlier).

Obviously the lights are not yet ready for Phase SmokeShow, but they are a proof of concept, of sorts. I need to clean up the wiring and I need to replace the drivers. The drivers, though they seem to be working fine, are fairly cheap and I’d like to replace them with something more substantial. At that point, I’m hoping to have a better handle on dimming with constant current arrays and have the ESP32 handle that as well.

This is a photo of the setup with the old lights – primarily 5050smd led strips and a couple of NeoPixel 12” led’s off amazon. In hindsight, I see the folly of that setup now, but its been a cool process of learning not only about the mechanical/electrical aspect of light as well as the way that plants utilize light.

Here’s another shot of the new rig:

The comparison is a little unfair because of the way the camera on my phone calibrates automatically – but the difference is drastic.

I’ve noticed a few things in the two weeks or so I’ve been running this on a 12 hour light cycle.

  • There’s been an all round shift in plant growth. Not only in volume, but in character.
  • Almost all plants have more red in their stems. The Hygrophilia Stricta that I have growing above the surface in basically growing deep red/purple leaves. The stems of the Creeping Jenny have turned red, while their leaves have a very nice tender green colouring.
  • There is a small clustering ground cover plant that I unearthed from my garden. Outside it is often deep purple, but previously in the tank it had turned a healthy-ish green colour. It has now returned to its dark purple colouration.
  • My Morning Glories flowered almost immediately with the new lights. The leaves that are directly under one of the red LEDs is growing with these cool purple veins through the leaf structure.
  • The aquatic plants are reacting more slowly. I’m noticing some steady growth, but nothing spectacular. My thinking is that the plant growth is now most limited by my water quality/paramaters.  My water is fairly hard from the tap, and with the amount of volume the tank loses to evaporation… its causing problems, to say the least.
  • The Sagittaria Subulata seems to be enjoying the increased light.
  • There’s been an increase in Algae. Nothing dramatic, but I wouldn’t be surprised if I came home one day soon to some green water.

Micropython and new horizons.

I have almost no real programming experience. I am ‘okay’ with computers, but most of it was all high-level UI kind of stuff. When I decided to get into Arduino as a hobby, it was because I knew that there were open source options for all of the IoT stuff coming to market, but I had no idea how to engage or hack any of those products. It seemed to me that a Google Home couldn’t be that complicated – or that a smart light was essentially just a wifi enabled on/off switch, which should be similarly simple.

I wasn’t wrong, but I wasn’t exactly right. Figuring out something as easy as a wifi controlled relay leads you into this world of computer science, programming languages, hardware compatibility and github (which I knew of, but was fairly intimidated by). I don’t know if diving into this rabbit warren was a necessary step or something particular to my personality (I am often confused by things until I can begin to understand their context.), but dive in I have been.

Arduino is a language based on C and C++. The underlying structure of the language is widely used and the Arduino language was developed by a helpful and dedicated community of people. Because of its legacy as one of the first hobby accessible microcontrollers, there was a concentration of people developing the language. But there are two limitations that I have encountered.

  1.  Because Arduino is based on a more complicated low level language (C, C++), writing new libraries and such requires substantially more ability and know-how than the casual hobby-ist. Luckily, the number of people more talented than I writing these libraries and code provides a wealth of examples and templates.
  2. The arduino IDE where you write the code needs to compile everything and translate it before loading it on the board and running it. This means that your workflow goes like this – code > compile > upload > run > error/unitended things > back to code > compile > upload > run > error/unitended things > back to code > compile > upload > run > etc etc. This means that it is difficult to quickly test and problem solve issues in your code, it also means that you spend a significant amount of time waiting to compile and upload code only to discover you made a typo somewhere.

This is where Micropython comes in. I came across micropython while experimenting with the ESP32 from Espresif. What an amazing little chip! I learned that Micropython is an implementation of Python 3 that was designed for the specific hardware constraints of microcontrollers.

Python and in this micropython has this wonderful little thing called a REPL. It allows you to pass code to the chip in real time and test out a section.like this:

>>> print(‘I am writing this in the REPL’)
I am writing this is the REPL

Python really is an elegant language. Very intuitive. The visual syntax of it is very clear and easy to read. For someone without much experience programming, it has an easily graspable internal logic.

The problem is that although its quite beautiful, it is far less common than Arduino and the number of libraries is far smaller. Now, you can leverage the huge python community for help, but there is going to be some stuff that doesn’t line up in the transition between a Python 3 and Micropython. Add to this the large number of hardware specific (relative to the size of the language) that have been made for various hardware… pyboard, circuitpython, microbit etc.

So, in a sense I am extremely excited by this new direction while also cautious … I think this will make me better at coding, but it might slow down the riparia project a bit.

So far I’ve written a few rudimentary scripts – a water level sensor that triggers a pump to top off the tank, a rudimentary light timer and a very basic thermostat/incubator for a horticultural project. All are just practice and proof of concept kind of things, but its exciting.

As always, the next big step (aside from adding more complexity to the operations) will be linking them to the net and getting wifi control, IFTTT hooks and wifi data-logging.

I really want micropython to surge, but also wondering if it makes more sense to run Python on a Pi Zero or something else.

A short synopsis of a round about plan / chasing waterfalls.

Just to catch up:
Been kind of absent lately. I had a little trouble with my server – I think they’re kind of skeezy and running a racket, anyway – I had to jump through all these hoops to appease them and I didn’t want to do too much here as the possibility of having to start from scratch if I couldn’t figure out my server issues was a real scenario. Then all the holiday stuff and short art school retreat/vacation etc – anyway, we’re back.

What I want to do in this post is just outline a couple aspects of this project and where they stand in terms of progress, change of direction, new ideas etc. Like a kind of a train-of-thought working list.

  1. Operation DEAL BREAKER: Deal Breaker is the name of the arduino set-up and program files I wrote to monitor aspects of the Paludarium. My original plan was to build the entire thing and then add wifi connectivity to the project with the assumption that adding this functionality would be as easy as adding a new sensor or switch ( I didn’t think that it was that easy, but it was definitely humbling to realize that despite Arduino’s impressive modularity, this wasn’t really included – or at least the way I had thought about it).

    After trying for a while to add an ESP8266 chip to my MEGA2560, I eventually came to the point that it wasn’t possible the way I had thought.  After posting a few questions on Reddit, I purchased a Lolin32 ESP32 dev board for 16.50CAD from Amazon and decided that I would slowly start migrating the project over to this board. It has something along the lines of 36 GPIO pins, so not quite as expansive as the Mega, but because they can operate in a mesh network, I could theoretically split the project up and just have different aspects of it communicate.

    The other twist in this part of the project is that I’ve decided recently to begin the process of learning Python, and while doing so I am also going to practice Micro Python (a version of python designed specifically for use on Microcontrollers). So, while I am going to leave the main ‘brain’ of the tank controller intact as is (and in Arduino code), I am going to start trying to write new aspects of the project in Micropython and designed to be IoT capable.

  2. This leads me to the second big change. Lights!
    Hopefully in the next week I will be posting a build guide to making a high powered DIY LED lighting system. It will be made using 5 colours of 3W LEDs mounted on an aluminum frame and controlled by the ESP32 with Micropython. So far, I think the supplies have run me about $140 or so.
  3. Website: So I was really enjoying this blog. I know that I stopped writing for a little while, but as I explained above, I had some shit to do and a couple haters standing in my righteous path. Anyway – one thing I was experimenting with was replacing this blog with a ‘personal’ wiki instead.

    My thought was that I could use it much more thoroughly as a research and development repository as well as an archive. Things like data sheets for specific parts, coding examples and other resources could be catalogued for future use and what not. I also like the very low key and austere graphics of the wiki format. Its like the internet from 1997.

  4. DIY-ish Co2 is in.
    The only problem is that it doesn’t really work. I am doing something wrong, I know that much. It keeps working through the solutions much too fast – like the longest I’ve got it to work for is roughly 20 hours – and barely that.
    I don’t really understand the mechanics of the device yet, so its hard to tweak it as I can’t identify the variables at play. I’m kind of being lazy about it, but I’m hoping I can get it up and running shortly. If not, I’ll have to start looking at getting a something a little more conventional – like a paintball gun co2 setup.
  5. Motorized Valves.
    I am still very much pursuing this, but will be slow walking the entire thing. Like most things that I start, I stupidly have to teach myself a bunch of new stuff in order to do the project, so this has to be a lower priority for now. But, I have been actively trying to find cheap Stepper Motors on Bunz and Aliexpress. I’m also going to start figuring out how to use the 3D printing labs that the Toronto Public Library offer. Eventually, this project will be implemented, but it just doesn’t make sense to drop a bunch of work that contributes to the core functionality of the project to focus on this (admittedly super awesome) aspect of the automation.
  6. A good example of something that I don’t want to drop to pursue some super sexy motorized valves is the automated refill system. This wasn’t super high on my priorities list, but then I went away for a week and was absolutely wracked by fear of my water levels. There are like three problems here: 1) The heaters are all in the sump, so if the water drops too low and can’t complete the plumbing loop, the paludarium temp will start dropping and fish, plants & bacteria might die. 2) The motor might burn out 3) The motor makes a lot of noise (which is annoying for my housemates) when the water drops below the threshold.

    My idea is to install a soil moisture sensor into the reservoir/pump chamber of the sump and basically program it as a yes/no switch. I believe these sensors measure the capacitance of the medium they are in, so if they are completely out of the water, I should be able to trigger a pump from backup reservoir to turn on for say 20 seconds or something. The second stage of this is adding a second capacitance sensor near the rim of the sump that either stops the pump or begins to close the outflow valves to avoid a flood.

  7. I will also be order 2 sheets of PolyCarbonate plastic soon to cover the paludarium display tank. I got them priced out and I think its about 60 bucks for both sheets (my tank has a brace in it..) Hoping this addresses the insane amount of evaporation, mitigates the noise from the moving water, and makes it easier to bring down the pH (if I don’t have refill the tank as frequently, I can more easily use distill water to do it and combat the accumulation of hard water agents.)

Project Seal Laker (Level Midnight)

This is the newest project in the building to do list. With two motor actuated valves controlling the sump filter intake and and outflow pipes connected to  dealBreaker would be game changing.

Not only could you map the open/close ratio to a pair of potentiometers for manual control on both valves, you could also have the valves automatically calibrating based on something like a water level sensor located in the pump compartment of the sump. Or, perhaps the rate of flow changes through out the day with times of higher flow and turbulence followed by lower flow at night when a quieter tank is more desirable. The valves could also simulate rising and falling water levels – which would be handy for occasionally flushing out low lying areas of the shore.

Make no mistake, the Threat Level is Midnight.

Aliexpress is amazing.

I just received these powerful little LED’s. They are 5 watts each and run at about 1500mA each. I’ve hooked one up just to see it in action and it was blinding.

LG 3535 LED
-Power: 5w
– Color: White
-LED brand: LG(from South Korea)
-Luminous flux: 533 lm (IF Curren:1500mA )
-Conditional current:350-1500mA
-Forward voltage: 2.8-3.6V
-View angle:115 degree
-Working temperature:-20–70celsius degree

My plan it to hook up 8 of these LEDs over the tank for about 3500-4000 Lumens.

These LED’s go for about 11$ each at my favourite local electronics shop – I love this store and will continue to shop there (I bought my arduino Mega 2560 there) – but I got 10 of these little starboard LED’s for $6.03 Canadian, which included shipping and they arrived in about a month. I also purchased an LED driver for them, which cost about 9 dollars all in.

PS: I took this photo with a super old tablet that I’m using in lieu of my phone (which I lost on a bus coming home from an aquarium store). I figure the Renoir painting kind of compliments the blurry photo of the LEDs.