Raspberry Pi 3 Motion Detection Camera With Live Feed

Introduction: Raspberry Pi 3 Motion Detection Camera With Live Feed

Introduction

In this project, you will learn how to build a motion detection camera that you will be able to use as a camera trap, a pet/baby monitor, a security camera, and much more.

This Project is organized into Several steps:

What you'll need:

  • A Raspberry Pi 3 model b ~~$35
  • 8gb Micro SD card ~~$10
  • USB Webcam ~~$20 (this project used a Logitech HD Webcam c270)
  • micro usb cable ~~$5
  • either:
  • rechargeable 5 volt battery pack (phone backup battery), this makes your project wireless ~~ $20
  • or
  • usb wall adapter ~~$5
  • A WiFi connection

What you'll need access to for setup:

  • A monitor
  • A mouse and keyboard
  • A computer with an SD card slot
  • A Micro SD to SD card converter (should come with your micro SD card)

Step 1: Setting Up Your Pi

Now let's set up your Pi

To begin, make sure you have all of the required items from the last step. Then, follow the steps on the Raspberry Pi website on installing Raspbian Jessie on your Microsd card, found here.

Once you have Raspbian installed on your Pi, it's time to get some basic features set up.

WiFi

The first step to getting the most out of your Pi is to connect your it to the internet. You may have completed this step already either by locating the WiFi symbol in the upper right corner of your Pi's main screen and signing in there, or doing the same thing before installing Raspbian in the last step. If you are unable to sign in to your WiFi network from your Pi's desktop interface, you can follow the instructions here to set up WiFi through the command line.

SSH

One very handy tool available to you when using your Pi is the option to issue commands to your Pi in what is known as a headless setup. By using a Secure SHell, or SSH, you can control your Pi remotely from a computer. With this method, all you will need to edit your Pi is a power source to keep it on, no more monitor and keyboard!


Step 2: SSHing Into Your PI

SSHing into your Raspberry Pi is easy and very useful, as the process allows you to issue commands to your Pi from any computer with nothing more than a WiFi connection.

To SSH into your Pi, you need to follow these 3 simple steps.

First, you need to enable SSH on your Pi. To do this, open up a command window in your Pi, and type in:

sudo raspi-config

This command allows you to enter a configuration menu. from there you will want to use the arrow, tab, and enter keys to go first into interfacing options, then to enable SSH, as well as the camera, then exit and reboot the pi.

Next, you'll need to find your Pi's IP address. In a command terminal, type:

sudo ifconfig

And your IP address should be in the wlan0 section that pops up, right under Link encap:ethernet. In the demo picture above, the IP Address is 192.168.1.10 .

Last, you'll need to either open up the built in terminal app on a mac, or find and follow instructions for a 3rd party ssh app for windows. In the Terminal app, type:

ssh pi@YOUR IP ADDRESS

If you haven't changed the password while in Raspi-config, then your password to enter when prompted will be the default password: raspberry.

From there, you should be good to go!

Step 3: Email Your IP Address on Boot

In this step we will focus on how to access your Raspberry Pi, regardless of the network you are on. Depending on the network, the Pi's IP address changes. And if you do not have a monitor setup, you would need to ssh into the Pi to trigger the motion detection protocol, change motion preferences, or access anything else on the device. To solve this problem we will write a python script that emails us the Pi's IP current IP address upon start up. The python script is as follows and was stored in an directory marked "background".

#start in home directory

cd ~

#create background folder

mkdir background

#create python script

sudo nano emailip.py

#write in emailip.py

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

s.connect(("8.8.8.8", 80))

print(s.getsockname()[0])x = s.getsockname()[0]s.close()

import smtplib

from email.MIMEMultipart import MIMEMultipart

from email.MIMEText import MIMEText

fromaddr = "YOUR ADDRESS"

toaddr = "RECEIVING ADDRESS"

msg = MIMEMultipart()

msg['From'] = fromaddr

msg['To'] = toaddr

msg['Subject'] = "IP Address"

body = xmsg.attach(MIMEText(body, 'plain'))

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

server.starttls()

server.login(fromaddr, "YOUR PASSWORD")

text = msg.as_string()

server.sendmail(fromaddr, toaddr, text)

server.quit()

#then this does it on reboot

sudo nano /etc/rc.local

#enter in /etc/rc.local

while ! /sbin/ifconfig wlan0 | grep -q 'inet addr:[0-9]';

do sleep 3

done

_IP=$(hostname -I) || true

if [ "$_IP" ]; then

printf "My IP address is %s\n" "$_IP"

python /home/pi/Background/emailip.py &

fi

exit 0

#and you're done

Step 4: Installing and Setting Up Motion

#update pi

sudo apt-get update

sudo apt-get upgrade

#download

sudo apt-get install motion

#now edit this file with the following changes

sudo nano /etc/motion/motion.conf

#to set a standard for this tutorial, change

#################

daemon on

stream_localhost off

webcontrol_localhost off

ffmpeg_output_movies on

target_dir /var/lib/motion

##################

#local web browser streaming options

##################

stream_maxrate 100 #This will allow for real-time streaming but requires more bandwidth & resources

framerate 60 #This will allow for 60 frames to be captured per second #the higher this gets, the slower the video processing

width 640 #This changes the width of the image displayed

height 480 #This changes the height of the image displayed

##################

#emailing video settings in .../motion.conf

##################

#delete the " ; " in front of the line, the semicolon comments the line out

on_event_start python /home/pi/background/motionalert.py %f

on_movie_end python /home/pi/background/motionvid.py %f

##################

#astectics

##################

#choices described in the file

output_pictures locate_motion_style

##################

#then change

sudo nano /etc/default/motion

#to say

start_motion_daemon=yes

#last, start the B**** up

sudo service motion start

#you can change the command to "stop", or "restart"

Step 5: Emailing Videos From Motion on Detection

Email when motion is detected:

#start at home

dircd ~

#create motion alert python script

sudo nano /home/pi/background/motionalert.py

#write

import smtplib

from datetime import datetime

from email.MIMEMultipart import MIMEMultipart

from email.MIMEText import MIMEText

fromaddr = "YOURADDRESS"

toaddr = "RECIEVINGADDRESS"

msg = MIMEMultipart()

msg['From'] = fromaddr

msg['To'] = toaddr

msg['Subject'] = "Motion Detected"

body = 'A motion has been detected.\nTime: %s' % str(datetime.now())

msg.attach(MIMEText(body, 'plain'))

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

server.starttls()

server.login(fromaddr, "YOURPASSWORD")

text = msg.as_string()

server.sendmail(fromaddr, toaddr, text)

server.quit()

Email Video of motion when video is saved:


#start at home
dircd ~

#create motion video python script
sudo nano /home/pi/background/motionvid.py

import smtplib

from email.MIMEMultipart import MIMEMultipart

from email.MIMEText import MIMEText

from email.MIMEBase import MIMEBase

from email import encoders


fromaddr = "YOUR EMAIL"

toaddr = "EMAIL ADDRESS YOU SEND TO"

msg = MIMEMultipart()

msg['From'] = fromaddr

msg['To'] = toaddr

msg['Subject'] = "Motion Cam Activated"

body = "Video of Motion Detected"

msg.attach(MIMEText(body, 'plain'))

import os

rootpath = '/var/lib/motion'

filelist = [os.path.join(rootpath, f) for f in os.listdir(rootpath)]

filelist = [f for f in filelist if os.path.isfile(f)]

newest = max(filelist, key=lambda x: os.stat(x).st_mtime)

filename = newest

import os

rootpath = '/var/lib/motion'

filelist = [os.path.join(rootpath, f) for f in os.listdir(rootpath)]

filelist = [f for f in filelist if os.path.isfile(f)]

newest = max(filelist, key=lambda x: os.stat(x).st_mtime)

attachment = open(newest, "rb")

part = MIMEBase('application', 'octet-stream')

part.set_payload((attachment).read())

encoders.encode_base64(part)

part.add_header('Content-Disposition', "attachment; filename= %s" % filename)

msg.attach(part)

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

server.starttls()

server.login(fromaddr, "YOUR PASSWORD")

text = msg.as_string()

server.sendmail(fromaddr, toaddr, text)

server.quit()

Step 6: Troubleshooting and Sources

Troubleshooting:

Because this project has multiple stages, there are several points at which things can go wrong. Below are some of the possible errors that could occur and how to fix them.

  • When setting up your pi to email you its current IP address, it is crucial to edit the rc.local file as shown earlier because this allows for a slight delay before the program activates after rebooting. Otherwise the pi will not yet be connected to wifi, and the email will not send.
  • When editing the motion.conf file make sure to delete the semicolons in front of certain parameters. The semicolon suppress a given action, so otherwise the change will not take effect.
  • The motion.conf file is very well organized and detailed. Feel free to change the settings to your liking, but understand they may effect the success of the motion capture system.
  • After setting up the email alert and email video options, it is important to note that the email of the motion detected video will take a little bit longer than to send than the initial alert email. This is because the video concludes a couple seconds after motion is no longer detected, and because the email attachment could be large enough to require a couple minutes to receive. In some cases, if motion is sustained for a very long amount of time it may be too large to send at all. Because of this it is always a good idea to check the livestream after receiving the initial alert email.

Why Motion?:

When first embarking on this project we considered several different resources. First we considered using the PiCam which is a camera unit built specifically for the raspberry pi. The PiCam is certainly a capable device and has many applications, but it is limited to using programs that are specifically designed for it and is relatively expensive compared to cheap multipurpose webcams. So in order to make this project accessible for a larger audience, we decided to use a common USB webcam. The next issue was which software to incorporate. We initially considered OpenCV which is free software that allows for many different sorts of Computer Vision and imaging projects. On of the issues here is that OpenCV is a massive file that takes up a lot of memory and a long time set up. The setup also has multiple stages, leaving even more room for error. We found that for our specific project, Motion was simpler to setup and get working, but much more robust in its execution.


Sources

Code Sources:

http://www.techradar.com/how-to/computing/how-to-b...

https://pimylifeup.com/raspberry-pi-webcam-server/

http://www.pyimagesearch.com/2015/06/01/home-surve...

http://naelshiab.com/tutorial-send-email-python/

https://www.raspberrypi.org/documentation/linux/us...

https://learn.adafruit.com/adafruits-raspberry-pi-...

https://learn.adafruit.com/adafruits-raspberry-pi-...

https://pinout.xyz/pinout/i2c


Photo credits:

SSH Snail: http://static.charlieharvey.org.uk/graphics/geeker...

Mail logo: http://www.telegraph.co.uk/content/dam/technology/...

Logitech webcam: https://assets.logitech.com/assets/55370/hd-webcam...

SSH window: https://cdn-learn.adafruit.com/assets/assets/000/0...

3 People Made This Project!

Recommendations

  • Battery Powered Contest

    Battery Powered Contest
  • Plywood Challenge

    Plywood Challenge
  • Plastic Contest

    Plastic Contest

35 Discussions

0
wayne276
wayne276

Tip 4 months ago

Motion not starting on reboot/start - tip. This problem occurred for me after setting up a second security camera raspberry pi. Nothing seemed to make the motion process start other than running a terminal command sudo service motion start . I tried many checks & solutions, including editing the motion file in /etc/default/motion and changing no to yes. A work-around that solved this was to use the crontab scheduler function, as per the helpful website: https://askubuntu.com/questions/1046980/motion-server-doesnt-start
You run sudo crontab -e
Then edit by adding the line @reboot /usr/bin/motion -b
This schedules motion to run on reboot - it worked!

0
Splodgeink
Splodgeink

5 months ago

Can anyone shed some light on how to remove the path from the emailed video as the forward strokes are replaced by underscores and that stops mobile device email apps from recognising the file. Changing the filename on the mobile device allows it to play, so the file is intact.
On a Windows 10 machine there is no problem!

Cheers
Andy

0
l2cps
l2cps

Question 1 year ago on Step 3

Hi. I wasn't able to get this part done properly: "while ! /sbin/ifconfig wlan0 | grep -q 'inet addr:[0-9]';" Is it there just for boot to wait on network, or Is it there for any other reason? I've tried few solutions and in the end just set option in raspi-config to wait for network on boot.

0
Luckydem
Luckydem

Answer 7 months ago

Hey. just in case anyone else is also struggling with this part of the code, I came across the following solution:
1: I first ran
/sbin/ifconfig wlan0 | grep 'inet addr:[0-9]'
removing the '-q' from the grep command (which runs the command in quietly - it doesn't display anything on the screen) - I realised that nothing displayed.
2: I then ran
/sbin/ifconfig wlan0
without the grep.
This displayed all the details about the wlan0.
I noticed that in the details that was returned, next to inet, the ip address followed immediately without the 'addr:' part of the grep command. so I updated the command like this:
while ! /sbin/ifconfig wlan0 | grep -q 'inet [0-9]';

3: I updated the rc.local file with the above modified command and it worked perfectly.

For those who are interested, what this line actually does is checks if there is an ip address present and only once there is one present, it continues with the next lines of code.

0
ssandbac
ssandbac

Reply 1 year ago

Hi I2cps,
Yes, that code is to wait for the network connection. When designing this project, we ran into issues with our WiFi network, specifically because it used a dynamic IP address, and used this workaround to make sure our Pi waited and connected to the network before proceeding. I like your solution too!

0
seenu0123
seenu0123

9 months ago

%Run motionvid1.py
Traceback (most recent call last):
File "/home/pi/background/motionvid1.py", line 35, in <module>
newest = max(filelist, key=lambda x: os.stat(x).st_mtime)
ValueError: max() arg is an empty sequence

0
hisunil40
hisunil40

10 months ago

Thanks for this info.
I have tried to install Motion Library on RaspberryPi via this information given above. It seems, their is serious issue between MariaDB installation as well as Motion Library installation on RaspberryPi.
I have installed MariaDB library using below link reference.
https://pimylifeup.com/raspberry-pi-mysql/
Need Motion library to capture and report live motion on RaspberryPi IP Camera, and need DB to store the configuration credentials. Can you guide please, if similar problem is observed by others, and what is possible solution on same. Many thanks,
Sunil Arora, hisunil40@gmail.com

0
tooluser1
tooluser1

Question 10 months ago on Step 6

Can this be done with the Pi Camera? It supports motion, now , doesn't it? I'm using a Pi2 with a recent pi cam . Won't the current script support this? Thanks for this great project!

0
_LOCHAN_
_LOCHAN_

10 months ago

#choices described in the file
output_pictures locate_motion_style
##################
#then change
sudo nano /etc/default/motion
#to say
start_motion_daemon=yes



bro i am not able to get,what should i do over here?

0
ashinde4
ashinde4

1 year ago

hello,
i tried to make this project but i got error as follows:
-----------------------------------------------------------------------------------------------------------
Traceback (most recent call last):
File "/home/pi/background/motionvid.py", line 20, in <module>
newest = max(filelist, key=lambda x:os.stat(x).st_mtime)
ValueError: max() arg is an empty sequence
-----------------------------------------------------------------------------------------------------------
is there any solution for it??


0
JustynaW2
JustynaW2

Reply 1 year ago

Hello, probably you have an empty /var/lib/motion directory. Make sure you have set motion config properly:
ffmpeg_output_movies on
target_dir /var/lib/motion

0
AntonM17
AntonM17

Tip 1 year ago

This line print(s.getsockname()[0])x = s.getsockname()[0]s.close() should be 3 lines. Like so

print(s.getsockname()[0])

x = s.getsockname()[0]

s.close()

Also from email.MIMEMultipart import MIMEMultipart is NOW
from email.mime.multipart import MIMEMultipart

for all those kind of imports

Had to add a device from gmail for a specific password as well.

And of course Apple can't open mime attachments so using my web Gmail client to see the vids.

Everything else is still working great as of Oct 2019 :D Thank-you again

0
kellykel9000
kellykel9000

1 year ago

Thanks for sharing and everyone for their input. Going to start woring on this since I am now to Raspberry Pi and wanted a project that gets me working on something worthwhile and trying to figure out issues or problems. I will keep you posted on my results.

0
wayne276
wayne276

1 year ago on Step 6

Hi & thanks to ssandbac for posting this excellent project. A few hiccups I overcame would be useful to share.

Firstly, in order for the emails to actually get through, you need to go into your Gmail settings & allow login from "less secure apps". This lets the raspberrypi actually log in to Gmail.

Next, it is not clear whether the Background folder actually needs to be in the /home/ directory. I put mine in /home/pi/ & this is fine, so long as the filepaths are correctly noted in the .py files and the motion.conf file you create.

Secondly, I altered the video codec to .mp4 in the motion.conf file so the vids would play easily on my phone & VLC video player.

Thirdly, I think there is an error in the rc.local code above, namely the filepath. If you have created you Background folder in /home/ then the following line from rc.local would be wrong: python /home/pi/Background/emailip.py & fi. It should be python /home/Background/emailip.py & fi. In my case it is ok as I created my Background folder in /home/pi/. Watch out for this!

The final error (I think) in the tutorial instructions is the video output directory in the motionvid.py file. Currently it says: target_dir /var/lib/motion. This wouldn't work if your motion.conf file is sending video files to /home/pi/Monitor. I guess the upshot is to keep the directory paths consistent & pointing to the same place.

Hope that's useful. My security cam works great. Just haven't got livestream going nor the sending of ip address to email, but I don't want this in any case.

0
rtek1000
rtek1000

Tip 1 year ago

The current version of the motion application is 4.2.2, but when installing via apt-get, an earlier version, such as version 4.0, may be installed.
(Files for ARMs are usually updated at a later time.)

The latest version has some improvements, and may be interesting. Look at the version modification information at this link:
https://github.com/Motion-Project/motion/releases

The below link shows how the latest version can be installed, (4.2.2 in the post comments), if necessary use the translator because it is in French.

Package: pi_stretch_motion_4.2.2-1_armhf.deb

In the most recent version (4.2.2) some command names have been modified. Some commands are not present in the configuration file, so they can be added. When the command is not present in the file, the default value can be used by the motion application.

Before upgrading your version of motion, save the settings file (motion.conf), and the videos, if not, they will be deleted. The old configuration file is for comparison of custom settings.

The attached file (motion.conf v4.2.2.txt) is the configuration file (motion.conf) for version 4.2.2 (with custom parameters - if you want to use it as is, rename it to motion.conf - Locale: /etc/motion/motion.conf)

Go to https://motion-project.github.io/motion_config.ht... and look for Configuration Options-Listed Alphabetically to compare the old names of the commands with the current ones.

Installation de MotionEye sur Raspbian Stretch sur Raspberry Pi3:
(Note: MotionEye is optional)
https://trevilly.com/installation-de-motioneye-sur...

Motion 4.2.2 Guide:
https://htmlpreview.github.io/?https://github.com/...

Installing with a release deb package:
https://htmlpreview.github.io/?https://raw.githubu...



0
rtek1000
rtek1000

1 year ago

Hello, I had problems with the network boot, so I had to redo the procedures, I found errors in the emailip.py file:

[SyntaxError: invalid syntax]

line 7:
From:
print(s.getsockname()[0])x = s.getsockname()[0]s.close()
To:
print(s.getsockname()[0])
x = s.getsockname()[0]
s.close()

line 31:
From:
body = xmsg.attach(MIMEText(body, 'plain'))
To:
body = x
msg.attach(MIMEText(body, 'plain'))

0
rtek1000
rtek1000

Reply 1 year ago

Hi @gaurangdoshi,

I believe that this kind of automation may be possible, please research the motion application documentation (Ctrl+F) on the commands supported in the project,

I believe that the command that can help you is the time limit (max_mpeg_time) for the video and the start command event.

For example, when starting the event, the script in Python could be monitoring the availability of videos (comparing movie_filename), so at each time interval send a video.

You can start with these Commands:

- max_mpeg_time (integer)
Values: 0 (infinite) - 2147483647 / Default: 3600

- movie_filename (string)
Values: Max 4095 characters / Default: %v-%Y%m%d%H%M%S
(check Conversion Specifiers)

- on_event_start (string)
The full path and file name of the program/script to be executed at the start of an event

- on_event_end

- on_motion_detected

Project links:
movie_max_time:
https://motion-project.github.io/motion_config.htm...

Conversion Specifiers:
https://motion-project.github.io/motion_config.htm...

Since the videos are being generated according to the need (10 ~ 15 seconds), help can be requested in the python language forums, for the identification and comparison of the names of the video files, the sending part of the email I believe should already serve what is available in this instructables website posting.

https://www.python.org/community/forums/

You can also contact the project developers to get some tips on how to set up the motion app in the best way for your need.

https://motion-project.github.io/motion_support.ht...

Good luck, sorry I can not help much!

0
gaurangdoshi
gaurangdoshi

1 year ago

Hi,
I have come to learn to install a security camera with live feed and email alerts for my parents house which was broken into.

I have a few questions :
1. How to get the IP address sent to my email each time the dynamic IP changes or say every 6 hrs.
2. How do I integrate PIR into the system instead of using camera motion DETECTOR? - any link ?

0
ssandbac
ssandbac

Reply 1 year ago

Hi gaurangdoshi,
For your first question, the instructable was designed to account for dynamic IP changes, so I would recommend looking at the code in that section to begin. In that section, the code only emails you the IP address at boot, so I think you would want to look for a line of code that automates the email process to occur every few hours. There also may be a line somewhere that would be able to run the code to email your IP address every time it changes.
For your second question, I don't think PIR is currently compatible with Motion, so you may want to look elsewhere for a solution to that problem.
Best of luck to you!

0
rtek1000
rtek1000

1 year ago

I modified the motionalert.py file to send the IP address along with the alert, this way I no longer need to edit the rc.local file, just add the part of the emailip.py file:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

s.connect(("8.8.8.8", 80))

print(s.getsockname()[0])

x = s.getsockname()[0]

s.close()

And modify the line:
From:
body = 'A motion has been detected.\nTime: %s' % str(datetime.now())
To:
body = '[IP:' + x + '] ' + 'A motion has been detected.\nTime: %s' % str(datetime.now())