Scope
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
P&ID
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.
Piping
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.
- Wire Raceway
- DS3231 AT24C32 IIC High Precision RTC Module
- Buck Converter
- 5V 2-Channel Relay Module Shield
- DC12V G1/2 Solenoid Inlet Valve Normally Closed
- Arduino Mega 2560 R3 Microcontroller
- IIC/I2C/TWI 2004 204 20X4 Character LCD Module
- DS18B20 Temperature Sensor Thermal Probe Waterproof 1-Wire
- 12V 8-Cha
nnel Relay Module With optocoupler - DHT11/12/22 Temperature&Hu
midity Sensor - DIN Rail Mount Screw Terminal Block Adapter Module, For Arduino MEGA-2560 R3
- 12VDC Power Supply
- Ultrasonic Sensor
- Flow Sensors
- CO2 Sensor (given to me)
- pH and EC (not cheap and a nice to have)
- pH Meter (from amazon)
- EC Meter
- Drain Pump (too noisy but not used often)
- Level Switch
- Submersible Pump
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
Software
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 https://github.com/chrapchp/IOLib and the main code at https://github.com/chrapchp/PlantLEDLighting/tree/hydroponics
// Discrete Outputs
DA_DiscreteOutput DY_102 = DA_DiscreteOutput(31, LOW); // Seeding LED 120 VAC
DA_DiscreteOutput DY_103 = DA_DiscreteOutput(32, LOW); // Growing Chamber LED 120 VAC
DA_DiscreteOutputTmr PY_001 = DA_DiscreteOutputTmr(33, LOW,
DEFAULT_CIRCULATION_PUMP_ON_DURATION, DEFAULT_CIRCULATION_PUMP_OFF_DURATION); //
Discrete Inputs DA_DiscreteInput HS_003B = DA_DiscreteInput(26,
DA_DiscreteInput::RisingEdgeDetect, true); // LCD display previous
DA_DiscreteInput HS_003C = DA_DiscreteInput(27, DA_DiscreteInput::RisingEdgeDetect, true); // LCD display Enter DA_
HOASwitch HS_001AB = DA_HOASwitch(7, 0, 8); // Circulation Pump Hand Status : HOA :Hand/Auto
DA_HOASwitch HS_102AB = DA_HOASwitch(52, 0, 53); // Seeding Area LED : HOA :Hand/Auto
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.
void on_GrowingChamberLED_Process(DA_HOASwitch::HOADetectType state)
{
#ifdef PROCESS_TERMINAL_VERBOSE
*tracePort << "on_FlowingLED_Process HS_103AB" << endl;
HS_103AB.serialize(tracePort, true);
#endif
switch (state)
{
case DA_HOASwitch::Hand:
DY_103.disable();
DY_103.forceActive(); // force the light on
break;
case DA_HOASwitch::Off:
DY_103.disable();
break;
case DA_HOASwitch::Auto:
DY_103.enable();
break;
default:
break;
}
}
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.
CO2
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.
HS_002.setPollingInterval(500); // ms
LSHH_002.setDebounceTime(1000); // float switch bouncing around
LSHH_002.setPollingInterval(500); // ms
HS_002.setOnEdgeEvent(& on_InletValve_Process);
LSHH_002.setOnEdgeEvent(& on_InletValve_Process);
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.
Wiring
- 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.