Making it more intelligent
Congratulations on making your first robot! But did you notice one problem? The robot we made was continuously looking for a moisture value and, as soon as it noticed that the moisture value was low, it suddenly pumped water and made sure that the humidity of the soil was always more than 20%. However, this is not required. In general, we water the garden once or twice a day. If we water it more then it might not be good for the plants.
So, let's go ahead and make it slightly more intelligent and make it water the plants only when the moisture level is low at a certain time. This time, we won't need to make any changes to the hardware; we simply need to tweak the code.
Let's go ahead and upload the following code, and then see what exactly happens:
from time import sleep
from datetime import datetime
import RPi.GPIO as GPIO
import Adafruit_ADS1x15
water_valve_pin = 23
moisture_percentage = 20
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(water_valve_pin, GPIO.OUT)
adc = Adafruit_ADS1x15.ADS1115()
GAIN = 1
def check_moisture():
adc.start_adc(0,gain= GAIN)
moisture_value = adc.get_last_result()
moisture_value = int(moisture_value/327)
if moisture_value < moisture_level:
GPIO.output(water_valve_pin, GPIO.HIGH)
sleep(5)
GPIO.output(water_valve_pin, GPIO.LOW)
else:
GPIO.output(water_valve_pin, GPIO.LOW)
while True:
H = datetime.now().strftime('%H')
M = datetime.now().strftime('%M')
if H == ‘07’ and M <= ‘10’:
check_moisture()
if H == ‘17’ and M <= ‘01’:
check_moisture()
This code might look a little alien to you, but trust me, it is as simple as it can get. Let's see what's happening step by step:
from datetime import datetime
This line of code is importing daytime instances from the date time library. This is a library which is by default in Python. All we need to do is to call it. Now, what it does is that without any hustle and bustle, it helps us determine the time within our code:
def check_moisture():
There are several times when we have to do something over and over again. These sets of code can be a few repetitive lines or multiple pages of code. Hence, rewriting that code doesn't make sense at all. We can create a function. In this function, we can define what will happen whenever it is called. Here in this line, we have created a function by the name of check_moisture(); now, whenever this function is called within a program, there will be a set of activities that will be performed. The set of activities that will be performed is defined by the user. So, whenever we write def, then it means that we are defining a function; thereafter, we write the name of the function that needs to be defined.
Once done, then whatever we write in the indentation following it will be done once the function is called. Do remember that whenever we call or define a function, it is denoted by an open and a closed () bracket at the end of the name of the function:
moisture_value = adc.get_last_result()
adc.get_last_result() is a function of adc. The activity it does is to simply take the result from the pin defined earlier (pin number 0) and fetch the reading to a variable moisture_value. So, after the line moisture_value will be the reading of the pin number 0 of the ADC or, in other words, the reading of the moisture sensor:
H = datetime.now().strftime('%H')
The code datetime is an instance and a method of .now(). What this function does is that it updates the time. Now, the date time.now() has updated all the parameters of date and time which includes the hours, minutes, seconds, and even the date. It is up to us whether we want all of it or any specific part of the date and time. At present, we want to put the value of hours in the variable H, hence we are using a .strftime('%H') method. strftime stands for string format of time. So whatever value it outputs is in string format. ('%H') means that it will give us the value of the hours only. Similarly, we can also get the time in minutes by using ('%M') and ('%S). We can also get the value of the date, month, and year with the following syntax:
- For getting the date: ('%d')
- For getting the month: ('%m')
- For getting the year: ('%Y')
if H == ‘07’ and M <= ‘10’:
In the preceding condition, we are checking if the time is 7 o'clock or not; further, we are also checking if the time is less than or equal to 10 minutes or not. So this piece of code will only run the statement in the if statement when the time is 7 hours and between 0 and 10 minutes.
One thing to particularly note is that we have used an and between both the conditions, hence it will only run the code inside it once both the statements are absolutely true. There are some other statements we can use inside it, as well, such as or, in which case it will run the code if either of the statements is true.
If we replace and with or in this if statement, then it will run the code for every 0 to 10 minutes of every hour and will run the code continuously for the entire time between 7:00 a.m. and 7:59 a.m.:
check_moisture()
As you may remember, previously we defined a function by the name of check_moisture(). While defining that function, we had also defined the set of activities that would happen every time this function is called.
Now is the time to call that function. As soon as the program reaches this end of the code, it will execute the set of activities that was earlier defined in the function.
So there we have it. Now, as soon as you run this code, it will wait for the time defined by you in the program. Once the specific time has been reached, then it will check for the moisture. If the moisture is less than the set value then it will start to water the plants until the time the moisture reaches above that threshold.