I have a plant in my room and sometimes I can't look after it because I am away. I don't want to implement automated watering system because I want to look after the plant that is the whole point. It is a hobby I enjoy and I want to have a bond with it. It is important to water it properly hence it can die without water and also with excess water. Therefore, I will build a watering system which will somehow show the plants status and water it when I am absent. If I have enough time, it can even send me photos or tweets
These are her photo more than a month ago and now but unfortunately, she is not very healthy now Flowers are dried before they blossom but leaves are still green. Therefore, there is a hope that it will blossom in the next season. Until that, I want to make sure it is watered properly.
Update 1 - 30 March
I have run Raspberry 3 and connect relay and led cloud. I am waiting for the soil moisture sensor to set the system run. I plan to use led cloud as an indicator of water level using PWM. It will shine brighter when it gets thirsty and if no one respond system will water automatically.
The following is test code to run the relay and led cloud.
import RPi.GPIO as GPIO GPIO.setmode(GPIO.BOARD) #configure gpio physical numbering GPIO.setwarnings(False) #disable gpio warnings GPIO.setup(13,GPIO.OUT) #set pin 13 relay output GPIO.output(13,GPIO.HIGH) GPIO.setup(32,GPIO.OUT) #set pin 32 led cloud pwm output pwm = GPIO.PWM(32,10) pwm.start(50)
Update 2 - 9 April
I have got the parts and implement the system. I still missing analog to digital converter but it is running and working. My main target is to aid to look plant. It is not an automated watering system. I planned two have two thresholds for moisture level. When it goes below the first threshold blink the led cloud and after the second threshold water the plant. Hence, I cannot get two threshold setting from the sensor, I implemented supervisorily watering. The plant blink led cloud and also send me an email in case I am not at home. If I cannot go I send an email to water the plant. The program logs watering warnings and successful watering. It also records temperature data every 10 minutes. Later, I can adjust the watering based on the temperature variations. It is easy to write the program but first I need to understand more about the plant.
I have 12V 2A adapter two supply system. It goes water pump via a relay and raspberry pi after step down to 5V via a regulator. You can see the inside of the box and completed setup in the following photos.
Here is the main code. First, it configures the board and set the GPIOs. It calls ds18b20 python function which records temperature every 10 minutes. Then, it checks every hour moisture level. First, I plan to use interrupt but it is not a good idea to use it because in some level sensor fluctuates a lot and trigger the system many times. Therefore I use normal read every hour. When the water level is low, it blinks led cloud and send an email. But, email is sent based on the alarmState condition otherwise it will send an email every hour. It also checks the emails to water itself. If there is a warning and I water plant, blinking will stop in the next check. In case, I can't water the plant and send email to water it. The program will water automatically and log the watering. There is also check to prevent watering more than once in a day.
import RPi.GPIO as GPIO import ds18b20 import time from datetime import datetime import smtplib import threading import smtplib import imaplib import email date_format = "%Y %b %d %H:%M:%S" lastWaterTime = datetime.now() global AlarmState AlarmState = 0 GPIO.setmode(GPIO.BOARD) #configure gpio physical numbering GPIO.setwarnings(False) #disable gpio warnings ds18b20.logTemp() #log temperature every 10 minutes #pin setting GPIO.setup(13,GPIO.OUT) #set pin 13 relay output GPIO.output(13,GPIO.HIGH) GPIO.setup(11,GPIO.IN) #set pin 11 moisture input GPIO.setup(32,GPIO.OUT) #set pin 32 led cloud pwm output GPIO.output(32,GPIO.LOW) pwm = GPIO.PWM(32,10) pwm.stop() #water plant and log it def waterPlant(): global AlarmState delta = datetime.now() - lastWaterTime handle = open('water.log','a') logline = str(datetime.now().strftime(date_format)) if delta.days>1: #if at least one day passed GPIO.output(13,GPIO.LOW)#run pump time.sleep(5) GPIO.output(13,GPIO.HIGH)#stop pump pwm.stop() logline = 'Watering successful at ' + logline AlarmState = 0 else: logline = 'Early watering attemp ' + logline handle.write(logline + '\n') handle.close #plant needs water start warning def moistureCheck(): global AlarmState threading.Timer(3600,moistureCheck).start() if GPIO.input(11): #moisture level low handle = open('water.log','a') logline = 'Water warning at ' + str(datetime.now().strftime(date_format)) handle.write(logline + '\n') handle.close pwm.start(60) if not (AlarmState): sendAlert() read_email_from_gmail() else: #no need water AlarmState = 0 pwm.stop() def sendAlert(): # send email when plant need water server = smtplib.SMTP('smtp.gmail.com',587) server.starttls() server.login('raspberrywatering email','password') msg = 'I need water man...' server.sendmail('raspiwaterering email','my email',msg) server.quit() global AlarmState AlarmState = 1 def read_email_from_gmail(): FROM_EMAIL = "raspberrywatering email" FROM_PWD = "password" SMTP_SERVER = "imap.gmail.com" SMTP_PORT = 993 try: mail = imaplib.IMAP4_SSL(SMTP_SERVER) mail.login(FROM_EMAIL,FROM_PWD) mail.select('inbox') type, data = mail.search(None, 'UNSEEN') mail_ids = data id_list = mail_ids.split() if len(id_list) == 0:# no new message print('No new message') latest_email_id = int(id_list[-1]) rv, data = mail.fetch(str(latest_email_id), '(RFC822)' ) if rv !='OK': print('Error getting message',latest_email_id) msg = email.message_from_bytes(data) hdr = email.header.make_header(email.header.decode_header(msg['Subject'])) subject = str(hdr) if subject == 'water': waterPlant() print ('Message %s : %s' % (latest_email_id,subject)) print('Raw date:',msg['Date']) except : print ('An error is occured') moistureCheck() #event trigger is not good because sensor flactuates #GPIO.add_event_detect(11, GPIO.RISING, callback= needWater)
# Import Libraries import os import glob import time import threading from datetime import datetime date_format = "%Y %b %d %H:%M:%S" # Initialize the GPIO Pins os.system('modprobe w1-gpio') # Turns on the GPIO module os.system('modprobe w1-therm') # Turns on the Temperature module # Finds the correct device file that holds the temperature data base_dir = '/sys/bus/w1/devices/' device_folder = glob.glob(base_dir + '28*') device_file = device_folder + '/w1_slave' # A function that reads the sensors data def read_temp_raw(): f = open(device_file, 'r') # Opens the temperature device file lines = f.readlines() # Returns the text f.close() return lines # Convert the value of the sensor into a temperature def read_temp(): lines = read_temp_raw() # Read the temperature 'device file' # While the first line does not contain 'YES', wait for 0.2s # and then read the device file again. while lines.strip()[-3:] != 'YES': time.sleep(0.2) lines = read_temp_raw() # Look for the position of the '=' in the second line of the # device file. equals_pos = lines.find('t=') # If the '=' is found, convert the rest of the line after the # '=' into degrees Celsius, then degrees Fahrenheit if equals_pos != -1: temp_string = lines[equals_pos+2:] temp_c = float(temp_string) / 1000.0 return temp_c def logTemp(): threading.Timer(600,logTemp).start()#10 minutes thread temp = str(read_temp()) #read temperature print(temp) waterTime = datetime.now().strftime(date_format) time.sleep(1) handle = open('temperature.log','a') logline = waterTime + ' t= ' + temp handle.write(logline + '\n') handle.close
Update 3 - 11 April
The watering system is working for the requirements I want but later I will implement some other functions like social media interactions. That is why I called it Social Plant Watering System. You can get the schematic of the current system below. If you build the system for only watering Raspberry Pi 3 is waste of resource. Arduino will do the same job with less money and energy consumption I had temperature and watering logs. Later, If I can find a correlation between the data and health of the plant, I can modify watering or system itself can adopt the best watering time and amount with some learning skills.
Here is the demonstration of how system work. I created a fake alarm and canceled the email part to shoot the video. It will first give a warning then water the plant and clear the warning.
It measures the moisture level and warns user via led cloud and email when the water level is low.
It waters the plant when it gets an email from the user
It doesn't water more than once in a day to prevent over watering
It records temperature data every 10 minutes
It records when the watering warnings occurred and the system is watered
The parts used:
Raspberry Pi 3 - Arduino is the better use of resource if you don't do more actions. I will add a camera and use Twitter
12V Water pump
12V to 5V regulator
DS18B20 waterproof temperature sensor