Mixing Electronics & Water

Enter Your Electronics & Design Project for Your Chance to Win a $100 Shopping Cart!

Back to The Project14 homepage

Project14 Home
Monthly Themes
Monthly Theme Poll

 

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.

PrimrosePrimrose

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.

Water Pump

 

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.

inside the watering systemplant warning and watering system

 

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[0]
        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[0][1])
        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)




      

 

 

ds18b20.py

# 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*')[0]
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[0].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[1].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[1][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

 

Summary

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.

Watering System Schematics

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.

 

 

System Features:

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

Relay

12V to 5V regulator

DS18B20 waterproof temperature sensor

Moisture sensor

LED Cloud

Jumpers