BC Robotics

Raspberry Pi Irrigation Control – Part 3

  PRODUCT TUTORIAL

In the past two Raspberry Pi Irrigation Controller Tutorials we have assembled the board, connected the Pi, added sensors, and tested all of the components. In the third part of this four part tutorial we are going to figure out how to write a program that will run our sprinklers, monitor a few of our sensors, and email us once it has finished running. We will also figure out how to schedule this program so it only runs when we want it to – what good would a sprinkler system be if it can’t follow your watering schedule! There are several different ways to approach this on the Raspberry Pi and we will go into the design logic and reason for our choices in this tutorial as well as writing the code.

Overview:
Before we get started, you should have completed the previous two sections of this tutorial. We are going to start by setting up a Gmail account to send our emails and then it is straight back to coding as we will have to modify our Python program. We want our program to operate the sprinklers for the correct duration, read the sensors, and email us once it has run. After that we will look at how to schedule it to run at the right time on the right date. As always, we will break it down into a bunch of easier steps to get through this!

Requirements:

This tutorial requires several items:

Required Items:
  Completed assembly from Part 1 of this tutorial set
  Completed code from Part 2 of this tutorial set
  Raspberry Pi Compatible Power Supply
  USB Keyboard & Mouse
  Internet Access
0%

Step 1 - Emails

It is always nice knowing when your scheduled devices are running – and sending out an email when they do is a great way to keep track! In this project we are going to send an email every time the program runs to let us know it has run as well as a few readings from our sensors. Sending an email with the Pi using Python isn’t that difficult, but there are a few steps as we need to use an external email provider to handle sending the emails. In this example we are going to use Google / Gmail. We are effectively going to create an email account for this device and give the Pi permission to send using this account. Do not use your normal email address – the email address and password are stored in plain text!

5.5%

Step 2 - Create a Gmail Account

Head on over to Gmail and create a new email account. You may need to sign out if you are already logged in with an existing account. Once that is completed – move on to step 3!  

11%

Step 3 – Set Gmail Permissions

To allow a device to use your Gmail account you will need to have 2-factor authentication enabled. This can be done through your Google Account under the Security tab – https://myaccount.google.com/security .

Once logged in, enable 2-Step Verification (if it is not already enabled). 

Once 2-Step Authentication is enabled, we can create an App Password specific to the Raspberry Pi we are sending emails from. This ensures the account password / Gmail password does not need to be stored in plain text in your code, just a device specific password. 

Click on “App Passwords” 

In the App Passwords screen, click the “Select Device” dropdown, and select “Other”

In the text box that appears, name your device. This name is just for your reference, so make it something meaningful. Once that is done, click “Generate” to create the App Password. 

Copy the password that appears – and paste it somewhere temporary while we get the code organized. This is going to be used as your Gmail Password when connecting from this device. 

16.5%

Step 4 – Back to Coding

Ok, back to coding on the Pi. We are going to start by opening Idle3 again to edit our previous Python program. The program was great for testing our sensors and solenoids, but it won’t run your sprinklers / irrigation in a way that would be desired. Once you have the program from Part 2 of this tutorial series loaded up, move on to the next step!

22%

Step 5 – Remove Un-Needed Code

This code was great for testing our components in the last part of the tutorial. Now that we know everything works, we can get on with converting it into something a little more useful. Start by removing the lines highlighted below (line 18 and lines 51 through 100):

				
					import time
from w1thermsensor import W1ThermSensor

import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)

import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

import RPi.GPIO as GPIO

ds18b20 = W1ThermSensor()

ads = ADS.ADS1015(i2c)
ads.gain = 1

interval = 5 #How long we want to wait between loops (seconds)
waterTick = 0 #Used to count the number of times the flow input is triggered

#Assign channels to variables to keep track of them easier (these BCM pin numbers were listed in part 1 of the tutorial)
s1 = 13
s2 = 16
s3 = 19
s4 = 20
s5 = 26
s6 = 21

#Set GPIO pins to use BCM pin numbers
GPIO.setmode(GPIO.BCM)

#Set digital pin 24 to an input
GPIO.setup(24, GPIO.IN)

#Set solenoid driver pins to outputs:
GPIO.setup(s1, GPIO.OUT) #set Solenoid 1 output
GPIO.setup(s2, GPIO.OUT) #set Solenoid 2 output
GPIO.setup(s3, GPIO.OUT) #set Solenoid 3 output
GPIO.setup(s4, GPIO.OUT) #set Solenoid 4 output
GPIO.setup(s5, GPIO.OUT) #set Solenoid 5 output
GPIO.setup(s6, GPIO.OUT) #set Solenoid 6 output

#Event to detect flow (1 tick per revolution)
GPIO.add_event_detect(24, GPIO.FALLING)
def flowtrig(self):
    global waterTick
    waterTick += 1

GPIO.add_event_callback(24, flowtrig)

while True:

    time.sleep(interval)
    
    #Pull Temperature from DS18B20
    temperature = ds18b20.get_temperature()
    
    #Measure Analog Input 0
    chan = AnalogIn(ads, ADS.P0) #ADS.P1 , P2, P3 for channels 1, 2, 3
    val = chan.value #Pull the raw ADC data from Channel 0
    
    waterFlow = waterTick * 2.25
    waterTick = 0
    
    #Test Solenoids by turning each on for a half second
    GPIO.output(s1, GPIO.HIGH) #turn solenoid 1 on
    time.sleep(0.5) #Wait for a half second
    GPIO.output(s1, GPIO.LOW) #turn solenoid 1 off
    time.sleep(0.5)
    
    GPIO.output(s2, GPIO.HIGH) #turn solenoid 2 on
    time.sleep(0.5) #Wait for a half second
    GPIO.output(s2, GPIO.LOW) #turn solenoid 2 off
    time.sleep(0.5)
    
    GPIO.output(s3, GPIO.HIGH) #turn solenoid 3 on
    time.sleep(0.5) #Wait for a half second
    GPIO.output(s3, GPIO.LOW) #turn solenoid 3 off
    time.sleep(0.5)
    
    GPIO.output(s4, GPIO.HIGH) #turn solenoid 4 on
    time.sleep(0.5) #Wait for a half second
    GPIO.output(s4, GPIO.LOW) #turn solenoid 4 off
    time.sleep(0.5)
    
    GPIO.output(s5, GPIO.HIGH) #turn solenoid 5 on
    time.sleep(0.5) #Wait for a half second
    GPIO.output(s5, GPIO.LOW) #turn solenoid 5 off
    time.sleep(0.5)
    
    GPIO.output(s6, GPIO.HIGH) #turn solenoid 6 on
    time.sleep(0.5) #Wait for a half second
    GPIO.output(s6, GPIO.LOW) #turn solenoid 6 off
    time.sleep(0.5)
    
    #Print the results
    print( ‘Temperature: ‘ , temperature)
    print( ‘Soil Moisture: ‘ , val)
    print( ‘Flow Rate: ‘ , waterFlow)
    print( ‘ ‘)
				
			
27.6%

Step 6 – No Loop, No Problem!

You may have noticed we have now removed the loop in this program. Since this program isn’t running all the time and we have an external method of triggering this program to run, we don’t need it! Instead, this program is going to run from start to finish once, and that’s it. Our external trigger will run it again the next time we need it. We will go a little further into how this works later on.

33.3%

Step 7 - Starting The New Code

Our new “loopless” design is going still use the majority of the original code. All of our pin assignments are the same and we still need all of the libraries. However, we do need to add a few pieces of user defined information at the top.

We are going start by creating variables to store the run duration of each sprinkler zone. The values here are going to vary wildly depending on what you are controlling. If you are watering your lawn, it may be 10 minutes, if you are running drip irrigation it could be a lot longer. So keep in mind, these variables will be something you will probably be adjusting as time goes on. 

				
					import time
from w1thermsensor import W1ThermSensor

import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)

import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

import RPi.GPIO as GPIO

ds18b20 = W1ThermSensor()

ads = ADS.ADS1015(i2c)
ads.gain = 1

waterTick = 0 #Used to count the number of times the flow input is triggered

zone1 = 6 #Zone 1 run duration in minutes
zone2 = 10 #Zone 2 run duration in minutes
zone3 = 8 #Zone 3 run duration in minutes
zone4 = 5 #Zone 4 run duration in minutes
zone5 = 7 #Zone 5 run duration in minutes
zone6 = 10 #Zone 6 run duration in minutes

#Assign channels to variables to keep track of them easier (these BCM pin numbers were listed in part 1 of the tutorial)
s1 = 13
s2 = 16
s3 = 19
s4 = 20
s5 = 26
s6 = 21

#Set GPIO pins to use BCM pin numbers
GPIO.setmode(GPIO.BCM)

#Set digital pin 24 to an input
GPIO.setup(24, GPIO.IN)

#Set solenoid driver pins to outputs:
GPIO.setup(s1, GPIO.OUT) #set Solenoid 1 output
GPIO.setup(s2, GPIO.OUT) #set Solenoid 2 output
GPIO.setup(s3, GPIO.OUT) #set Solenoid 3 output
GPIO.setup(s4, GPIO.OUT) #set Solenoid 4 output
GPIO.setup(s5, GPIO.OUT) #set Solenoid 5 output
GPIO.setup(s6, GPIO.OUT) #set Solenoid 6 output

#Event to detect flow (1 tick per revolution)
GPIO.add_event_detect(24, GPIO.FALLING)
def flowtrig(self):
    global waterTick
    waterTick += 1

GPIO.add_event_callback(24, flowtrig)

				
			
38.8%

Step 8– SMTP Library

Ok time to start setting up the Email portion of the program. We are going to add one more library to make this a little easier – add the SMTP reference to the top of the file:

				
					import smtplib
import time
from w1thermsensor import W1ThermSensor

import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)

import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

import RPi.GPIO as GPIO

ds18b20 = W1ThermSensor()

ads = ADS.ADS1015(i2c)
ads.gain = 1

waterTick = 0 #Used to count the number of times the flow input is triggered

zone1 = 6 #Zone 1 run duration in minutes
zone2 = 10 #Zone 2 run duration in minutes
zone3 = 8 #Zone 3 run duration in minutes
zone4 = 5 #Zone 4 run duration in minutes
zone5 = 7 #Zone 5 run duration in minutes
zone6 = 10 #Zone 6 run duration in minutes

#Assign channels to variables to keep track of them easier (these BCM pin numbers were listed in part 1 of the tutorial)
s1 = 13
s2 = 16
s3 = 19
s4 = 20
s5 = 26
s6 = 21

#Set GPIO pins to use BCM pin numbers
GPIO.setmode(GPIO.BCM)

#Set digital pin 24 to an input
GPIO.setup(24, GPIO.IN)

#Set solenoid driver pins to outputs:
GPIO.setup(s1, GPIO.OUT) #set Solenoid 1 output
GPIO.setup(s2, GPIO.OUT) #set Solenoid 2 output
GPIO.setup(s3, GPIO.OUT) #set Solenoid 3 output
GPIO.setup(s4, GPIO.OUT) #set Solenoid 4 output
GPIO.setup(s5, GPIO.OUT) #set Solenoid 5 output
GPIO.setup(s6, GPIO.OUT) #set Solenoid 6 output

#Event to detect flow (1 tick per revolution)
GPIO.add_event_detect(24, GPIO.FALLING)
def flowtrig(self):
    global waterTick
    waterTick += 1

GPIO.add_event_callback(24, flowtrig)

				
			
44.3%

Step 9 – Email Variables

We need to store a bunch of information for sending out emails as well. Be sure to update the email address and password in your code to match what you set up for your email account earlier.

You will also define where you want the notification to be sent to. This can be sent to any email address or, if you prefer, you can also send to a phone via email to text message. The information for this will be location and provider specific. In Canada this is typically done by emailing your phone number including area code @ your provider. This website has a listing for all major Canadian providers (External Link). Depending on your plan, charges may apply!

Starting with Line 58, add the following code:

				
					import smtplib
import time
from w1thermsensor import W1ThermSensor

import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)

import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

import RPi.GPIO as GPIO

ds18b20 = W1ThermSensor()

ads = ADS.ADS1015(i2c)
ads.gain = 1

waterTick = 0 #Used to count the number of times the flow input is triggered

zone1 = 6 #Zone 1 run duration in minutes
zone2 = 10 #Zone 2 run duration in minutes
zone3 = 8 #Zone 3 run duration in minutes
zone4 = 5 #Zone 4 run duration in minutes
zone5 = 7 #Zone 5 run duration in minutes
zone6 = 10 #Zone 6 run duration in minutes

#Assign channels to variables to keep track of them easier (these BCM pin numbers were listed in part 1 of the tutorial)
s1 = 13
s2 = 16
s3 = 19
s4 = 20
s5 = 26
s6 = 21

#Set GPIO pins to use BCM pin numbers
GPIO.setmode(GPIO.BCM)

#Set digital pin 24 to an input
GPIO.setup(24, GPIO.IN)

#Set solenoid driver pins to outputs:
GPIO.setup(s1, GPIO.OUT) #set Solenoid 1 output
GPIO.setup(s2, GPIO.OUT) #set Solenoid 2 output
GPIO.setup(s3, GPIO.OUT) #set Solenoid 3 output
GPIO.setup(s4, GPIO.OUT) #set Solenoid 4 output
GPIO.setup(s5, GPIO.OUT) #set Solenoid 5 output
GPIO.setup(s6, GPIO.OUT) #set Solenoid 6 output

#Event to detect flow (1 tick per revolution)
GPIO.add_event_detect(24, GPIO.FALLING)
def flowtrig(self):
    global waterTick
    waterTick += 1

GPIO.add_event_callback(24, flowtrig)

#Email Variables
SMTP_SERVER = 'smtp.gmail.com' #Email Server (don’t change!)
SMTP_PORT = 587 #Server Port (don’t change!)
GMAIL_USERNAME = 'youremail@gmail.com' #change this to match your gmail account
GMAIL_PASSWORD = 'yourPassword' #change this to match your gmail password

recipient = 'sendToEmail@email.com' #change this to your destination email account
				
			
50%

Step 10 – Let’s Do Something!

Ok enough setup! Now that everything is defined, we can create the bulk of the program… the part that does everything! The workflow of this program is as follows:

Program Workflow:
  Read the initial ground moisture
  Run each of our sprinklers for the specified amount of time
  Read the moisture sensor once again to see what it is at after the sprinklers have run
  Calculate the total water consumed
  Grab a temperature reading
  Construct our email and send out our data
50%

Step 11 – Initial Moisture Reading

Before we start throwing water on everything, we want to read the Soil Moisture Sensor to get an initial value. Add the highlighted code at the very bottom:

				
					import smtplib
import time
from w1thermsensor import W1ThermSensor

import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)

import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

import RPi.GPIO as GPIO

ds18b20 = W1ThermSensor()

ads = ADS.ADS1015(i2c)
ads.gain = 1

waterTick = 0 #Used to count the number of times the flow input is triggered

zone1 = 6 #Zone 1 run duration in minutes
zone2 = 10 #Zone 2 run duration in minutes
zone3 = 8 #Zone 3 run duration in minutes
zone4 = 5 #Zone 4 run duration in minutes
zone5 = 7 #Zone 5 run duration in minutes
zone6 = 10 #Zone 6 run duration in minutes

#Assign channels to variables to keep track of them easier (these BCM pin numbers were listed in part 1 of the tutorial)
s1 = 13
s2 = 16
s3 = 19
s4 = 20
s5 = 26
s6 = 21

#Set GPIO pins to use BCM pin numbers
GPIO.setmode(GPIO.BCM)

#Set digital pin 24 to an input
GPIO.setup(24, GPIO.IN)

#Set solenoid driver pins to outputs:
GPIO.setup(s1, GPIO.OUT) #set Solenoid 1 output
GPIO.setup(s2, GPIO.OUT) #set Solenoid 2 output
GPIO.setup(s3, GPIO.OUT) #set Solenoid 3 output
GPIO.setup(s4, GPIO.OUT) #set Solenoid 4 output
GPIO.setup(s5, GPIO.OUT) #set Solenoid 5 output
GPIO.setup(s6, GPIO.OUT) #set Solenoid 6 output

#Event to detect flow (1 tick per revolution)
GPIO.add_event_detect(24, GPIO.FALLING)
def flowtrig(self):
    global waterTick
    waterTick += 1

GPIO.add_event_callback(24, flowtrig)

#Email Variables
SMTP_SERVER = 'smtp.gmail.com' #Email Server (don’t change!)
SMTP_PORT = 587 #Server Port (don’t change!)
GMAIL_USERNAME = 'youremail@gmail.com' #change this to match your gmail account
GMAIL_PASSWORD = 'yourPassword' #change this to match your gmail password

recipient = 'sendToEmail@email.com' #change this to your destination email account

smStart = AnalogIn(ads, ADS.P0) #Read initial value from soil moisture sensor connected to A0
				
			
55.5%

Step 12 – Run the Sprinklers

There are many ways to do this – but we are going to keep it nice and simple. In the past we have used time.sleep() to pause a program. Since our program doesn’t do anything while each solenoid is triggered we can use this as a very primitive (and easy) way to run our sprinkler zones for the correct amount of time. It is as simple as triggering one of our solenoids, sleeping the program for the amount of time we want the water flowing, and then shutting off that solenoid.

What about the water flow? In the last tutorial we created a background process that counts the flow even while the program is paused. We left this code in place so the flow will be counted already, no need to change anything.

The times we want each of our zones to run for have already been defined. These times are stored in minutes for our own convenience, but the sleep command is expecting seconds. We will make the conversion at the time of operation by simply multiplying our minutes by 60 to get seconds.

				
					import smtplib
import time
from w1thermsensor import W1ThermSensor

import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)

import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

import RPi.GPIO as GPIO

ds18b20 = W1ThermSensor()

ads = ADS.ADS1015(i2c)
ads.gain = 1

waterTick = 0 #Used to count the number of times the flow input is triggered

zone1 = 6 #Zone 1 run duration in minutes
zone2 = 10 #Zone 2 run duration in minutes
zone3 = 8 #Zone 3 run duration in minutes
zone4 = 5 #Zone 4 run duration in minutes
zone5 = 7 #Zone 5 run duration in minutes
zone6 = 10 #Zone 6 run duration in minutes

#Assign channels to variables to keep track of them easier (these BCM pin numbers were listed in part 1 of the tutorial)
s1 = 13
s2 = 16
s3 = 19
s4 = 20
s5 = 26
s6 = 21

#Set GPIO pins to use BCM pin numbers
GPIO.setmode(GPIO.BCM)

#Set digital pin 24 to an input
GPIO.setup(24, GPIO.IN)

#Set solenoid driver pins to outputs:
GPIO.setup(s1, GPIO.OUT) #set Solenoid 1 output
GPIO.setup(s2, GPIO.OUT) #set Solenoid 2 output
GPIO.setup(s3, GPIO.OUT) #set Solenoid 3 output
GPIO.setup(s4, GPIO.OUT) #set Solenoid 4 output
GPIO.setup(s5, GPIO.OUT) #set Solenoid 5 output
GPIO.setup(s6, GPIO.OUT) #set Solenoid 6 output

#Event to detect flow (1 tick per revolution)
GPIO.add_event_detect(24, GPIO.FALLING)
def flowtrig(self):
    global waterTick
    waterTick += 1

GPIO.add_event_callback(24, flowtrig)

#Email Variables
SMTP_SERVER = 'smtp.gmail.com' #Email Server (don’t change!)
SMTP_PORT = 587 #Server Port (don’t change!)
GMAIL_USERNAME = 'youremail@gmail.com' #change this to match your gmail account
GMAIL_PASSWORD = 'yourPassword' #change this to match your gmail password

recipient = 'sendToEmail@email.com' #change this to your destination email account

smStart = AnalogIn(ads, ADS.P0) #Read initial value from soil moisture sensor connected to A0

#Run Zone 1
GPIO.output(s1, GPIO.HIGH) #turn zone 1 on
sleepTime = zone1 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s1, GPIO.LOW) #turn zone 1 off
				
			
61%

Step 13 – Run the Sprinklers Part 2

Now that we have the first zone done, just copy it for each of the remaining zones as highlighted in lines 74 – 102

				
					import smtplib
import time
from w1thermsensor import W1ThermSensor

import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)

import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

import RPi.GPIO as GPIO

ds18b20 = W1ThermSensor()

ads = ADS.ADS1015(i2c)
ads.gain = 1

waterTick = 0 #Used to count the number of times the flow input is triggered

zone1 = 6 #Zone 1 run duration in minutes
zone2 = 10 #Zone 2 run duration in minutes
zone3 = 8 #Zone 3 run duration in minutes
zone4 = 5 #Zone 4 run duration in minutes
zone5 = 7 #Zone 5 run duration in minutes
zone6 = 10 #Zone 6 run duration in minutes

#Assign channels to variables to keep track of them easier (these BCM pin numbers were listed in part 1 of the tutorial)
s1 = 13
s2 = 16
s3 = 19
s4 = 20
s5 = 26
s6 = 21

#Set GPIO pins to use BCM pin numbers
GPIO.setmode(GPIO.BCM)

#Set digital pin 24 to an input
GPIO.setup(24, GPIO.IN)

#Set solenoid driver pins to outputs:
GPIO.setup(s1, GPIO.OUT) #set Solenoid 1 output
GPIO.setup(s2, GPIO.OUT) #set Solenoid 2 output
GPIO.setup(s3, GPIO.OUT) #set Solenoid 3 output
GPIO.setup(s4, GPIO.OUT) #set Solenoid 4 output
GPIO.setup(s5, GPIO.OUT) #set Solenoid 5 output
GPIO.setup(s6, GPIO.OUT) #set Solenoid 6 output

#Event to detect flow (1 tick per revolution)
GPIO.add_event_detect(24, GPIO.FALLING)
def flowtrig(self):
    global waterTick
    waterTick += 1

GPIO.add_event_callback(24, flowtrig)

#Email Variables
SMTP_SERVER = 'smtp.gmail.com' #Email Server (don’t change!)
SMTP_PORT = 587 #Server Port (don’t change!)
GMAIL_USERNAME = 'youremail@gmail.com' #change this to match your gmail account
GMAIL_PASSWORD = 'yourPassword' #change this to match your gmail password

recipient = 'sendToEmail@email.com' #change this to your destination email account

smStart = AnalogIn(ads, ADS.P0) #Read initial value from soil moisture sensor connected to A0

#Run Zone 1
GPIO.output(s1, GPIO.HIGH) #turn zone 1 on
sleepTime = zone1 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s1, GPIO.LOW) #turn zone 1 off

#Run Zone 2
GPIO.output(s2, GPIO.HIGH) #turn zone 2 on
sleepTime = zone2 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s2, GPIO.LOW) #turn zone 2 off

#Run Zone 3
GPIO.output(s3, GPIO.HIGH) #turn zone 3 on
sleepTime = zone3 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s3, GPIO.LOW) #turn zone 3 off

#Run Zone 4
GPIO.output(s4, GPIO.HIGH) #turn zone 4 on
sleepTime = zone4 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s4, GPIO.LOW) #turn zone 4 off

#Run Zone 5
GPIO.output(s5, GPIO.HIGH) #turn zone 5 on
sleepTime = zone5 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s5, GPIO.LOW) #turn zone 5 off

#Run Zone 6
GPIO.output(s6, GPIO.HIGH) #turn zone 6 on
sleepTime = zone6 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s6, GPIO.LOW) #turn zone 6 off
				
			
66.7%

Step 14 – Read the moisture level again

Now that everything has run, lets go grab the moisture level again as seen in line 104:

				
					import smtplib
import time
from w1thermsensor import W1ThermSensor

import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)

import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

import RPi.GPIO as GPIO

ds18b20 = W1ThermSensor()

ads = ADS.ADS1015(i2c)
ads.gain = 1

waterTick = 0 #Used to count the number of times the flow input is triggered

zone1 = 6 #Zone 1 run duration in minutes
zone2 = 10 #Zone 2 run duration in minutes
zone3 = 8 #Zone 3 run duration in minutes
zone4 = 5 #Zone 4 run duration in minutes
zone5 = 7 #Zone 5 run duration in minutes
zone6 = 10 #Zone 6 run duration in minutes

#Assign channels to variables to keep track of them easier (these BCM pin numbers were listed in part 1 of the tutorial)
s1 = 13
s2 = 16
s3 = 19
s4 = 20
s5 = 26
s6 = 21

#Set GPIO pins to use BCM pin numbers
GPIO.setmode(GPIO.BCM)

#Set digital pin 24 to an input
GPIO.setup(24, GPIO.IN)

#Set solenoid driver pins to outputs:
GPIO.setup(s1, GPIO.OUT) #set Solenoid 1 output
GPIO.setup(s2, GPIO.OUT) #set Solenoid 2 output
GPIO.setup(s3, GPIO.OUT) #set Solenoid 3 output
GPIO.setup(s4, GPIO.OUT) #set Solenoid 4 output
GPIO.setup(s5, GPIO.OUT) #set Solenoid 5 output
GPIO.setup(s6, GPIO.OUT) #set Solenoid 6 output

#Event to detect flow (1 tick per revolution)
GPIO.add_event_detect(24, GPIO.FALLING)
def flowtrig(self):
    global waterTick
    waterTick += 1

GPIO.add_event_callback(24, flowtrig)

#Email Variables
SMTP_SERVER = 'smtp.gmail.com' #Email Server (don’t change!)
SMTP_PORT = 587 #Server Port (don’t change!)
GMAIL_USERNAME = 'youremail@gmail.com' #change this to match your gmail account
GMAIL_PASSWORD = 'yourPassword' #change this to match your gmail password

recipient = 'sendToEmail@email.com' #change this to your destination email account

smStart = AnalogIn(ads, ADS.P0) #Read initial value from soil moisture sensor connected to A0

#Run Zone 1
GPIO.output(s1, GPIO.HIGH) #turn zone 1 on
sleepTime = zone1 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s1, GPIO.LOW) #turn zone 1 off

#Run Zone 2
GPIO.output(s2, GPIO.HIGH) #turn zone 2 on
sleepTime = zone2 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s2, GPIO.LOW) #turn zone 2 off

#Run Zone 3
GPIO.output(s3, GPIO.HIGH) #turn zone 3 on
sleepTime = zone3 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s3, GPIO.LOW) #turn zone 3 off

#Run Zone 4
GPIO.output(s4, GPIO.HIGH) #turn zone 4 on
sleepTime = zone4 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s4, GPIO.LOW) #turn zone 4 off

#Run Zone 5
GPIO.output(s5, GPIO.HIGH) #turn zone 5 on
sleepTime = zone5 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s5, GPIO.LOW) #turn zone 5 off

#Run Zone 6
GPIO.output(s6, GPIO.HIGH) #turn zone 6 on
sleepTime = zone6 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s6, GPIO.LOW) #turn zone 6 off

smEnd = AnalogIn(ads, ADS.P0) #Read end value from soil moisture sensor connected to A0
				
			
72.2%

Step 15 – Temperature

We will grab the temperature for fun while we are at it in line 106:

				
					import smtplib
import time
from w1thermsensor import W1ThermSensor

import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)

import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

import RPi.GPIO as GPIO

ds18b20 = W1ThermSensor()

ads = ADS.ADS1015(i2c)
ads.gain = 1

waterTick = 0 #Used to count the number of times the flow input is triggered

zone1 = 6 #Zone 1 run duration in minutes
zone2 = 10 #Zone 2 run duration in minutes
zone3 = 8 #Zone 3 run duration in minutes
zone4 = 5 #Zone 4 run duration in minutes
zone5 = 7 #Zone 5 run duration in minutes
zone6 = 10 #Zone 6 run duration in minutes

#Assign channels to variables to keep track of them easier (these BCM pin numbers were listed in part 1 of the tutorial)
s1 = 13
s2 = 16
s3 = 19
s4 = 20
s5 = 26
s6 = 21

#Set GPIO pins to use BCM pin numbers
GPIO.setmode(GPIO.BCM)

#Set digital pin 24 to an input
GPIO.setup(24, GPIO.IN)

#Set solenoid driver pins to outputs:
GPIO.setup(s1, GPIO.OUT) #set Solenoid 1 output
GPIO.setup(s2, GPIO.OUT) #set Solenoid 2 output
GPIO.setup(s3, GPIO.OUT) #set Solenoid 3 output
GPIO.setup(s4, GPIO.OUT) #set Solenoid 4 output
GPIO.setup(s5, GPIO.OUT) #set Solenoid 5 output
GPIO.setup(s6, GPIO.OUT) #set Solenoid 6 output

#Event to detect flow (1 tick per revolution)
GPIO.add_event_detect(24, GPIO.FALLING)
def flowtrig(self):
    global waterTick
    waterTick += 1

GPIO.add_event_callback(24, flowtrig)

#Email Variables
SMTP_SERVER = 'smtp.gmail.com' #Email Server (don’t change!)
SMTP_PORT = 587 #Server Port (don’t change!)
GMAIL_USERNAME = 'youremail@gmail.com' #change this to match your gmail account
GMAIL_PASSWORD = 'yourPassword' #change this to match your gmail password

recipient = 'sendToEmail@email.com' #change this to your destination email account

smStart = AnalogIn(ads, ADS.P0) #Read initial value from soil moisture sensor connected to A0

#Run Zone 1
GPIO.output(s1, GPIO.HIGH) #turn zone 1 on
sleepTime = zone1 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s1, GPIO.LOW) #turn zone 1 off

#Run Zone 2
GPIO.output(s2, GPIO.HIGH) #turn zone 2 on
sleepTime = zone2 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s2, GPIO.LOW) #turn zone 2 off

#Run Zone 3
GPIO.output(s3, GPIO.HIGH) #turn zone 3 on
sleepTime = zone3 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s3, GPIO.LOW) #turn zone 3 off

#Run Zone 4
GPIO.output(s4, GPIO.HIGH) #turn zone 4 on
sleepTime = zone4 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s4, GPIO.LOW) #turn zone 4 off

#Run Zone 5
GPIO.output(s5, GPIO.HIGH) #turn zone 5 on
sleepTime = zone5 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s5, GPIO.LOW) #turn zone 5 off

#Run Zone 6
GPIO.output(s6, GPIO.HIGH) #turn zone 6 on
sleepTime = zone6 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s6, GPIO.LOW) #turn zone 6 off

smEnd = AnalogIn(ads, ADS.P0) #Read end value from soil moisture sensor connected to A0

temperature = ds18b20.get_temperature() #Get temperature from the temperature sensor
				
			
77.7%

Step 16 – Water Consumed

Just about done collecting data – let’s figure out how much water we used. Our flow sensor counts up by one every time ~2.25ml of water flows by. So we can take our count and simply multiply it by 2.25. To convert that to liters, we would then divide by 1000. Add this at line 108 and 109:

				
					import smtplib
import time
from w1thermsensor import W1ThermSensor

import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)

import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

import RPi.GPIO as GPIO

ds18b20 = W1ThermSensor()

ads = ADS.ADS1015(i2c)
ads.gain = 1

waterTick = 0 #Used to count the number of times the flow input is triggered

zone1 = 6 #Zone 1 run duration in minutes
zone2 = 10 #Zone 2 run duration in minutes
zone3 = 8 #Zone 3 run duration in minutes
zone4 = 5 #Zone 4 run duration in minutes
zone5 = 7 #Zone 5 run duration in minutes
zone6 = 10 #Zone 6 run duration in minutes

#Assign channels to variables to keep track of them easier (these BCM pin numbers were listed in part 1 of the tutorial)
s1 = 13
s2 = 16
s3 = 19
s4 = 20
s5 = 26
s6 = 21

#Set GPIO pins to use BCM pin numbers
GPIO.setmode(GPIO.BCM)

#Set digital pin 24 to an input
GPIO.setup(24, GPIO.IN)

#Set solenoid driver pins to outputs:
GPIO.setup(s1, GPIO.OUT) #set Solenoid 1 output
GPIO.setup(s2, GPIO.OUT) #set Solenoid 2 output
GPIO.setup(s3, GPIO.OUT) #set Solenoid 3 output
GPIO.setup(s4, GPIO.OUT) #set Solenoid 4 output
GPIO.setup(s5, GPIO.OUT) #set Solenoid 5 output
GPIO.setup(s6, GPIO.OUT) #set Solenoid 6 output

#Event to detect flow (1 tick per revolution)
GPIO.add_event_detect(24, GPIO.FALLING)
def flowtrig(self):
    global waterTick
    waterTick += 1

GPIO.add_event_callback(24, flowtrig)

#Email Variables
SMTP_SERVER = 'smtp.gmail.com' #Email Server (don’t change!)
SMTP_PORT = 587 #Server Port (don’t change!)
GMAIL_USERNAME = 'youremail@gmail.com' #change this to match your gmail account
GMAIL_PASSWORD = 'yourPassword' #change this to match your gmail password

recipient = 'sendToEmail@email.com' #change this to your destination email account

smStart = AnalogIn(ads, ADS.P0) #Read initial value from soil moisture sensor connected to A0

#Run Zone 1
GPIO.output(s1, GPIO.HIGH) #turn zone 1 on
sleepTime = zone1 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s1, GPIO.LOW) #turn zone 1 off

#Run Zone 2
GPIO.output(s2, GPIO.HIGH) #turn zone 2 on
sleepTime = zone2 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s2, GPIO.LOW) #turn zone 2 off

#Run Zone 3
GPIO.output(s3, GPIO.HIGH) #turn zone 3 on
sleepTime = zone3 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s3, GPIO.LOW) #turn zone 3 off

#Run Zone 4
GPIO.output(s4, GPIO.HIGH) #turn zone 4 on
sleepTime = zone4 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s4, GPIO.LOW) #turn zone 4 off

#Run Zone 5
GPIO.output(s5, GPIO.HIGH) #turn zone 5 on
sleepTime = zone5 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s5, GPIO.LOW) #turn zone 5 off

#Run Zone 6
GPIO.output(s6, GPIO.HIGH) #turn zone 6 on
sleepTime = zone6 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s6, GPIO.LOW) #turn zone 6 off

smEnd = AnalogIn(ads, ADS.P0) #Read end value from soil moisture sensor connected to A0

temperature = ds18b20.get_temperature() #Get temperature from the temperature sensor

waterUsed = waterTick * 2.25 #convert our sensor count to millilitres
waterUsed = waterUsed / 1000 #convert to liters
				
			
83.2%

Step 17 – Let’s Write An Email

In this step we are going to assemble our Email and send it! First we need to give it a subject. Next we will have to assemble all of our text for the email into one string. We don’t really want one long line of text in our email so it has been broken up into 5 pieces – one for each line of text. The “\n” is used to input a carriage return to force the next chunk of text to a new line. Finally we structure the email header, connect to Gmail and send the email. Lines 111 – 139 handle this!

				
					import smtplib
import time
from w1thermsensor import W1ThermSensor

import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)

import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

import RPi.GPIO as GPIO

ds18b20 = W1ThermSensor()

ads = ADS.ADS1015(i2c)
ads.gain = 1

waterTick = 0 #Used to count the number of times the flow input is triggered

zone1 = 6 #Zone 1 run duration in minutes
zone2 = 10 #Zone 2 run duration in minutes
zone3 = 8 #Zone 3 run duration in minutes
zone4 = 5 #Zone 4 run duration in minutes
zone5 = 7 #Zone 5 run duration in minutes
zone6 = 10 #Zone 6 run duration in minutes

#Assign channels to variables to keep track of them easier (these BCM pin numbers were listed in part 1 of the tutorial)
s1 = 13
s2 = 16
s3 = 19
s4 = 20
s5 = 26
s6 = 21

#Set GPIO pins to use BCM pin numbers
GPIO.setmode(GPIO.BCM)

#Set digital pin 24 to an input
GPIO.setup(24, GPIO.IN)

#Set solenoid driver pins to outputs:
GPIO.setup(s1, GPIO.OUT) #set Solenoid 1 output
GPIO.setup(s2, GPIO.OUT) #set Solenoid 2 output
GPIO.setup(s3, GPIO.OUT) #set Solenoid 3 output
GPIO.setup(s4, GPIO.OUT) #set Solenoid 4 output
GPIO.setup(s5, GPIO.OUT) #set Solenoid 5 output
GPIO.setup(s6, GPIO.OUT) #set Solenoid 6 output

#Event to detect flow (1 tick per revolution)
GPIO.add_event_detect(24, GPIO.FALLING)
def flowtrig(self):
    global waterTick
    waterTick += 1

GPIO.add_event_callback(24, flowtrig)

#Email Variables
SMTP_SERVER = 'smtp.gmail.com' #Email Server (don’t change!)
SMTP_PORT = 587 #Server Port (don’t change!)
GMAIL_USERNAME = 'youremail@gmail.com' #change this to match your gmail account
GMAIL_PASSWORD = 'yourPassword' #change this to match your gmail password

recipient = 'sendToEmail@email.com' #change this to your destination email account

smStart = AnalogIn(ads, ADS.P0) #Read initial value from soil moisture sensor connected to A0

#Run Zone 1
GPIO.output(s1, GPIO.HIGH) #turn zone 1 on
sleepTime = zone1 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s1, GPIO.LOW) #turn zone 1 off

#Run Zone 2
GPIO.output(s2, GPIO.HIGH) #turn zone 2 on
sleepTime = zone2 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s2, GPIO.LOW) #turn zone 2 off

#Run Zone 3
GPIO.output(s3, GPIO.HIGH) #turn zone 3 on
sleepTime = zone3 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s3, GPIO.LOW) #turn zone 3 off

#Run Zone 4
GPIO.output(s4, GPIO.HIGH) #turn zone 4 on
sleepTime = zone4 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s4, GPIO.LOW) #turn zone 4 off

#Run Zone 5
GPIO.output(s5, GPIO.HIGH) #turn zone 5 on
sleepTime = zone5 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s5, GPIO.LOW) #turn zone 5 off

#Run Zone 6
GPIO.output(s6, GPIO.HIGH) #turn zone 6 on
sleepTime = zone6 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s6, GPIO.LOW) #turn zone 6 off

smEnd = AnalogIn(ads, ADS.P0) #Read end value from soil moisture sensor connected to A0

temperature = ds18b20.get_temperature() #Get temperature from the temperature sensor

waterUsed = waterTick * 2.25 #convert our sensor count to millilitres
waterUsed = waterUsed / 1000 #convert to liters
				
			
88.7%

Step 17 – Let’s Write An Email

In this step we are going to assemble our Email and send it! First we need to give it a subject. Next we will have to assemble all of our text for the email into one string. We don’t really want one long line of text in our email so it has been broken up into 5 pieces – one for each line of text. The “\n” is used to input a carriage return to force the next chunk of text to a new line. Finally we structure the email header, connect to Gmail and send the email. Lines 111 – 139 handle this!

				
					import smtplib
import time
from w1thermsensor import W1ThermSensor

import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)

import adafruit_ads1x15.ads1015 as ADS
from adafruit_ads1x15.analog_in import AnalogIn

import RPi.GPIO as GPIO

ds18b20 = W1ThermSensor()

ads = ADS.ADS1015(i2c)
ads.gain = 1

waterTick = 0 #Used to count the number of times the flow input is triggered

zone1 = 6 #Zone 1 run duration in minutes
zone2 = 10 #Zone 2 run duration in minutes
zone3 = 8 #Zone 3 run duration in minutes
zone4 = 5 #Zone 4 run duration in minutes
zone5 = 7 #Zone 5 run duration in minutes
zone6 = 10 #Zone 6 run duration in minutes

#Assign channels to variables to keep track of them easier (these BCM pin numbers were listed in part 1 of the tutorial)
s1 = 13
s2 = 16
s3 = 19
s4 = 20
s5 = 26
s6 = 21

#Set GPIO pins to use BCM pin numbers
GPIO.setmode(GPIO.BCM)

#Set digital pin 24 to an input
GPIO.setup(24, GPIO.IN)

#Set solenoid driver pins to outputs:
GPIO.setup(s1, GPIO.OUT) #set Solenoid 1 output
GPIO.setup(s2, GPIO.OUT) #set Solenoid 2 output
GPIO.setup(s3, GPIO.OUT) #set Solenoid 3 output
GPIO.setup(s4, GPIO.OUT) #set Solenoid 4 output
GPIO.setup(s5, GPIO.OUT) #set Solenoid 5 output
GPIO.setup(s6, GPIO.OUT) #set Solenoid 6 output

#Event to detect flow (1 tick per revolution)
GPIO.add_event_detect(24, GPIO.FALLING)
def flowtrig(self):
    global waterTick
    waterTick += 1

GPIO.add_event_callback(24, flowtrig)

#Email Variables
SMTP_SERVER = 'smtp.gmail.com' #Email Server (don’t change!)
SMTP_PORT = 587 #Server Port (don’t change!)
GMAIL_USERNAME = 'youremail@gmail.com' #change this to match your gmail account
GMAIL_PASSWORD = 'yourPassword' #change this to match your gmail password

recipient = 'sendToEmail@email.com' #change this to your destination email account

smStart = AnalogIn(ads, ADS.P0) #Read initial value from soil moisture sensor connected to A0

#Run Zone 1
GPIO.output(s1, GPIO.HIGH) #turn zone 1 on
sleepTime = zone1 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s1, GPIO.LOW) #turn zone 1 off

#Run Zone 2
GPIO.output(s2, GPIO.HIGH) #turn zone 2 on
sleepTime = zone2 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s2, GPIO.LOW) #turn zone 2 off

#Run Zone 3
GPIO.output(s3, GPIO.HIGH) #turn zone 3 on
sleepTime = zone3 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s3, GPIO.LOW) #turn zone 3 off

#Run Zone 4
GPIO.output(s4, GPIO.HIGH) #turn zone 4 on
sleepTime = zone4 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s4, GPIO.LOW) #turn zone 4 off

#Run Zone 5
GPIO.output(s5, GPIO.HIGH) #turn zone 5 on
sleepTime = zone5 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s5, GPIO.LOW) #turn zone 5 off

#Run Zone 6
GPIO.output(s6, GPIO.HIGH) #turn zone 6 on
sleepTime = zone6 * 60 #multiply our run time (minutes) by 60 to get seconds
time.sleep(sleepTime ) # sleep for our duration with the solenoid open
GPIO.output(s6, GPIO.LOW) #turn zone 6 off

smEnd = AnalogIn(ads, ADS.P0) #Read end value from soil moisture sensor connected to A0

temperature = ds18b20.get_temperature() #Get temperature from the temperature sensor

waterUsed = waterTick * 2.25 #convert our sensor count to millilitres
waterUsed = waterUsed / 1000 #convert to liters

#Send Email

#Email Subject
subject = ‘Sprinkler Update’

#Email Content
line0 = ‘Run Completed \n’
line1 = ‘Starting Moisture: ‘ + str(smStart.value) + ‘\n’
line2 = ‘Ending Moisture: ‘ + str(smEnd.value) + ‘\n’
line3 = ‘Water Consumed: ‘ + str(waterUsed) + ‘\n’
line4 = ‘Temperature: ‘ + str(temperature)

emailText = line0 + line1 + line2 + line3 + line4

#Email Headers
headers = [“From: ” + GMAIL_USERNAME, “Subject: ” + subject, “To: ” + recipient, “MIME-Version: 1.0”, “Content-Type: text/html”]
headers = “\r\n”.join(headers)

#Send Email
session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
session.ehlo()
session.starttls()
session.ehlo

session.login(GMAIL_USERNAME, GMAIL_PASSWORD)

session.sendmail(GMAIL_USERNAME, recipient, headers + “\r\n\r\n” + emailText)
session.quit
#Done
				
			

Save your program – we saved it in the /home/pi/ directory to keep things simple later on. Once it is saved, feel free to test run the program with the “F5” key – however it may take a while to run through before emailing depending on the run times set for each zone. To speed it up, you could always set the zone durations shorter – just remember to set them back!

94.3%

Step 18– Schedule It To Run

Ok now that the program is done, we need to get it to run at the right times. There are many ways to write a program to run things on a schedule – we could have simply written python code to continuously check against predefined times or run every xxxxxx number of seconds. But that gets a bit clunky and complicated. Fortunately for us, the Raspberry Pi is a little more sophisticated and already has something that sort of takes care of this problem. We are going to use a really useful tool found within Raspbian (and all Unix-like operating systems) called a Cron Job. This is effectively a scheduling tool that allows you to run code / commands at predefined times or intervals – Exactly what we are looking to do! We are going to use this schedule to run a python script at our desired intervals. Once the program is done, it closes and the system will not run it again until it is scheduled. Pretty cool, huh? 

The Cron Scheduler for Raspberry Pi is a full tutorial in itself, so have a look below:

Raspberry Pi Cron Tutorial

Specifics from this project relating to the Cron Tutorial:
We saved our program as sprinkler.py in the default directory of “/pi/home” so our command to run the program is:
				
					python3 /home/pi/sprinkler.py
				
			
A few examples of schedules typically used for sprinkler systems:

This would run the script 8pm every odd numbered day from the start of May to the end of September.  

				
					0 20 1-31/2 5-9 * python3 /home/pi/sprinkler.py
				
			

This would run the script 7am every even numbered day from the start of June to the end of August.  

				
					0 7 2-30/2 6-8 * python3 /home/pi/sprinkler.py
				
			
100%

8 thoughts on “Raspberry Pi Irrigation Control – Part 3”

Leave a Reply

Your email address will not be published.

Select the fields to be shown. Others will be hidden. Drag and drop to rearrange the order.
  • Image
  • SKU
  • Rating
  • Price
  • Stock
  • Availability
  • Add to cart
  • Description
  • Content
  • Weight
  • Dimensions
  • Additional information
  • Attributes
  • Custom attributes
  • Custom fields
Click outside to hide the comparison bar
Compare