A $50 DIY IOT solution for pet care

IOT for petcare

It all started when I got a new pet (Wall-E), a labrador puppy. When pups are small, they can’t be left alone and need a lot of your attention. If you prefer to spend your night working like me, you don’t get enough time to give proper attention to your loved pet. Small puppies doesn’t move much, they spend most of the time eating, pooping and sleeping. So, the pup only needs attention when he’s awake, Awesome! That got me thinking about designing a system that can alerts me whenever he moves.

IOT for petcare

Since, I work extensively with technologies I could easily think of systems that could easily simplify my work. Nevertheless, each and every design takes some time to get more usable, this is no exception.

What this arrangement of internet of things does for petcare?

Basically an alarm starts in your system whenever the pup moves and an email alert is sent to your mobile. The choices were made for rapid prototyping, you can select whatever medium you want to alert yourself.

Things you need to start with this IOT tutorial

To get started with this tutorial the prerequisites are:
1. 2 Wireless XBE Transceiver.
2. ATMEGA 328 PU (Microcontroller).
3. One red LED.
4. PIR Motion sensor.
5. Python installed in your computer.

You can easily buy these things from internet, no biggie here. For, installing python in your system, follow instructions here. If you are using Windows then make sure you add path to your system variables. Here’s a tutorial you can use for your reference.

What does the parts involved in this tutorial do?

PIR Motion sensor relies on light based difference. XBee Transceiver sends information ( one sends, other receives). ATMEGA Micro controller when it gets a software interrupt from digital “pin 8” of Arduino. It converts the signal in a digital form and sends it serially to transceiver while turning on Red Led at Pin 13, the transceiver in turns sends data to the other Xbee transceiver connected with PC initiating python script to send an e-mail.

Block diagram of the IOT arrangement
IOT block diagram

IOT assembly

Scripts I used for this internet of things project

Here’s the Python script that I used for this project:

import serial
 
import threading
 
import queue
 
import tkinter as tk
 
from time import sleep
 
import smtplib
 
fromaddr = 'dog.sendmail@gmail.com'
 
toaddrs  = 'my@gmail.com'
 
msg = 'Motion Detected'
 
username = 'dog.sendmail@gmail.com'
 
password = 'password'
 
import winsound

class SerialThread(threading.Thread):

    def __init__(self, queue):

        threading.Thread.__init__(self)

        self.queue = queue

    def run(self):

        s = serial.Serial('COM3',9600)

        while True:

            if s.inWaiting():

                text = s.readline(s.inWaiting())

                server = smtplib.SMTP('smtp.gmail.com:587')

                server.starttls()
                server.login(username,password)

                server.sendmail(fromaddr, toaddrs, msg)

                print('mail sent')

                server.quit()

                self.queue.put("POOP")

                winsound.PlaySound('/poop_alert/poop.wav', 

winsound.SND_ASYNC)

                sleep(100)

                self.queue.put("RESET")

                print("sentuu

                s.flush()
class App(tk.Tk):

    def __init__(self):

        tk.Tk.__init__(self)

        self.geometry("1360x750")

        frameLabel = tk.Frame(self, padx=40, pady =40)

        self.text = tk.Text(frameLabel, wrap='word', font='TimesNewRoman 37',bg=self.cget('bg'), 

relief='flat')

        frameLabel.pack()

        self.text.pack()

        self.queue = queue.Queue()

        thread = SerialThread(self.queue)

        thread.start()

        self.process_serial()

    def process_serial(self):

        while self.queue.qsize():

            try:
                self.text.delete(1.0, 'end')

                self.text.insert('end', self.queue.get())

            except Queue.Empty:

                pass

        self.after(100, self.process_serial)

app = App()

app.mainloop()

Created by Pretty R at inside-R.org

Now that you are all set with Python, let’s look at the code that I used with Audrino:

import serial
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)

int calibrationTime = 30;        

//the time when the sensor outputs a low impulse

long unsigned int lowIn;         

//the amount of milliseconds the sensor has to be low 

//before we assume all motion has stopped

long unsigned int pause = 5000;  

boolean lockLow = true;

boolean takeLowTime;  

int pirPin = 3;    //the digital pin connected to the PIR sensor's output

int ledPin = 13;

/////////////////////////////

//SETUP

void setup(){

  Serial.begin(9600);

  pinMode(pirPin, INPUT);

  pinMode(ledPin, OUTPUT);

  digitalWrite(pirPin, LOW);

  //give the sensor some time to calibrate

  Serial.print("calibrating sensor ");

    for(int i = 0; i < calibrationTime; i++){

      Serial.print(".");

      delay(1000);

      }

    Serial.println(" done");

    Serial.println("SENSOR ACTIVE");

    delay(50);

  }

////////////////////////////

//LOOP

void loop(){

     if(digitalRead(pirPin) == HIGH){

       digitalWrite(ledPin, HIGH);   //the led visualizes the sensors output pin state

       if(lockLow){  

         //makes sure we wait for a transition to LOW before any further output is made:

         lockLow = false;            

       //  Serial.println("---");

         Serial.write("motion detected  ");

         //Serial.print(millis()/1000);

         //Serial.println(" sec");

       //  Serial.write("POOP");  

         delay(50);
        }         

         takeLowTime = true;

       }

     if(digitalRead(pirPin) == LOW){       

       digitalWrite(ledPin, LOW);  //the led visualizes the sensors output pin state

       if(takeLowTime){

        lowIn = millis();          //save the time of the transition from high to LOW

        takeLowTime = false;       //make sure this is only done at the start of a LOW phase

        }

       //if the sensor is low for more than the given pause, 

       //we assume that no more motion is going to happen

       if(!lockLow && millis() - lowIn > pause){  

           //makes sure this block of code is only executed again after 

           //a new motion sequence has been detected

           lockLow = true;                        

         //  Serial.print("motion ended at ");      //output

          // Serial.print((millis() - pause)/1000);

          // Serial.println(" sec");

           delay(50);

           }

       }
}

Created by Pretty R at inside-R.org

XBee 2.4 GHz Transceiver Configuration

Coordinator Console session

+++OKATID 1000 OKATDH 0013A200OKATDL

40ADFB32OKATID1000ATDH13A200ATDL40ADFB32ATWROK

Xbee Router Configuration

Similiarly you need to configure your router using following paratmeter as lister in the table below:

Function Command Parameter
PAN ID ATID 1001 (any address from 0 to FFFE will do)
Destination address high ATDH 0013A200
Destination address low ATDL (See lower address of your Coordinator Xbee module)
Write function ATWR NA

The console session for router will look like this:

Router

+++OK

ATID 1000

OK

ATDH 0013A200

OK

ATDL 40A78409

OK

ATID 1000

OK

ATWR

This system is far from perfect, I haven’t really worked much on it. But, if you have any suggestion towards improving the system, do not hesitate to drop a comment.

References:
1. http://firstbestanswer.com/question/1z0dq9/python-code-serial-data-print-window.html
2. http://forum.arduino.cc/index.php?topic=187742.5;wap2

Leave a Reply

Your email address will not be published. Required fields are marked *