Home Hydroponic Control System

Hydroponic – 4 Months Later

It has been 4 of months since the Arduino-based hydroponic control system has been in operation and I’ve since harvested arugula and lettuce. I’ve added a couple of columns to to grow cherry tomatoes. For the most part it has been a good experience.








I’ve finally added EC and pH measurement from Atlas Scientific  and programmed it using I2C rather than serial. I also added voltage isolation between the probe and the rest of circuitry to reduce changes of noise interference.  Data collected is via modbus over xbee to my SCADA host as before. The updated wiring includes the two extra sensors as shown below.







The spike in measurement resulted from adding more nutrient and pH down to the nutrient tank. More about that later.





New Development Environment

Most noteworthy, I migrated to using PlatformIO as the dev environment given that it supports multiple boards, has a command line interface, integrates nicely with the Atom editor and github.


  1. Inconsistent distribution of flow. The drip lines where sitting at the top and some plants would not get enough water. Fix: added 2″ caps (orange in pic) ensuring proper alignment of drip line.
  2. Water leaking to the floor. I could have done a better job in making the holes to host the net pots. When harvested, I would have to keep an empty net pot to avoid dripping of water. Fix: Replaced with 2″ Wye. It holds a 2″ net pot nicely. I could not find white wyes that did not cost and arm and a leg. I opted for the black drainage type.  The photo shows a trial test.
  3. 3″ net pots to hold cherry tomatoes is throwaway. The holes where made into 4″ pipe and it caused all kinds of issues. Fix: Replace with TODO wyes.
  4. Drain pump. The one I bought is too slow and noisy. Fix: I use a wet vac to drain the water. It is a lot faster and helps with cleaning the tank.
  5. Level Sensor: The sensor got destroyed with the splashing of the nutrient mixture over time. Also, the readings on average were correct but I did not like the range in level during operation.  Fix: Removed and looking for different sensor.
  6. Topping off nutrients is ok a the start but after a while, I just want to system to take care of it all. One has to add it over a period of time rather than in one shot. Otherwise, spikes in pH/EC occur. Fix: purchased nutrient containers  and some peristaltic pumps. With some TODO driver circuitry and code, managing nutrients should be mostly automated.


The following plot represents nutrient temperature and growing chamber temperature. The nutrient temperature is on the low end of the range and I’m going to test to see if keeping the temperature around 21C (70F) impacts the growing cycle.





Next Steps

The fun stuff begins and it is machine vision. One to assess how well photosynthesis is occurring and the other is to measure growth.

Arduino based Plant LED Lighting – Iteration 1

After years of procrastination, the itch to get into hydroponics needed attention. Before jumping headfirst into the unknown, a quick experiment to see how the plants responded to neopixel LED strips was in order. As such, I’ve put the MEAN stack exploration on hold.


Can the neopixel LED strips provide enough lighting to grow herbs and other leafy vegetables?

Materials Used

Putting it Together

The following diagram illustrates the wiring.  The LM35 when used with other analog inputs leads to erratic readings. The capacitor stabilizes things.

The software is straight forward with the xbee operating using AT mode rather than API mode.  For now, I used modbus to communicate to Mango and for giggles VT-Scada. More on that in a future post as the IIoT speak I hear from certain vendors — not the two mentioned–make me cringe knowing what they have under the hood.

Software Feature List

  • set time from host via modbus  or terminal console
  • set lights on time via modbus or terminal console (default 18 hrs on)
  • set lights off time via modbus or terminal console (default 6 hrs off)
  • set duty cycle via modbus or terminal console
  • set duty cycle period via via modbus or terminal console
  • get temperature via via modbus or terminal console
  • get soil moisture via via modbus or terminal console
  • force the lights on or off via modbus or terminal console
  • save/load/restores settings to/from EEPROM

Modbus was used as I already had a SCADA host running. It could have been xbee API or bluetooth. Having done both, this is relatively easy to refactor the code later.

The code can be found at https://github.com/chrapchp/PlantLEDLighting. Not the prettiest code yet it it does the job for this experiment.

Periodically changing the red/blue ratio aka duty cycle between 70-95% red with the remaining in blue light tainted the experiment. Regardless, it is logged in the SCADA/HMI host for further analysis.  Interestingly, the research around  LED-based plant lighting is growing along with plenty of do-it-yourselfers experimenting.

Lessons Learned

On the Mega front, the Chinese knock-off ended up with causing more trouble that they’re worth. Problems included the following:

  •  voltage regulator fried
  • TX1 via the header pin did not work
  • headers were loose
  • finding a driver took extra goggling

Needless to say,  I ended up purchasing the real one.

Wiring xbees on breadboards gets old fast. The current setup consists of switches to commission/reset and  a potentiometer to vary the input voltage for testing a device. Nevertheless, I  purchased the wireless connectivity kit  (S2C) and the pro version of the xbee  to facilitate the configuration and program some custom functionality in the xbee in the future. Highly recommended if xbee development is on the radar. BTW, digikey Canadian or US site offer great service and fast delivery. I’ve ordered from them several times.



The basil and oregano took a couple of weeks to germinate followed with a slow growth rate.  In contrast to what others are doing, the growth rate falls far short with expectation.

Leafy Vegetables

The kale and arugula germinated in 3 days and grew relatively fast. The weak stems could be attributed to the LED’s . I’ve planted some outside as well and will compare the stem sizes with the indoor ones.

Minor Changes

The addition of a fan to create a light  breeze led to stronger stems. After a couple of weeks of circulation, the arugula and kale stems seemed stronger. The basil grew and looked healthy yet remained small. When compared to their outdoor counterparts, the healthier looking indoor basil prevailed.

Next Steps

There seems to be some confusion out there between lumens and pars. I read about people only measuring lumens for plants and scratch my head.  Consequently,  I like ChilLED‘s pitch in positioning their lighting products as well an intro-101 from Lush Lighting.

Incidentally, a buzz exists stating the effects of UV could lead  to ‘certain’ plants to produce more THC. Note, I am not interested growing those plants and just want to grow edibles all year round.  At any rate,  I think the root cause revolves around the low LED pars and power rather than the effects of different soil, nutrients, and seeds.

In short, I’m considering using ChilLED for sourcing my lighting needs provided that  controlling the output of the various channels without using their controller remains feasible.  Note  growmay5 provides some interesting vlogs on this as well as other topics around LED plant lighting.

Altogether, I’m satisfied with experiment and how quickly I could mash up a solution. Hydroponics is the next step with better LED lighting and queued for later this year as a project.



Temporary setup


Slapped together hardware



Host Software

Rather than re-invent the wheel, I thought there should be software out there that provides SCADA/HMI functionality for free. It is a commoditized activity by now.  After combing the web, I stumbled and settled on Mango, an open-source M2M solution. Mango is Java based that integrates with MySQL and runs under Apache. All good stuff so far.  The web site describes the features and how to install the software.  I liked the data historian, alarms, and the various types data points including calling external web based sources. I set one to get the external temperature at the airport and using regex to scrape of the temperature form the HTML. All within Mango.

I found it relatively easy to get going. One thing I had to do was write a Modbus function 6 (write a single register) for the Arduino in C as I want to send commands to the arduino. i.e. set the time for example.

The diagram below shows some of the points I configured to handle the home energy monitoring. I used ISA motivated nomenclature to name the tags. I may revert to a human readable tags as I won’t have hundreds of points and becomes cryptic after a while.


Data logging for each data point is configurable as shown in the screen shot below. The example is for the temperature in the basement. All of this info is in the MySQL database from which one can chose to slice and dice the data later on using external tools.


As for graphical objects, one can create custom objects e.g. dials, meters, etc. and assign tags to them. When this is all done I will add an iPhone friendly UI to this so I can interact with the home energy system on the road. One thing that Mango does is allow me to work on my solution rather than re-inventing the wheel.  I know have the facility to hook up multiple ardduinos and focus on the fun stuff which is the embedded side of things.

Just XBee Left Wire

I finally got around to spend some time on this and got everything on a perfboard . I also included a temperature sensor (LM35) along with a button to select the LCD display mode.  If I had to change one thing, I would chose different connectors so I can disconnect the current and voltage sensing wiring without screwing on a terminal block. I removed the CT and voltage wiring to the terminal block in the picture.


Given that I will be working with two current transformers any open circuit can be lethal. I will  add a switch that short circuits the secondary before I disconnect from the terminal blocks. The last piece to connect will be a XBee chip to send the data to the master. As stated early, I am using Modbus over serial as the protocol to communicate with the host.

One thing that did give me grief is that the temperature reading was erratic under certain scenarios.  I sampled the currents and voltage to get 2000 samples do some computations and then take a sample of the ambient temperature. If I did not perform the 2000 sample burst, I got a stable temperature reading. If I looped for sample 2000 readings then took a temperature, the temperature would be erratic.  I still don’t know why and my hunch is that it lies in the A/D mux in the Arduino.  What I did was take average 10 temperature readings with a delay of 20 ms between sample which led to a more stable temperature reading.

All that is left is to mount an XBee chip on the bread board and the hardware should be ready to stuff into an enclosure.

Host Communication


Well I got around to dabbling with how to best communicate with a host to implement a data historian. I started writing a extremely dumbed down protocol inspired by Modbus  After a day I realized that why settle for less and figured that pure Modbus would be better.  I could then use Modbus master software to query my Arduinos.  I found a Modbus C code for the arduino to provide RTU slave functionality over serial line. I loaded the sketch and downloaded a Modbus tool to read some values from the arduino to see if it all worked. There is only support for Modbus function 3 and function 16 in the arduino implementation and I added code to handle function 6. If you know enough C it is rather straightforward.

Java Host

Now that connectivity using Modbus was feasible, I wanted to ensure that I could implement a data historian with open source tools and decided that Java was the way to go.  After all Apache Tomcat, mySQL, and the eclipse dev environment are free and just require wetware to use. I also wanted to have my own arduinoController to collect the energy information that abstracted the details of Modbus.  After combing the net, I quickly realized that there was no reference implementation from Sun or whatever they are called now for Win32 serial data com. I will use Linux later  host it all later, but wanted a platform independent solution.  I found RXTX as a potentially viable implementation and free! Now all I need is a Java implementation of a Modbus not surpisingly, that exists too at jamod.

What I hate is screen painting and UI work can be a  pain. I wanted a simple java application to test read/write of registers and display them in float, long, int, unsigned int, binary, and hex formats. It would be a way for me to understand the details further and I would not have to deal feel guilty using commercial software as a trial offer.  I digressed in my focus and looked for a tool that would allow me to create UI with minimal effort. I found JformDesigner to be flawless and will probably purchase it.  It installed in Eclipse without a glitch and a Luddite like me was productive in a matter of hours. Anyway after a couple of days, I had the RXTX source compiled and my arduinoController source integrated to provide a simple test tool for me to experiment with. The screen shot is shown below. The challenging part was how to display longs and floats as Modbus does not support floats and longs per say and is something one does at the application layer (for you OSI compliant people)

modbus tool

Representing Float

For those that are interested, to get implement a float from a Modbus register representation, one just has to do this

Arduino Side

It takes two registers ( 16 bytes in total to represent the float). One may ask how does one mash a float into ints on the arduino side? I used the union

int regsf[2];
float value;
} mashedFloat;

I used it as holding area to mash my floats into to registers.

e.g.  mashedFloat.value = powerfactor

regs[0] = mashedFloat.regsf[0];
regs[1] =

Java Side

The data flows over standard Modbus to the host and on the Java side do something like this to unmash into a float.

float x = Float.intBitsToFloat( (mRegisters[i+1].toShort() & 0xffff) << 16 | (mRegisters[ i].toShort() & 0xffff) );

Modbus Registers

I captured how I will represent my power metrics from the main panel and send over Modbus. Rather than waste 2 registers for floats to represent something like 118.1 volts I will cast it into a single register as a 1181 and convert back on the host. The reason for this, on the Arduino Duemilanove, there is only 2k of RAM and I created my power calcs using classes and that is not cheap on memory.  I plan on taking the Modbus code I found on the web and make it class as well.  I will have other arduino’s in the house collecting spot power measurements and must ensure that I can upgrade code (read fix bugs)  in a consistent manner.

Tag Line Voltage Units Type R/W Offset
EI-011 Black Line Voltage Vrms short R 0
EIC-011 Black Line Voltage Crest Factor short R 1
CI-011 Black Line Current Irms short R 2
CIC-011 Black Line Current Crest Factor short R 3
CI-021 Red Line Current Irms short R 4
CIC-021 Red Line Current Crest Factor short R 5
KD-011 Black Delta T between Samples ms short R 6
KD-031 Red Delta T between Samples ms short R 7
TI-001 Local Temperature C short R 8
JI-011 Black Line Real Power Watt float R 9
JI-021 Red Line Real Power Watt float R 11
JIA-011 Black Line Aparrent Power VA float R 13
JIA-021 Red Line Aparrent Power VA float R 15
JIR-011 Black Line Reactive Power var float R 17
JIR-021 Red Line Reactive Power var float R 19
JIP-011 Black Line Reactive Power Factor float R 21
JIP-021 Red Line Power Power Factor float R 23
GC-001 Display Mode short W 30
GC-002 Number of samples per calculation short W 31
KC-001 Time sync (unix time) s long W 32

CO2 and kW*hr

On the arduino side, the CO2 produced and the kWatt*hr are accumulated over a 24 hour period and displayed on the LCD. I plan computing those on the host side rather than send over Modbus . I have all the raw data to do that and do statistical operations as well as part of the data historian. e.g. average CO2 per day, Standard Deviation, etc.