Automatic Control of Nutrient and pH

A day after installing the hardware and upgrading the firmware to control the pH and EC using an Arduino, the results are as expected-the steady state trends just above the setpoint.

Keeping the pH and EC to a desired set point uses a simple on/off approach. The use of a a PID controller was briefly considered and in the spirit of the minimum viable product, I opted for something simple for now.

Armed with three peristaltic pumps and another on way, some scrap wood, and additional code, a functional setup connected to the Arduino based control panel led to the following setup.

Nutrient Controller

Nutrient Controller








Diluting Fertilizers and pH Down solutions

The peristaltic pumps used have a max flow rate of 70 mL/min. Note I received one in the batch that could only pump 27 mL/min so I ended up using that one to control pH.

I opted for constant speed control rather than variable speed and avoided having to deal with PWM and filters to generate the analog output. Based on this information and erring on the safe side, a minimum dispensed volume of 4 ml was assumed. Using trial and error a dilution ratio of 4:1 water:fertilizer and 3:1 water:vinegar make up source to feed the nutrient tank (100 L).  Without dilution, the EC and pH spiked as shown below.

EC Trend






Control Philosophy

As stated early, on/off control frames the approach to keeping the pH and EC at the desired setpoint.


Hand – Dispense fixed volume (mL) and stop. Volume to dispense set from HMI and saved in the Arduino’s non-volatile memory.

Off – turn off pump

Auto – Dispense a fixed volume (mL) every interval (s) . Volume and Interval set from HMI and saved in the Arduino’s non-volatile memory.

  1. Dispense if ( error = (setpoint – present value)) < 0 and trend to control on rising
  2. Dispense if (error = (setpoint – present value)) > 0 and the trend to control on is falling
  3. Stop dispensing when PV is 5% above or below SP depending on the trend to control. This minimizes unnecessary on/off chatter around the SP.


EC – Desired trend is falling trend. e.g. when below SP control apply control

  • SP = 1050, PV = 1020
  • error = 1050 – 1020 = 30 > 0
  • trend desired: falling
  • Result: control pump
  • Stop control when PV = 1050 * 1.05 ~ 1100

pH – Desired trend is rising trend. e.g. when above SP control apply control

  • SP = 6, PV = 6.2
  • error = 6 – 6.2 = -0.2 < 0
  • trend desired: rising
  • Result: control pump
  • Stop control when PV = 6* .95 = 5.7

The following charts illustrates the result. The left side is when I first moved the controller into Auto and was not tuned to the given process. Both pH and EC respond to drastically to the step change. The right side highlights the EC needing control and the bump in process is not as drastic. One day I may revert to implementing the P part of the PID and dispense the volume based magnitude of the error. So far there is no need for that.

ph ec control

Peristaltic Pumps for Hydroponic Nutrient Dispenser

Nutrient Containers and Pumps

Time to mock up some hardware and write some code to drive the pumps using the nutrient containers and pumps now on hand.


  1. Use the transistors available spare parts bin
  2. No need for speed control so PWM not required
  3. Dispense a specific volume (ml) of liquid
  4. Pump a volume (ml) liquid over a period of time (s)
  5. Periodically dispense a volume (ml) of liquid every interval (s)

Wiring Diagram

I did not have any MOSFETs on hand and the BJTs available could easily drive small loads.  The measured current draw of the pump came in at around 160mA. The max current the Arduino can source is 40 mA per pin with a max of 200mA combined. Given that the hydroponics drives several circuits, I opted to limit the driving current to 4mA resulting to a 1kΩ resistor and would drive the transistor into saturation. (switch mode).








The flyback diode is to prevent any back-emf to harm the transistor.  The before and after reveal  shows the effects of shunting the excess voltage when turning off the pump.





The software is built on top of what is currently written. The partial class diagram with public methods highlights the gist of the PeristalticPump class.








Dispensing fluids becomes quite simple. I’ve tested the outputs using an oscilloscope. The one issue the cheap pumps and hoses is the max flow rate degrades over time. e.g. hoses don’t contract and expand the same way. I will deal with that later but there is a method to set the maxflowrate which could be part of the calibration process.

Now that this is unit tested, it is time to replicated the setup 2 more times, and come up with a control philosophy for pH/EC.


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 canabis and 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.

Home Hydroponics


After experimenting with LED plant lighting, I finally got to the point of building an Arduino based hydroponic controller and ready to start planting things. As usual, functional requirements frames the project and consist of the following:

  •  Lighting control by On Hour/Minutes and Off Hour Minutes
  • Circulation pump and Fan control via on time/off time
  • Hand-Off-Auto for lighting and circulation pump
  • Measure Mixture Temperature
  • Measure Chamber temperature and humidity
  • Drain pump
  • Circulation Pump
  • H2O Inlet valve
  • pH and Electrical Conductivity
  • LCD display of key parameters
  • SCADA integration via modbus
  • xbee connectivity since I have several of those lying around
  • Nice to Have – CO2


A simple P&ID of the system the building of the system from which the tag list was created along with the corresponding modbus addresses.

Device Communications

The system consists of a mash-up of several technologies which communicate over different protocols. I like I2C and 1Wire as it simplifies the wiring.

Control Panel

The control panel components came from Digi-Key  as they provide competitive pricing and quick delivery. Note I chose Phoenix terminal blocks for the cheap price and quality.  Enclosures ended up too expensive leading to the din rails, terminal blocks, etc. mounted on wood. It does the job and came out ok.

A simple food container houses the LCD/RTC and switch enclosure and the future EC/pH sensor electronics as this is where the I2C devices reside. Labeling is not the nicest but it is good enough for now. The xbee device is left hanging there for now as well.


Inspiration for the setup came from this site and a chat with the folks at Quick Grow. I was told that 2.5″ piping would be sufficient to grow lettuce and thus ended up using that size for the first phase. I left a space for future expansion for 3″ pipe for cherry tomatoes.

Note this was built in an un-sused shower space in the basement and the folks at Quick Grow stated that the white will reflect the light so no need for reflective material. I also purchased the LED lighting from them for both the growing chamber and seeding area to support the local business.

General Parts List

A partial parts list used for the project.

The Schedule 40 piping and connectors as well as the sharkbite products came from good old Home Depot.

Stripping wire and terminating them became quite easy with these tools


There is a lot of libraries available to connect the various sensors. I also wrote my own to handle discrete inputs and outputs, timer outputs, Hand-Off-Auto, etc. This made things easier to maintain and can be found at and the main code at

Changes in switch values are detected and invoke a callback function. For example, the HOA class invokes a callback function passing the new switch state detected.


Median Filters

Noisy Liquid and CO2 levels was observed over time through the SCADA system. I exported the data in question and explored ways to deal with the extreme fluctuations. Note I did put an oscilloscope and the CO2 signal was clean. After some Excel plotting, I ended up with wanting a median filter with with a window size of 5. Fortunately, a library was written for it which saved me some time. The content of the signal on the left is the before filtering there is about 3000 samples in that image.


Nutrient Tank Level

Data Acquisition

The flow and CO2 use interrupts. Polling rates of the switch are set up at 500ms unless overridden. e.g.

Flow rates are calculated every 1second based on the pulses from the interrupt handler. The 1-wire and DHT-22 reading is performed every 5 seconds.

The ultrasonic level sensor was “calibrated” to read 100% at 100 L as well as the hi level switch.



  • Ultrasonic sensor – no special circuitry required to connect to the Arduino. Example here
  • DHT-22 sensor – added a 10k resistor between vcc and signal. Example here
  • 1Wire Temperature sensor -added 4.7k resistor between vcc and data
  • Input and level switches – enabled internal pull-up resistor in Arduino.
  • CO2 – no special circuitry required. Data sheet here
  • Flow sensor – no special circuitry required. How-to here
  • Added 1000uF electrolytic capacitor between 5v and DC ground handle potential inrush currents
  • Added 100nF ceramic capacitor between 5V and DC ground to filter out high frequencies

Next Steps

Installing a camera to take time-lapsed photos of the plants in the growing chamber as well moving to a smaller fan rather than the larger 12″ one in place is on the radar. Creating  mobile friend UI on the SCADA system is also in the queue.

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 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



Bike LED Vest Swift 3

Earth Day is is here. Tonight, organizers set up a night time a bike ride encouraging creative ways to make yourself seen.  My daughter wanted to wear my LED vest and assumed it was just a matter of lighting it up. Needless to say, the iOS app crashed. Considering I  never tested it out with iOS 10.3, it was high time to start troubleshooting.

Because of the fact I used the objective-C BLE libs, the crash precipitated the move 100% swift solutions. For the purpose of this exercise, I forked the current the swift version and patched it to use XCGLogger, compiled it for swift 3.0, and added a couple of delegates for my own app. The changes can be found  at the forked site.

Incidentally, the crash was attributed parsing JSON results from a YML query to yahoo. The service URL changed and I cleaned up the code so it would not crash in the future should it change again.

MEAN Tools Installation

Well after some thought, I figured it was time to roll up my sleeves and install some tools and frameworks to start with my minimilist IoT playground. I use macOS and will focus just on that.

Environment under macOS

I first started to go down the path provided at and felt there was too much of a heavy lift for a newbie trying to ramp up on four technologies at the same time. I opted for installing each of them by hand so I can see the type of problems can occur.

I installed the following:

Sublime Text – Nice editor and I started using it for Arduino development as well

MongoDB –  I used the homebrew approach.

Node Version Manager (NVM) – Used to manage different versions of node.js. Note I have Xcode installed and you may need the command line tools later.

If the NVM is too much of a hassle, get node directory from node.js via download
Node.js – It is already newer than the version I have (7.8.0). This is an easy install and should not pose any problems

Express Generator – another straight forward install for light weight web framework

I installed the following as well based on what I thought I needed for this learning exercise.

log4jslog4jslog4js based logging services for node.jsnpm install log4js -S
monkmonkwrapper to mongodb that is simpler yet not as powerful as mongoosenpm install monk -S
nodemonnodemonlistens for file changes and restarts server npm install nodemon -g
dummy-jsondummy-sontool to generate JSON files used for my testingnpm install dummy-json -g
RobomongorobomongoMongoDB managerdownload and point to mongoDB instance (default localhost:27017)
Bluebirdbluebirdpromise library implementationnpm install bluebird -S
SerialPortserial portserial port driver for node.jsnpm install serialport -S # have 4.0.7
xbee-apixbee-apixbee API for node.jsnpm install xbee-api -S

Off to learning this stuff.

Empowering the Many

Hello MEAN stack

A few years ago I had boat loads of temperature envelop data of my house and outside temperature. When I was looking for quotes to re-insulate my old house, an insulation vendor expressed interest in purchasing my before and after analysis and results. I did not proceed with a full re-insulation of my house but did end up loosing my data which was 100% my fault. I did not back up to a NAS and experiences a hard drive failure.

Fast forward today. There is lots of talk of IoT, Analytics, and cloud services. Many, I feel are putting lipstick on their outdated products so buyer beware.  That said, the various IoT ecosystems provided through services such as Microsoft Azure, etc. are making it easier to mashup, collect, aggregate, and analyze data. Alarm Management, historians may become moot at some point unless vendors provide added value services such as predictive analytics and performance management solutions.

My interests these days revolve around machine learning and visual analytics but I do like to keep on top of some technology that can be used to marry IoT with the enterprise. With the handful of XBee devices lying around, I’ve set my eyes to ramp up on the MEAN (MongoDB, ExpressJS, Node.js, AngularJS stack and see what I can come up with for my own use at home. I chose a Typescript/Javascript environment as I can get by with basic open source tools and decent editors without having to get something like visual studio.

Key System Architecture Components


1-configure XBee end devices to sleep and send to coordinator AI/DI data. (I’ve tested this a few years ago so I know it works) (Temperature, ambient light, etc) Mesh network using API mode.

2. 0 or more routers to relay the messages from the end devices to the coordinator

3. 1 coordinator that feeds into the system via serial port

4. Node.JS+ Express to handle the configuration of the I/O wired to the XBees. e.g. scaling, tag name, etc. MongoDB to persist the data, and angularJS to render the UI.

5. There are three IoT platforms ( GE Predix , XivelyThingSpeak, and Azure IoT )  that I have accounts with that I would like to push data to to test it out. I have two SCADA and one HMI system that I am also going to test out the IIoT readiness.

6. My home power monitoring has been running for 8 years on arduino and XBee. The next step is to push data rather than poll from the host to see what that SCADA system can do.

Further down the horizon the inclusion of some  MQTT flavour and and node.js integration.

Bike LED Vest Revisited

With Swift 3,  watchOS3, and iOS 10 released, it was time to migrate the code  from Swift 2.1 to Swift 3.0 using Xcode 8.0.  I still have use for my Myo armband but wanted to explore using Apple’s CoreMotion and HealthKit SDKs. The conversion tool in Xcode did a great job and most of it was dealing with optional chaining that required my attention. Once completed, the existing application worked as before. Although the bluetooth code migrated ok, I was left with a handful of deprecations warnings in iOS 10.0 that will need clean up so I can keep current on iOS releases.  For now, I wanted to explore how to use the iWatch Series 1 to achieve the following goals:

  • Capture Heart Rate and include with geolocation data in the  iPhone app
  • Detect and send turn signals to LED Vest
  • Display Temperature and Battery Voltage with alarm set points
  • Learn more about the Swift language, the various SDKs

Watch interface

Hats off to UIX designers. This does not come easy to me. I ended up purchasing Graphics (was iDraw) from Autodesk as it was affordable and comes with a rich feature set.  A nice bonus is that this tool can generate can generate Core Graphics “copy as” code.  Alas, my first pass works and leveraged the context menus to save on screen real estate.






Context Menu

The context menu used canned icons. The start/stop implement the obvious functionality.  The Speak functionality allows me to either send one of three messages or speak into the watch and send the resulting text to display on my LED Vest. The user interaction side was rather easy to implement using the presentTextInputController method of the WKInterfaceController class.








Swift extensions are your friend.  One can extend classes without access to source and add additional behaviour.  For example, to quickly implement alarm functionality, WKIntefaceLabel was extended to allow a refresh a label.


Healthkit is a pain to get going using just Apple’s docs.  Fortunately, there are lots of tutorials out there to help get things going.  I would have liked to have more detailed information so one can track heart rate variability (HRV).  These folks are working on some cool stuff mashing technologies using HRV. It seems we are left with BPM samples at around 5 second intervals. I get why, given that there could be other apps wanting access to this information and sub second resolution in a device that was meant to tell time at first would overwhelm watchOS. I suspect one day this should be available.

Core Motion vs. Myo

I found Myo integration to detect hand signals easier to implement. It was more intuitive. On the Myo, the “home” position would be cached so relative changes in movement could be computed. e.g.  right hand turn gesture using pitch and left hand turns using yaw and roll. It works quite well.

I could not get this to function using that same approach with consistent results on the iWatch.  I ended up working with just gravity component for hand signals position. e.g. right turn detection is using the X component of the accelerometer and the Y component for the left hand turn. Initially, I used CMDeviceMotion‘s CMAttitude  component and used multiply(byInverseOf: x) method of CMAttitude to get relative changes in motion.  It worked for the right hand turn but was inconsistent for the left hand turn.

The gravity only component with a range threshold range works ok for now. I will investigate the CMAttitude further and will look at integrating (summing changes along X,Y, Z over small sample windows to detect hand signals.



Bike LEDVest

I’ve been tossing this project in my head for a few years. I signed up when the Myo Armband came out on kickstarter and figured I could make use of it one day.   When I purchased the the Apple Watch, then that got the wheels in motion to build an LEDVest.

Some of the goals I wanted to achieve included the following:

  • Learn the iOS development (Swift language)
  • Drill down on Bluetooth LE development
  • Persist information on iCloud and retrieve from different devices
  • Create something useful and provides context based information to others while riding my bicycle at night
  • Explore iOS HealthKit and MapKit

Screen Shot 2016-02-06 at 5.26.43 PM



My wife did all the sewing. The LED’s are so bright that the iPhone camera does not do it justice inside. Many people commented from motorists, pedestrians, and cycles on how cool this vest was.

It took a lot of effort but it was a nice diversion from the day job. Learning a new programming language, organizing the code so that the appropriate level of abstractions exist to easily add new features, creating an application level protocol to control the LEDVest, and designing and building simple hardware bumped up the fun factor.

Using my Apple Watch, I can speak text to display and I send it to the LEDVest to display. If I am annoyed at a stop light, I tend to keep it safe. e.g. “Smog sucks”.  So far the software periodically displays the temperature from the hardware, along with the WTI price and Canadian currency via the yahoo finance API. If I loose connectivity to the iPhone, the arduino portion fails-safe and displays the stop symbol and posts the temperature every 30 seconds.

I’ll talk about the implementation details later.