# Automatic plant watering system, pycom based with meassurement upload to pybytes By: Gustav Giske (gh222ih), Estimated time: 30 hours. ## Introduction This project aims to make an automated plant watering system using pybytes lopy4 module. In this tutorial you will get a description on how to build a system that takes meassurements from three sensors, soil humidity sensor, temperature sensor and a water sensor and from theese meassurements calculate an optimal amount of water for the plants. When the optimal amount of water is calculated the system will turn on a water pump which will deliver the desired amount of water to the plants to make them happy:) For easy acces to the information about the plants and water tank level the information gathered by the sensors and the result of the calculations is sent via Wifi to Pybytes for visual presentation. ## Objective I decided to make an automatic plant watering system for my balcony since it can be both hard to remember to water the plants every day and also a challenge to find someone to water the plants when I'm out of town. The project is based on the Pycom lopy4 device and micropython code along with some other hardware such as a water pump, relay, humidity, water and temperature sensors and a 12 V power supply. In order to ba able to monitor the plants and the water level in the tank, information gathered from the sensors is sent to and presented in pybytes for easy access. I decided to do this project since when it is done, it will be useful to be in order to keep my plants healthy but also sine it seems like a project that implements many important things to know when doing a home automation system such as controling realys and gathering data from sensors. It also gives a possibility to use the data in calculations to optimize the water usage depending on weather and soil conditions. I think the project will give insigths on how an automated system can be built, even if it is far from a proffesional system it can still give some basic understanding for the subject. Following this tutorial my guess is that the project would take around 30 hours to complete. ## Materials Below a list of the materials used is presented along with place of purchace and an approximate price. | Item | Approx price (Sek) | Store | Brand & product name | | ------------------------- | ------------------ | ------------------ | -------------------- | | Breadboard | 30 | Kjell & Co | Unknown | | Relay | 100 | Kjell & Co | Velleman (VMA406) | | Assorted cables | 30 | Kjell & Co | Unknown | | Temperature sensor | 150 | Kjell & Co | Velleman (VMA324) | | Water and humidity sensor | 120 | Kjell & Co | Velleman (VMA303) | | Water Pump | 300 | Sunwind | Seaflo 12 liter | | Microtube | 100 | Impecta fröhandel | Unknown | | Water sprinklers | 80 | Impecta fröhandel | Unknown | | 12 mm water hoose 2m | 40 | Bauhaus | Unknown | | 12 V DC power supply | 150 | Kjell & Co | luxorparts (IK100006) | | Expansion board V3 | 160 | Mouser electronics | Pycom | | Lopy 4.0 | 320 | Mouser electronics | Pycom | All the sensors use 5V as an input and the lopy4 and the expansion board is powered via a regular micro usb cable and an old cell phone charger I had laying around at home. The water and soil humidity sensor delivers analog readings and the temperature sensor digital readings to the Lopy4. The Lopy4 and the expansion shield V3 is produced by Pycom and has several connectivity bands such as wify, bluetooth, Lora and Sigfox as well as both digital and analog inputs/outputs. In this project we will however only use the bluetooth connection. The Lopy4 is programmed using micropython. Pictures of the parts can be seen in the picture below, circuit diagram and in the finalizing the project part of the report. ![](https://i.imgur.com/nKJFQvc.jpg) ## Computer setup The main computer used to write code on in this project is running Windows 10. As a text editor and IDE Atom was used with the pycom add on pymakr which allows you to run the code on the computer as well as synchronize all the files in the project to the board. Atom for windowas can be found here: https://atom.io/ and the pymakr plugin can be found here: https://atom.io/packages/pymakr. The code is simply uploaded to the board by pressing the upload button in the Atom editor. Also to be able to update the lopy4 deveice the Pycom firmware update app was installed and run. It can be downloaded from: https://pycom.io/downloads/. After the lopy4 was updated using the firmware update app the setup was complete. The device was also registered on Pybytes with an account in order to be able to send and present data meassured by the lopy4. A more close description on how toset up the account can be found here: https://docs.pycom.io/pymakr-online/toolsfeatures/#update-hierarchy. It is a very easy process and should only take a few minutes. ## Putting everything together In the circuit diagram below all the wiring can be seen with the red being + voltage, blue conected to GND and orange being the signal wiring connected to different inpuy/output ports of the expansionboard. ![](https://i.imgur.com/VVmoWNQ.jpg) Furthermore the 12 V DC power used is as mentioned in the materials section a converter conected to the 230 V power outlet. Between the DATA and Vcc on the temperaboture sensor a 10 k ohm resistor is connected and all sensors are running on the V_in which is approximately 5 V since the expansionboard is run via usb. The rain sensor is connected to pin 15, the soil humidity sensor to pin 14 and the temperature sensor is conected to pin 23. The relay is connected to pin 5 which gives a high signal to trigger the relay and turn on the pump. Important to notice is that the realy has two possible imputs for the 12 V power cable, NC which means normally closed and NO which means normally open. Since the water pump mostly will be turned off the normally open connection is used. Since the sensors and relay will consume relatively low power and therefore low currents it is fine to drive them from the pycom device. However the pump has to be powered through a separate power source since it both requre higher voltage and power than the board can deliver. The setup done here is only for development since a breadboard is used and if it where supposed to be produced in a larger scale the design could be done in a more compact form. ## Platform The platform for presenting the data given by the sensors is Pybytes. It was chosen since it is a fairly easy way to present the data and it is also free. It is cloud based platform which also gives the oppotunity to update and upload new code to the device. It also gives the opportunity to update the firmware over the air. ## The code The code for the project is presented below. In order for it to be easy to understand almost every line have been commented. A description of the idea of how the code is thought out is anyway important in order for the reader to tailor the watering system to it's own conditions. Starting at line 3 the code block for the teperature sensor is imported and it can be downloaded from: http://donkey.vernier.se/~yann/onewire.zip Furthermore all the pins used in the code is defined and at line 10 and 11 it can be seen that the analogue pins have to be attenuated since the sensors will give up to 3.3 V instead of 1.1 V which is the standard setting. On line 12 the tank level at start is defined to 10 liters which have to be changed in case the tank size is changed. The basic outline of the code is then two functions, the onehourloop and the waterusage. In the Onehourloop the sensor meassurements are taken and saved into three different lists. It consists of a while loop which is set to run 5 times and at the end of each loop the data is sent to pybytes. The code is also set to sleep for five seconds between each reading. The idea of the code is that the Onehourloop will run for approximately 6-12 hours by changing the number of time the while loop runs and increase the sleep time between the meassurements since it is hardly neccesary to meassure the soil humidity every five seconds. Then, when the Onehourloop is done after a prefered amount of time decided by the user the code will enter the waterusage loop. In this function the variable waterb defines the amount of water which is used to water the plants. Firstly, the code checks if the soil is dry, wet or good and sets waterb to a value of 0, 1 or 2 liters based on this. A value from the sensor below 1000 has been defined as dry, between 1000 and 3000 to be good and above 3000 to be wet. Furthermore, since warm weather increase the evaporation waterb is multiplied by 1.2 if the temperature is above 26 degrees and multiplied with 0.9 if the temperature is below 19 degrees. If it has been raining the waterb is reduced in a similar way by multiplying it by 0.7 if water sensor is above 3000 and 0.95 if the water sensor gives a reading between 1000 and 3000. On line 72 the specified water volume given per minute by the pump is stated. This is then used to calculated for how long the pump is supposed to be turned on in order to deliver waterb amount of water. The relay is then set to on and then a sleep with the amount of time the pump is supposed to be on is set in line 80 before the pump is turned off again. The water level in the tank is then calculated on line 77 before the amount of water used and tank level data is sent to Pybytes. The program will then loop until the water level in the tank is below 0.1 liters and the code is stopped. The idea is that the tank will last several days and when it is empty the user will press the reeboot button on the lopy4 and fill up the tank in order for the program to restart. The complete code is presented below: ```python= from machine import Pin, ADC from time import sleep from ds18x20 import DS18X20 #for temperature import math #probably not needed import machine relay = Pin('P5', mode=Pin.OUT) #relay for water pump btn = Pin('P10', mode=Pin.IN) #button not integrated in code yet d=DS18X20(Pin('P23', mode=Pin.OUT)) #tepmerature meassurement adc = ADC() # create an ADC object apin = adc.channel(pin='P15', attn = ADC.ATTN_11DB) #attn 11 db to adjust for 3.3 V input apin2 = adc.channel(pin='P14', attn = ADC.ATTN_11DB) list4 = [10] #Tank level at start def onehourloop(): #loop for meassurements list1 = [] #list for temperature readings list2 = [] #list for rain level readings list3 = [] #list for soil humidity readings counter = 0 print('o h loop started') while counter < 5: # Number of times meassurements will be taken before watering result=(d.read_temps()) #Temperature reading if result: #If faul in reading temperature will be set to -1 temp_val=result[0] else: temp_val=-1 print(temp_val) rain_val = apin() #rain level reading print(rain_val) humid_val = apin2() #soil humidity reading print(humid_val) list1.append(temp_val) #put values in lists list2.append(rain_val) list3.append(humid_val) sleep(5) #time between readings pybytes.send_signal(2, temp_val) #send values to pybytes pybytes.send_signal(3, round(humid_val/41)) pybytes.send_signal(4, round(rain_val/409)) counter += 1 print('o h loop finished') return list1, list2, list3 #return lists to be used in waterusage def waterusage(): #waterusage calculations and pump time print('water usage loop started') list1, list2, list3 = onehourloop() waterb = 0 #sets initaial value to be changed in function if list3[-1] < 1000: #takes last value of soil humidity waterb = 2 #2 liters is just a guess on how much water is needed, to be adjusted print("Dry soil!") elif list3[-1] > 3000: #assume wet soil at reading above 3000 waterb = 0 print("Wet soil!") else: waterb = 1 print("Soil humidity good!") if list1[-1] < 19: #this if loop takes temperature into account print("Cold weather!") waterb = waterb*0.9 #reduses water used if weather is cold due to less evaporation elif list1[-1] > 26: waterb = waterb*1.2 #increase water used if weather is hot due to more evaporation print("Hot weather!") else: print("Nice temperature for plants!") if list2[-1] < 500: #this loop takes rain amount into account print("No rain!") elif list2[-1] > 3000: #if a lot of rain has fallen we reduce the water amount sligthly waterb = waterb*0.7 #some plants are however under roof so water is still needed print("Heavy rainfall!") else: print("Scattered showers!") #if there has been just a little rain the water amount waterb = waterb*0.95 #is reduced just by multiplying with 0.95 V_per_min = 12 #Volume water given by pump in liter/min time_on=waterb/V_per_min*60 #time on for the pump to give the rigth amount of water relay.value(1) #realy turn on sleep(time_on) #relay stays on for time_on relay.value(0) #realy shut of water_level = list4[-1]-waterb #calculate the new water tank level print('Plants have been watered', waterb, 'liter') print('water usage loop ended') print('time on', time_on) print('water level is', water_level) list4.append(water_level) #save water tank level in list pybytes.send_signal(5, str(waterb)) #send water amount to pybytes pybytes.send_signal(6, str(water_level)) #send water tank level to pybytes sleep(10) # just a short break while True: #main code to be run until tank is empty waterusage() # onehour loop is run in waterusage if list4[-1] < 0.1: #stops code if water level is too low print('Fill up tank and press reboot button on pycom device') break ``` ## Transmitting the data/connectivity As the code is written the data will be sent around every 5 seconds except for a break at around 30 seconds when the waterusage loop is running. The idea is however that the user will increase the sleep time in the onehourloop and send data less frequent since the meassurements won't change very fast. My plants are located in my balcony and hence Wifi was the natural wireless protocoll to use. As mentioned before Pybytes is used as the destination for the data. Pybytes is supposed to use MQTT as transport protocol. ## Presenting the data ![](https://i.imgur.com/GU3sZeR.jpg) In Pybytes the data visualisation is fairly fast and easy to set up. As can be seen in the figure above the program sends data at five signals, temperature, humidity, rain level, water usage and water tank level. From this view which only shows the last recieved value for each signal it is possible to read historic values by going into any of the signals. There is then a posibility to see the values in a table or a line chart as is shown below where the values for the soil humidity is presented. The data is saved in the database as often as they are sent. In other words approximately every 5 seconds. ![](https://i.imgur.com/hNocmpU.jpg) ## Finalizing the design The finalized project can be seen in the pictures below. Since no 3d printer was available at the time the lopy4 and the breadboard was placed in a plastic box which should be waterprooof. The rain level meassurements was done by placing the water level sensor in a samll box in order to be able to meassure the amount of rain that falls. The Water sprinklers was connected to the main hose via the micro tube as can be seen in the pictures and the water pump was connected to the main hose and then put into the 10 liter water bucket/tank. The project went according to plan for the most part, hovewer the pump seem to be delivering a little too low pressure in order for the sprinklers to reach all of the plant pots so there might be an upgrade into a more powerful water pump in the future. ![](https://i.imgur.com/UI3U4vZ.jpg) ![](https://i.imgur.com/ageBhcb.jpg) ![](https://i.imgur.com/CBP6tmk.jpg)