Introduction: HYDROMATICS

We are 6 engineering students currently going through our last year of studies. For our electronics course, we decided to make an hydroponics project called “Hydromatics”. The purpose of this project is to grow plants without soil but instead using fertilizer solutions in a water solvent. It is a good solution for growing plants anywhere.

Step 1: Needed Tools

Many tools were used but keep in mind that the tools needed may change depending on the construction. Here is the list of what we used:

  • Screw drivers;
  • Drill and bits;
  • Hole saw;
  • Circular saw;
  • Jigsaw;
  • Soldering iron;
  • Crimping tool;
  • Basic tools (hand saw, hammer, pliers, ...);
  • Multi-socket;
  • Glue gun;
  • 3D printer;
  • Monitor, keyboard and mouse.

Step 2: Materials

The material that we used is divided into 2 parts. Mandatory material cannot be avoided for this project. Props are the things that we used but which could be replaced (e.g.: buckets could be replaced by boxes or tanks). Of course, we reused as much as possible.

Mandatory :

  • 2 water valves;
  • 5 humidity sensors;
  • 1 flow sensor;
  • 1 water pump;
  • 3 relays;
  • 1 Arduino Mega;
  • 1 Raspberry PI;
  • 1 breadboard;
  • 12 V power supply;
  • Water;
  • Liquid fertilizer.

Props :

  • 4 buckets;
  • 1 wooden pallet;
  • Wooden boards;
  • Screws;
  • Boxes;
  • PVC pipes;
  • PVC glue;
  • Hoses;
  • Wiring and crimping terminals;
  • Tape and/or thermoshrinkable sheath;
  • 3D printer consumable items (PLA);
  • Hot glue;
  • Lettuce sprouts.

Step 3: Preparation

3D printed parts :

To protect the water level sensors, PLA case is created and printed (left picture). You can find the .stl named "Couvercle1.5.stl"

To keep the salads in place, you need special buckets. For our project we used a 3D printer with PLA filament to print the buckets (right picture).

This bucket was found on : https://www.thingiverse.com/thing:790339

Fertilizer :

To create our plant nutrients

  • compost tea ( to bring a various range of nutrients)
  • coffee ( to give enough acidity )
  • ginger ( to boost vegetables growth )
  • urine ( for nitrogen )

Download files :

Step 4: Dimensions and Assembly of the Structure

Here are the different steps to make the structure :

- Find a wooden pallet

- Screw 4 wooden legs of 1 meter long. They have to protuce enough for the pipes to pass underneath

- Add the feet reinforcement

- Cut to size the 4 pipes of 1 meter long and the short part (approx. 0,4m)

- Assemble the straight pipes with the angled ones to obtain two round trips on the pallet. The water inlet and outlet side is called the front side.

- Cut down the holes for the pots. 3 for each section of 1 meter

- Add the angled pipe for the water inlet

- Add the section reduction at the end of the water circuit

- Seal the pipes

- Screw a wide board over both feet on the front side

- Hole up and insert the level sensors into the buckets. Low levels must be at approx. 10 cm of the bottom, high level must be at 10cm of the top.

- Make Hole and insert the solenoid valves on the rainwater bucket and the fertilizer bucket

- Seal the level sensors and the solenoid valves with hot glue

- Screw two wooden boards at 40 cm of the ground on the feet. They must extend of about 45cm in the front side

- Screw two boards between the previous ones to make a support area for the main tank.

- Put and attach the electronic boards box on the board

- Cable everything

- Print the pots

- Place the water pump into the main tank

- Fill the main bucket with water

Step 5: Implementation of Buckets and Hydraulic Path

Here are the different steps to make the hydraulic path and prepare the buckets :

To create the hydraulic path :

1. The hydraulic path is made by using a series of linear and angle pipes. Plastic glue must be used on the inside parts which will be in contact with the pipe (to be redone for each nesting).

2. At the end of the path a section reducer is used. It allows to choose the water level inside the pipes.

3. Put the newly created hydraulic path on an adequate structure (see building explanation).

4. Drill holes of the adequate diameter to fit in your vegetables.

To create the Buckets system :

1. Place three buckets on the upper part of the hydroponic greenhouse.

2. Place the rainwater recovery bucket on the top left, followed by the liquid fertilizer, and finally the bucket that acts as a buffer to manage flow and ensure fertilizer/water mixing.

3. Drill a hole of 3 centimeters of diameter in the last bucket using the Dremel so as to add the hose that will allow it to drain into the hydraulic path.

4. Drill a hole of the adequate diameter in the fertilizer bucket and the rainwater bucket using the Dremel so as to implement the needed solenoid valves and level sensors.

5. Place the fourth bucket, the water tank one, on the medium-height support.

6. Drill a hole of the adequate diameter using the Dremel so as to implement the needed level sensors.

7. Put the pump in the water tank and link it to the bucket that act as a buffer.

All images of the needed materials and the process of making the hydraulic path and the buckets can be found on the top of this step.

Step 6: Introduction of the Software

An Arduino Mega is used to read the sensors and control the actuators. It sends those information to the Raspberry PI using serial communication. The Raspberry PI is used to host a web server that allows the information to appear on a web page.

The Web Server is made using Python with Flask. More information can be found on : https://towardsdatascience.com/python-webserver-wi...

The web page is done using HTML and CSS.

Here are the python and the CSS codes :

Python :

import RPi.GPIO as GPIO
from flask import Flask, render_template, request import serial import time from datetime import datetime app = Flask(__name__)

ser = serial.Serial('/dev/ttyACM0', 9600) ser.flushInput() time.sleep(3)

pumpSts = 0 #automatic electrovalve1Sts = 0 electrovalve2Sts = 0

#Decrypting the String Function def decrypt(): ser.flushInput() line=ser.readline() line=ser.readline() line=line.decode('utf-8') deb,h_security_watertank,h_low_watertank,h_high_watertank,h_low_rainwatertank,h_low_fertilizertank,Arduino_pump,Arduino_electrovalve1,Arduino_electrovalve2=line.split() deb=list(deb) h_security_watertank=list(h_security_watertank) h_low_watertank=list(h_low_watertank) h_high_watertank=list(h_high_watertank) h_low_rainwatertank=list(h_low_rainwatertank) h_low_fertilizertank=list(h_low_fertilizertank) b=0 for a in deb: deb[b]=ord(a)-97 b+=1 b=0 for a in h_security_watertank: h_security_watertank[b]=ord(a)-97 b+=1 b=0 for a in h_low_watertank: h_low_watertank[b]=ord(a)-97 b+=1 b=0 for a in h_high_watertank: h_high_watertank[b]=ord(a)-97 b+=1 b=0 for a in h_low_rainwatertank: h_low_rainwatertank[b]=ord(a)-97 b+=1 b=0 for a in h_low_fertilizertank: h_low_fertilizertank[b]=ord(a)-97 b+=1 time=datetime.now().strftime('%d-%m-%Y %H:%M:%S') return deb,h_security_watertank,h_low_watertank,h_high_watertank,h_low_rainwatertank,h_low_fertilizertank,Arduino_pump,Arduino_electrovalve1,Arduino_electrovalve2,time @app.route("/") def index(): deb,h_security_watertank,h_low_watertank,h_high_watertank,h_low_rainwatertank,h_low_fertilizertank,Arduino_pump,Arduino_electrovalve1,Arduino_electrovalve2,time=decrypt() debitSts=''.join(str(e) for e in deb) #int(debitSts) humidity1Sts=''.join(str(e) for e in h_security_watertank) humidity2Sts=''.join(str(e) for e in h_low_watertank) humidity3Sts=''.join(str(e) for e in h_high_watertank) humidity4Sts=''.join(str(e) for e in h_low_rainwatertank) humidity5Sts=''.join(str(e) for e in h_low_fertilizertank) #int(humiditySts)

if (Arduino_pump == 'a'): texte="The pump is on" texte5="on" else: texte="The pump is off" texte5="off" if (Arduino_electrovalve1 == 'a'): texte1="The water tank is being filled" texte6="on" else: texte1="The water tank level is OK" texte6="off" if (Arduino_electrovalve2 == 'a'): texte7="on" else: texte7="off" if (int(humidity4Sts)>300): texte2="The rain water tank level is OK" else: texte2="The rain water tank is empty" if (int(humidity5Sts)>300): texte3="The fertilizer tank level is OK" else: texte3="The fertilizer tank is empty" if ((int(humidity1Sts)<300 and int(humidity2Sts)>300) or (int(humidity1Sts)<300 and int(humidity3Sts)>300) or (int(humidity2Sts)<300 and int(humidity3Sts) >300)): texte4="Default sensors" else: texte4="Sensors are OK" templateData = { 'debit' : debitSts, 'humidity1' : humidity1Sts, 'humidity2' : humidity2Sts, 'humidity3' : humidity3Sts, 'humidity4' : humidity4Sts, 'humidity5' : humidity5Sts, 'pump' : pumpSts, 'electrovalve1' : electrovalve1Sts, 'electrovalve2' : electrovalve2Sts, 'texte' : texte, 'texte1' : texte1, 'texte2' : texte2, 'texte3' : texte3, 'texte4' : texte4, 'texte5' : texte5, 'texte6' : texte6, 'texte7' : texte7, 'time' : time, } return render_template('index.html', **templateData) @app.route("//") def action(deviceName, action): global pumpSts global electrovalve1Sts global electrovalve2Sts if deviceName == 'pump' and action == "on": pumpSts=1 ser.write(b'1') if deviceName == 'pump' and action == "off": pumpSts=0 ser.write(b'2') if deviceName == 'electrovalve1' and action == "on": electrovalve1Sts=1 ser.write(b'3') if deviceName == 'electrovalve1' and action == "off": electrovalve1Sts=0 ser.write(b'4') if deviceName == 'electrovalve2' and action == "on": electrovalve2Sts=1 ser.write(b'5') if deviceName == 'electrovalve2' and action == "off": electrovalve2Sts=0 ser.write(b'6')

deb,h_security_watertank,h_low_watertank,h_high_watertank,h_low_rainwatertank,h_low_fertilizertank,Arduino_pump,Arduino_electrovalve1,Arduino_electrovalve2,time=decrypt() debitSts=''.join(str(e) for e in deb) #int(debitSts) humidity1Sts=''.join(str(e) for e in h_security_watertank) humidity2Sts=''.join(str(e) for e in h_low_watertank) humidity3Sts=''.join(str(e) for e in h_high_watertank) humidity4Sts=''.join(str(e) for e in h_low_rainwatertank) humidity5Sts=''.join(str(e) for e in h_low_fertilizertank) #int(humiditySts) if (Arduino_pump == 'a'): texte="The pump is on" texte5="on" else: texte="The pump is off" texte5="off" if (Arduino_electrovalve1 == 'a'): texte1="The water tank is being filled" texte6="on" else: texte1="The water tank level is OK" texte6="off" if (Arduino_electrovalve2 == 'a'): texte7="on" else: texte7="off" if (int(humidity4Sts)>300): texte2="The rain water tank level is OK" else: texte2="The rain water tank is empty" if (int(humidity5Sts)>300): texte3="The fertilizer tank level is OK" else: texte3="The fertilizer tank is empty" if ((int(humidity1Sts)<300 and int(humidity2Sts)>300) or (int(humidity1Sts)<300 and int(humidity3Sts)>300) or (int(humidity2Sts)<300 and int(humidity3Sts) >300)): texte4="Default sensors" else: texte4="Sensors are OK" templateData = { 'debit' : debitSts, 'humidity1' : humidity1Sts, 'humidity2' : humidity2Sts, 'humidity3' : humidity3Sts, 'humidity4' : humidity4Sts, 'humidity5' : humidity5Sts, 'pump' : pumpSts, 'electrovalve1' : electrovalve1Sts, 'electrovalve2' : electrovalve2Sts, 'texte' : texte, 'texte1' : texte1, 'texte2' : texte2, 'texte3' : texte3, 'texte4' : texte4, 'texte5' : texte5, 'texte6' : texte6, 'texte7' : texte7, 'time' : time, } return render_template('index.html', **templateData) if __name__ == "__main__": app.run(host='0.0.0.0', port=80, debug=True)

And CSS :

* {
box-sizing: border-box; font-family : Arial; font-weight : bold; }

body { background: rgb(27,27,27); color: white; width: 70%; margin: auto; }

.button { font: bold 15px Arial; text-decoration: none; background-color: #EEEEEE; color: #333333; padding: 2px 6px 2px 6px; border-top: 1px solid #CCCCCC; border-right: 1px solid #333333; border-bottom: 1px solid #333333; border-left: 1px solid #CCCCCC; }

.command{ text-align: center; display: inline-block; border: 1.5px black solid; padding: 10px; /*Marge intérieure */ width: 49%; vertical-align: middle; background : rgb(98,98,98); }

.monitoring{ text-align: center; display: inline-block; width: 49%; border: 1.5px black solid; padding: 0px; /*Marge intérieure */ margin-bottom:2px; vertical-align: middle; background : rgb(98,98,98); }

h1 { text-align: center; text-decoration: underline; margin-bottom:75px; }

h2 { color:black; text-decoration: underline; margin-bottom:45px; }

h3 { text-align: center; margin-bottom:45px; }

.statu{ text-align: center; width: 80%; margin:auto; margin-top:25px; border: 1.5px black solid; padding: 10px; /*Marge intérieure */ vertical-align: middle; background : rgb(98,98,98); }

The different files for the Raspberry PI can be found in the .rar file.

Step 7: Implementation of the Hardware

The voltage is brought by a multi-socket. It is used to supply electricity to the pump (220V), the raspberry PI (5V) and the solenoid valves (12V). The multi-socket is fixed under the project.

The electronics cables going from the humidity sensors to the Arduino are roughly 1.5m long. We used arduino cables from the sensor’s side and the arduino sides, then we welded each ends to a longer cable.

The humidity sensors are placed in the holes made in the different buckets and hot glue is used for fixing and waterproofing the buckets.

All the relays and the electronic cards are placed in a box for waterproofing.

Step 8: Useful Tips

Here are some useful tips to if you want to redo our project :

- Beware to be precise during the gluing to ensure seal between the different components;

- Check regularly the water pH and EC to guarantee the water composition;

- Use liquid fertilizer (even homemade) to ensure that no fertilizer lock occurs;

- Buy electronic lots (Banggood, Amazon, …);

- Regulate the flow using the section reducer on the end of the hydraulic path.

Gardening Contest

Participated in the
Gardening Contest