Thursday, November 21, 2013

Raspberry Pi Home Security System - Phase 1


I wanted to make an inexpensive home security and automation system with the following goals:
  • Home security system controlled by the internet or a 4x3 keypad
  • Use 433MHz Door/window sensors to trigger an alarm
  • Use 433MHz wireless switches to control home lighting
  • Actions on alarm trigger - Siren and send out an email/tweet
  • Future enhancements -  Laser trip wires!
Update 1: I added 2 webcams to the system and any motion now triggers an alarm as well.
Update 2: Check out phase 2 of the project here, which adds internet controlled outlet switches.
Update 3: Check out phase 3 of the project here, which adds a wireless siren + a demo video of the system.
Update 4: I swapped the 433Mhz receiver for a much better one based on reader Kris's feedback. Updated original post below.
Update 5: The information from all the phases of this project have been consolidated and written up as an instructable here: http://www.instructables.com/id/DIY-Home-Security-Automation-using-a-Raspberry-Pi/

System Overview:



For Phase 1 - I plan on enabling the home security functionality. Phase 2 will be the home automation (wireless light control etc.) and additional security features like webcam motion detection and potentially laser trip wires.

Hardware:

I picked up an inexpensive set of 433MHz transmitter-receiver modules ($2.77) and 433Mhz  door/window sensors ($12.99) from Ebay (links below)



433MHz Tx-Rx pair (set of 2)








I am now using a 433MHz receiver ($5.99) suggested by Kris (Thanks!) which is much better than the one originally recommended.  Link for that item is here:

Updated module - 433MHz super heterodyne receiver

433MHz Door/Window Sensors (set of 4)











For the input interface I picked up a 4x3 membrane keypad available on the Adafruit website ($3.95)












I have 2 webcams that I use for this project:

  1. An inexpensive USB webcam connected to the Pi directly
  2. A Tenvis JPT3815W IP Webcam connected to my home internet.


Software:

433 MHz RF communication on Pi:
I found this article on using 433MHz Tx-Rx modules with the raspberry pi. Follow the instructions here to install the 433Utils package.
http://ninjablocks.com/blogs/how-to/7506204-adding-433-to-your-raspberry-pi

A couple of points to note here:
  1. The outputs of the receiver are 5V TTL and I wasn't so pleased connecting them directly to 3.3 V tolerant Pi inputs.So I used a simple voltage divider circuit (220 ohm/440 ohm) to drop the voltage to something around 3.3 V. 
  2. The receiver from Ebay does not come with an antenna. This threw me off initially because I wasn't receiving any code unless my transmitter was few inches away from the receiver. The recommended length for an antenna for this module is a 172mm long one (1/4 wavelength).
  3. I modified RFSniffer.cpp to write to a file, if the code matched my specific transmitters.
 
  if (value == 0) {
          printf("Unknown encoding");
        } 
  else {

          printf("Received %i\n", mySwitch.getReceivedValue() );
          if (mySwitch.getReceivedValue() == enter your transmitter code here ) {
                  system("sudo echo -n 1 > trigger.txt");
          }
       }

       Run a "make" in the RPi_utils directory to create an updated executable.

You will need to install WebIOPi for the web interface. 

You will also need motion to detect movement using any webcam. Check out my previous post here to see how to set this up. 

Python code for rest of the software can be found on github:
https://github.com/tkmaker/RaspberryPiHomeAlarm

A shout out to Chris Crumpacker for enabling the 4x3 keypad code on the Pi. Thanks!

You can modify the passcode to arm/disarm the system from the keypad via keypad.py

You need to modify intruder_mail.sh with your email settings. You can also customize your email subject/message in this script.

Code overview:

There are 2 main scripts of importance -
  1. control.py - Calls keypad.py and alarm.py. Arms/Disarms the system based on web/keypad interface.
  2. alarm.py - Monitors the system status and if armed, checks for triggers before sounding an alarm.





Setup:

I have the RF receiver hooked up to my Pi (rev B) with data input on GPIO 21.

The 4x3 membrane keypad is connected as follows:
  • Pin 7 on the keypad is ROW 0- GPIO 18
  • Pin 6 on the keypad is ROW 1- GPIO 23
  • Pin 5 on the keypad is ROW 2- GPIO 24
  • Pin 4 on the keypad is ROW 3- GPIO 25
  • Pin 3 on the keypad is COL 0 - GPIO 4
  • Pin 2 on the keypad is COL 1 - GPIO 17 22
  • Pin 1 on the keypad is COL 2 - GPIO 22 10
Update: I had to change the GPIO being used here since GPIO 17 will be used by the RF transmitter (see post for phase 3) to send a code to the RF siren.

Green LED is on GPIO 7

The 2 webcams are monitored as 2 different threads via the motion software. You can check out this post here to see how to set that up.

I have modified /etc/motion/motion.conf to write to trigger.txt on motion detection.

# Command to be executed when a motion frame is detected (default: none)
on_motion_detected sudo echo -n 1 > /home/pi/trush_workdir/scripts/homealarm/trigger.txt

I also have it set up to upload images and videos to my Google drive (see my previous post for details)

Start control.py as a webiopi process:
 
sudo python control.py -m webiopi -d 8085
You can use any port of choice above. I used 8085.
You should see an interface like this once you go to your Pi IP address:8085

If you pull the website up on a touchscreen phone connected to your home internet, you can press the arm/disarm buttons to activate/de-active the system. The rest of the buttons are not enabled yet.
You can also enter the passcode (default 123) on your keypad to arm/disarm your system.
To test out the system -
  1. Arm it via the web interface or keypad - The terminal should show the status here
  2. Trigger a fake intrusion via the door sensor - Look for the alarm triggered message. The LED will blink 20 times and an email will be sent out 
  3. Disarm and arm again
  4. Trigger a fake intrusion by moving in front of the webcam - Look for the alarm triggered message. The LED will blink 20 times and an email will be sent out 
For now, the alarm action doesn't include a siren - I plan to add this as part of phase 2 as well. 
Please feel free to leave your questions and comments Any suggestions to improve or enhance the system are welcome.

Tuesday, November 12, 2013

Raspberry Pi Motion Detector


One of my first projects with a Raspberry Pi was a  motion detector for a home security application. The goal was to  alert me via an email when there was any movement detected by a webcam and also upload pictures and videos to a Google drive account. The webcam  could also be controlled remotely to view my home when I was away as well.

This post should help if you want to attempt something similar.

First off, you will need:

A webcam -  For this project I used an inexpensive Silicon Motion USB webcam which I borrowed from a friend you had it lying around. 

WiFi  - I used the popular Edimax EW-7811Un 150 Mbps Wireless 802.11bgn USB Adapter

Motion Detect Software:

Motion - An open source motion detection software

sudo apt-get install motion     

Main file of importance here is:  /etc/motion/motion.conf
Lines to modify
daemon on -> change this to  off
webcam_localhost on -> change this to  off
control_localhost on  -> change this to  off
Some useful parameters:
TCP/IP Port for remote webcam control:
control_port 8080
TCP/IP Port for remove webcam stream:
webcam_port 8081
Picture size:
width 320
height 240
Threshold for detecting motion. The threshold is the number of changed pixels counted after noise filtering, masking, despeckle, and labelling. Change this based on your personal needs.
threshold 1500

Actions to perform based on motion detect:
on_picture_save <script>
on_motion_detected <script>
on_movie_end <script>

You can customize what action you want to take based on several triggers. In my case, I used a google drive uploader script written by Peter Nichols(Thanks!).  You can copy the python code from the post here

You will need python and gdata (google data) Linux packages to get this to work.

Usage: Change the action line in the motion.conf above to this:
on_picture_save sudo python <script name> -u <google username> -p <google passwd> -l <google drive folder> -f  %f -m jpg
on_movie_end sudo python  <script name> -u <google username> -p <google passwd> -l <google drive folder> -f  %f -m mp4


You are all set!

Start the motion software in setup mode:
sudo motion -s

While running, you can see the pixel change value, noise value etc per frame. You can change the threshold value in the motion.conf file based on your specific needs. 

Test out the motion detection to see if everything works as expected.

Remote control/monitoring of the Webcam

 You can connect to your Raspberry Pi IP address with port 8080 i.e. (<my raspberry Pi IP>:8080) to control and change different parameters of your motion.conf file remotely. I will let you play around with that

You can also monitor your webcam feed via the streaming port (8081). This is useful if you want to see what is going on in your home after a motion detect alarm.

If you want to connect to your raspberry pi and motion software from a remote location, you have to setup port forwarding via your home router firewall settings. You can usually see what devices are connected to your router (via IP address) and enable certain ports for those devices (eg 8080,8081). Be careful here, since you are now opening this up to the outside world! Motion allows you for password enabled access as well (see motion.conf file) which I would highly recommend.

Please leave your comments or questions below and I will be happy to respond to them.

Monday, November 11, 2013

Raspberry Pi meets Galileo - Controlling Galileo GPIO via Pi

I wanted to control my Galileo's GPIO remotely based on user input and since I had my Raspberry Pi lying around, I decided to put it to work. Using a Raspberry Pi to control an Arduino board has been documented before, so with a little bit of exploring, I narrowed it down to 2 methods:
  1. pyserial - Allows the Pi to  communicate serially via USB. Requires a sketch to be uploaded to the Galileo first. The Pi sends commands serially to control different actions on the Galileo
  2. pyfirmata - Similar to pyserial but doesn’t require a sketch to be pre-loaded. Has the ability to drive an Arduino directly.
I will talk about #1 here since I hit issues with #2 which I will try and address sometime later.
 
Example below uses a GUI to turn the LED on Galileo pin 13 on/off.
 
Step1:
Upload this sketch to the Galileo
 
/*
Turns an LED on/off based on serial input from the Pi
*/

// Pin 13 has an LED connected on most Arduino boards.

// give it a name:

int led = 13;


// the setup routine runs once when you press reset:

void setup() {              

// initialize the digital pin as an output.

pinMode(led, OUTPUT);    
Serial.begin(9600);

}

// the loop routine runs over and over again forever:

void loop() {

if (Serial.available())

  {
    char ch = Serial.read();
   if (ch == 'a') {  

             digitalWrite(led, HIGH);   // turn the LED on

               }
   if (ch == 'A') {  

             digitalWrite(led, LOW);   // turn the LED off

               }
   }
}
Step2:
Install serialpy on the Raspberry Pi

Download pyserial-2.6.tar.gz
Make a temp folder and move the downloaded file into it.
cd temp   #Change to the temp directory   
gunzip pyserial-2.6.tar.gz    #to unzip it
tar –xvf pyserial-2.6.tar    #to untar it
cd pyserial-2.6   #move into the new folder
sudo python setup.py install   #to install it
 
Step 3:
Python script to send serial commands to the Galileo
 
import socket
from Tkinter import *

UDP_IP = "192.168.1.92"
UDP_PORT = 5005


#print "UDP target IP:", UDP_IP
#print "UDP target port:", UDP_PORT


sock = socket.socket(socket.AF_INET, # Internet
                     socket.SOCK_DGRAM) # UDP


MSG_LEDON = "LED ON"
MSG_LEDOFF = "LED OFF"

root = Tk()

def on() :
   sock.sendto(MSG_LEDON, (UDP_IP, UDP_PORT))
   return
 
def off() :
  sock.sendto(MSG_LEDOFF, (UDP_IP, UDP_PORT))
  return

 
Button(text='LED ON', command=on).pack()
Button(text='LED OFF', command=off).pack()
 
root.mainloop()
Step4:
Run the python script on the Pi. You should see a GUI like this:
  

Clicking the on/off buttons should result in the desired output on the Galileo LED.
  
The delay over serial was not noticeable for this particular applications. Plan is to play around with some motor control next.