In this chapter we go through the wiring and testing of the hardware components connected to the Arduino. You can use the sketches presented here to verify the functionality of your sensors, controllers and feedback providing parts using the same pin layout as the final grow box monitoring code. Sketches were written using Arduino Software (IDE) and circuits were drawn using Fritzing, both applications are open source, free and support Windows, Linux and Mac OS X as well.
Download Gbox420 Sketches (ZIP) : Complete grow box controlling sketch, test sketches for the different components, libraries and website with the grow box controls. Optionally you can browse the zip content and download sketches individually or check the code out at GitHub.
Using a speaker from an old PC case works great as an audio source. To adjust the volume of the speaker connect a resistor in series with the Arduino analog output and the speaker`s positive side. I have used a 330Ω resistor for moderate volume, to make the speaker louder use a smaller resistance. The standard PC speakers have 8Ω resistance and 0.25W rating, to ensure on 5V the maximum power rating is not surpassed use a minimum 100Ω resistor. Here are a few sound intensity measurements taken using different resistance values: 100Ω - 77dB , 220Ω - 71dB, 330Ω - 69dB, 1kΩ - 59dB, 3kΩ and above are inaudible.
Buzzer
8 ohm
0.25W - 1W
Metal film resistor
100Ω / 220Ω / 330Ω / 1kΩ
Expected test result: Plays the Star Wars theme song.
Internal and external temperature and humidity are monitored using DHT22 sensors. The internal sensor is installed inside a remote box connected via UTP cable and placed inside the grow box while the external sensor is placed inside the PC case near the air intakes, far away from any heat source like the power supply or LED driver. The chip runs on 5V power and communicates with Arduino over a single digital data line.
Expected test result: Temperature and humidity measurements are printed in on the serial output every 2 seconds.
In an attempt to keep the wiring modular I have used UTP cables to connect remote sensors back to the Arduino. Plastic food containers were used to provide the sensors and cabling with physical support, these containers are cheap, pretty easy to work with and come in various sizes, you just need a large enough box to fit the sensors and a UTP cable connector inside. The UTP cable will be used to feed power to the sensors and relay sensor readings back to the Arduino. A single UTP cable has 8 wires inside, two of which can be used as common power lines (VCC,GND) and 6 can act as data lines. In the first box I`m going to place the DHT and a Light sensor, later on there will be a second box that will house the water level, water temperature and pressure sensors.
RJ45 keystone jack
2pcs
8 punch down
connectors
Plastic container
300 - 350ml
Velcro tape
Self adhesive
UTP cable
CAT5 or CAT6
Jumper wires
10 cm / 4 inch
1set of 120 cables
Male to male
Male to female
Female to female
First we need to prepare the plastic container by:
Besides using a drill, an old soldering iron or a heated up nail could be used to melt the ventilation holes, just make sure to do this in a well ventilated area as plastic fumes are definitely not healthy. For the light sensor make the hole on the downwards facing side of the sensor box, the photo sensor will be poking out here directed towards the lights.
Second step was to prepare the plastic box by cutting a rectangle outlet for the RJ45 connector, for this I used a sharp utility knife, running the blade multiple times along the edges to cut the wall through. Be careful not to apply too much pressure to avoid cracking the plastic like I did.. Heating up the blade would probably ease cutting the plastic. Once you have the hole ready you need to cut off the latch on the bottom side of the keystone jack to allow it to fit through the hole.
Bypass capacitors were added between the 5V power input and ground pins to compensate for the internal resistance/inductance of the UTP cable. (Here is an excellent video from EEVblog that explains bypass capacitors). I have added a 470uF electrolytic and a 0.1 uF ceramic capacitor in this example. Be mindful that electrolytic capacitors are polarized, meaning the negative leg that needs to be connected to GND, and a positive leg to 5V, do not mix the two up as that causes the capacitor to heat up and fail. Ceramic capacitors have no polarity, you cannot connect them the wrong way and accidentally blow them up. You can vary the capacitance of both the electrolytic and ceramic capacitors based on the sensor`s power needs as long they support 5V voltage or above.
Electrolytic capacitor
470uF - 2200uF
16V or above
Ceramic capacitor
470pF - 100nF
16V or above
Shorten the legs of the capacitors and using a flat head screwdriver push the ceramic and electrolytic (polarized!) capacitor legs into the UTP keystone jack connectors, then place the jumper wires on top. You only need to put bypass capacitors on the sensor side of the UTP cable, the other end can connect directly to the Arduino power lines. Use short 10cm / 4inch jumper wires to connect the sensors, choose male or female cable connectors depending on the sensor pins. When the jumper cables are pushed into the UTP keystone connectors the small blades inside the connector cut into the insulating plastic of the cable and make electrical contact with the wire inside. Once the cable is fitted it is hard to remove it without damaging the internal wires.
When the wiring is complete place the sensors into the plastic container, use a small blob of hot glue to keep them in place if needed. Mount the sensor box inside the grow box using self adhesive velcro tape.
The LM393 light sensor used in this project has one digital and one analog output and needs 3.3V or 5V power input, we are going to use 5V input as the Arduino signal voltage is also 5V. The digital output signals if the screw adjustable light level is reached, sending HIGH if light is not detected and LOW if light is detected. The analog output shows how intense the detected light is between 0 and 1023, where lower value means stronger light. This sensor is installed inside the remote sensor box connected by UTP cable to the Arduino.
Expected test result: Reads light intensity and determines if its over or under the screw adjusted preset limit. Results are printed to the serial output.
The B variant of the Meanwell HLG driver`s dimming circuit supports 3 different dimming options: 100kΩ adjustable resistor, 10V PWM signal or 1-10V DC voltage. Originally I have used resistance based dimming with a digital potentiometer, but one of you guys pointed out the PC817 optocoupler based PWM dimming is easier to implement, cheaper and uses less pins (thanks for that! ). In this solution the dimming works by varying the duty cycle of an Arduino generated PWM signal and modulating the voltage between the LED driver`s DIM+ and DIM- cables with it. As the HLG drivers use 10V signals it cannot be directly controlled by the 5V Arduino, an electrically isolated switch called an optocoupler is required.
The optocoupler`s anode pin is connected through a current limiting 680Ω resistor to the 5V Arduino PWM pin and the cathode pin connects to Arduino ground. It provides electrical isolation from the collector and emitter legs, where the 10V DIM- and DIM+ wires are connected to. When the Arduino PWM signal is high the collector and emitter on the Output side is shorted, signaling LOW to the HLG dimming circuit. This HIGH - LOW difference on the input and output side of this circuit is called an inverted output, meaning the HLG dimming will measure the inverse of the PWM duty cycle ( Arduino duty cycle: 90% → HLG measures 10% duty cycle, Arduino duty cycle 20% → HLG measures 80% duty cycle). This can be compensated in the Arduino sketch. The HLG dimming circuit can measure the duty cycle of PWM signals in the 100 Hz - 3 kHz frequency range, the default Arduino PWM frequency of 490 Hz is a good fit for dimming.
14.1% vs 92.2% duty cycle difference between a 490 Hz PWM signal - Higher duty cycle = longer lasting high signal
Arduino 14.1% PWM = HLG 85.9% brightness (Bright), Arduino 92.2% = HLG 7.8% brightness (Dimm)
PC817 optocoupler
Input 5V
Output max 80V
80 kHz cutoff frequency
Metal film resistor
680Ω
Splicing connector
2 pcs
2 pin
Wago 221-412
Expected test result: LED brightness cycles between 8% and 100%, pausing for 10 seconds on Max and Min values.
Using an LM393 light sensor I have taken measurements every 10% over the course of 6 full loops, as the graph shows the light intensity was pretty consistent at the different dimming stages. At 100% output the Arduino PWM signal duty cycle is 0% and the maximum dimming is at 92% duty cycle. This is due to the inverting logic of the optocoupler: When the Arduino signal is high(5V) the optocoupler outputs are shorted pulling DIM+ voltage to DIM- (0V), when the Arduino output is low (0V), the DIM+ cable is high (10V). Meanwell does not recommend dimming below 6%, this is the reason the duty cycle is maxed out at 92% on the Arduino side providing dimming to 8%.
Fun fact: The photo where the light looks stronger is the fully dimmed state, the camera could not handle the maximum brightness
Contactless water sensors are used to track the reservoir nutrient levels . These sensors can detect the presence of water through the plastic walls of the reservoir (up to 2mm thickness). There are multiple versions (NPN / PNP / T12) of the sensor , differentiating in how the Signal cable acts when the sensor detects water. I recommend using the NPN version that connects the Signal cable to Ground when water is detected. This can be read on an Arduino pin as LOW input. When the sensor is not detecting water we need to ensure the signal line is connected to HIGH, this is done by defining the pin mode as INPUT_PULLUP.
Expected test result: Water level readings on serial output. I’m using four sensors in the example, you only need two sensors for the final build.
Output while filling the container:
This is the second UTP connected remote sensor box for the water level, water temperature and pressure sensors. The four water sensor connectors were installed inside the plastic container with a UTP keystone jack and the sensor heads got glued to a piece of L profile aluminum leftover from the LED lamp frame. Using an RJ45 keystone jack connector is an easy way to connect remote sensors to the Arduino. With a single UTP cable a total of six data signals plus two power lines ( 5V, Ground) can be connected. In the below box the water sensors use 4 signal cables and two common power cables, leaving 2 lines free for the pressure and water temperature sensors.
RJ45 keystone jack
2pcs
8 punch down
connectors
Plastic container
300 - 350ml
UTP cable
CAT5 or CAT6
Jumper wires
10 cm / 4 inch
1set of 120 cables
Male to male
Male to female
Female to female
A waterproof DS18B20 sensor is used to read the water reservoir temperature. The sensor is powered by 5V and communicates with the Arduino over a single data line. A 4.7kΩ resistor is required between 5V and Data lines, else the sensor will not return readings. This component is connected to the second remote sensor box along the water lever and pressure sensors.
DS18B20 waterproof Temperature sensor
Metal film resistor
4.7 kΩ
Expected test result: Temperature readings in Celsius and Fahrenheit logged to serial every 2 seconds.
This component is only needed with the High Pressure Aeroponics setup. It is used to monitor the pressure in the expansion tank and control the high pressure water pump that fills the pressure tank. The sensor works on 5V and outputs an analog signal lineary changing with the pressure. At 0 bar / PSI the output is around 0.5V (Analog Read 102) and at maximum 12 bar / 174 PSI the output is 4.5V (Analog Read 921). As every sensor is slightly different they need to be calibrated to 0 bar / psi.
First we need to determine the offset voltage the sensor outputs at 0 pressure, this is done by taking the average of 50 measurements while there is no pressure in the system and calculating the voltage using: Offset Voltage = Average Reading * 5.0 / 1024.0; The test sketch at the bottom of this section helps to calculate the offset voltage. Once the offset voltage is known we need to determine the rate the voltage increases as the pressure rises. As this requires a second pressure reference it's best to look up this value for the specific sensor type on the internet. Researching my sensor the recommendations were in the 2.8 - 3 range. The formula to calculate the pressure is: Pressure = VoltageToPressureRatio * ( (SensorReading * 5 / 1024) - OffsetVoltage)
As I already had a pressure sensor I took my own readings to determine the VoltageToPressureRatio. For this I made a Google Sheets spreadsheet where I noted down the pressure sensor readings (Column A) and the reference pressure (Column B) while slowly decreasing the pressure. Then using the above formulas I calculated the voltage for the sensor readings, then calculated the pressure by subtracting the offset voltage I measured at 0 pressure (G1 cell) and multiplied the result by the recommended VoltageToPressureRatio (Cell G2).
Once I had the raw data I made a line chart to display the Calculated voltage (green line), Calculated pressure (red line) and the reference pressure (blue line). Now I only had to adjust the VoltageToPressureRatio (Cell G2) value until the Calculated pressure matched the Reference pressure as close as possible. As the high pressure aeroponics setup will run in the pressure range of 5.5 - 7 bar / 80 - 100 PSI I focused to align the top section of the lines. The ideal VoltageToPressureRatio based on my measurements is 2.7. You can use the Google Sheets spreadsheet to note down your own measurements and figure out the ratio for yourself, or just take the 2.7 if you have the same sensor. In the Gbox420 sketch you can change these values under 420Setting.h file: They are stored as PressureSensorOffset and PressureSensorRatio variables.
Pressure sensor
5V power
1/4" external thread
Pressure: 0 - 1.2 MPa
(Max 12 bar / 174 PSI)
Reducer fitting
1/4" internal to
3/4" internal thread
Expected test result: Offset voltage somewhere in the 0.5V range, and the calculated pressure of 0 bar / PSI.
Gbox420 sketch: In the complete monitoring sketch you can find the calibration values under the 420Settings.h tab, update this before uploading the code.
Once the Gbox420 sketch is on the Arduino you can re-calibrate the pressure sensor using the Settings tab. Use the Read offset button when there is no pressure in the tank and update the Offset based on the displayed result. The calibration parameters are saved to the EEPROM of the Arduino and stored between reboots.
The pressure sensor connects to the same plastic container with a UTP connection to Arduino as the water level sensors. It gets power from the shared power lines (5V, Ground) and uses one signal cable.
To calibrate the PH meter at least 2 readings are needed at known PH levels. To set the PH of water to a predefined value we are going to need calibration solutions that come either in powder or liquid form. In this example I`m going to be using 3 bags of powdered PH solutions that need to be poured into 250ml, 25°C/77°F distilled water. Distilled water is a type of purified water available in larger stores or can be homemade, it is free of impurities and minerals that could react with the calibration solution and alter it`s PH. The buffer used in this example will set the PH of the water samples to 4.01 , 6.86 and 9.18. After mixing the solution we just need to take measurements with the PH probe and note down the analog read values. Using just two measurement points and a little linear algebra magic we can get the equation of a line ( y=m*x + b , where “m” is the slope, “b” is the intercept ) that can calculate the PH for any reading.
PH-4502C sensor + module
5V power
PH 0 - 14 range
60sec settling time
BNC connector
BNC extender cable
Male to Female
3 meters / 10 ft
PH buffer powder
PH: 4.01 , 6.86 , 9.18
First of all hook up the PH reader to the Arduino:
Expected test result: Sketch will take 200 readings with 100ms intervals and calculate the average analog read value. Once the sketch is uploaded put the PH probe into each PH solution, wait for the readings to stabilize (~60 sec) and note down the Analog reading value. Before dipping the probe into a solution rinse it off in pure distilled water to avoid contaminating the solution and altering it`s PH. At this point do not worry about the displayed PH, it will not be accurate until the calibration is done.
These were the readings I got in the different calibration solutions, notice that as the PH gets higher the reading gets lower:
Now comes the math magic: Using two of the above results we can calculate the equation of a line that gives us the PH value for any reading. To get the line equation head over to MathPortal - Two point form calculator and enter your results for the 4.01 and 6.86 measurements (You could enter any 2 points, but it is best to use the PH range where the calibration should be the most accurate). Hit the Calculate button and you will get the equation that returns the PH (y) for any analog read value (x). Will will need to put the Slope and Intercept parameters to the PH monitoring sketch to calibrate the sensor.
The site will give you the two values in fractions, just type these into a calculator and round them to 6 decimal places. For example -95/3032 will become -0.031332 and 3431791/151600 will be 22.637144. This keeps the Arduino from doing the same calculation every time it takes a PH reading. Now the only remaining thing is to head back to the calibration code and update the PH calibration parameters: PHCalibrationSlope and PHCalibrationIntercept.
Upload the updated code and put the PH meter into the 9.18 PH calibration solution to verify the line equation works. The result should be pretty close to 9.18:
Gbox420 sketch: In the complete monitoring sketch you can find the calibration values under the 420Settings.h tab, update this before uploading the code.
Once the Gbox420 sketch is on the Arduino you can re-calibrate the PH meter using the Settings tab. After putting the probe into the calibration solution use the Read raw button to get the analog read value for the calibration point. After calculating the PH equation and updating the Slope and Intercept values press Set to store the values. The calibration parameters are saved to the EEPROM of the Arduino and stored between reboots.