======= Raspberry Pi Dash-Cam ======
Developers: Gabriel Alvarado Morales & Fabiola Muñoz Ugalde
===== Objective =====
The aim here is to provide continuous, high-quality video recording in a vehicle to capture significant events without human intervention.\\
These devices are sometimes called 'dash cams' and lately have become quite popular since many drivers now rely on dashboard cameras for insurance and legal purposes.\\
In case you're involved in an accident, you will have a video record of the event for your insurance company, or if you witness an accident or any other dangerous situation, your video may help law enforcement and other emergency responders.
===== Hardware Description =====
We have used the latest Raspberry Pi model B with an 8 GB SD card, along with the Raspberry Pi camera module to improve video-recording quality and simplify the programming due to compability terms.\\
For information and details about the Raspberry Pi and it´s camera module you can visit:
http://www.raspberrypi.org/
To provide internet access to our device we used an USB Wi-Fi dongle with the Raspberry Pi.
To keep the RPi running when the ignition of the vehicle is not on, we also added an external portable battery.
===== Getting Started =====
==== Installing OS Raspbian on the Raspberry Pi ====
The Raspberry Pi will not start without a properly formatted SD Card, containing the bootloader and a suitable operating system, you should install the OS and software to the Raspberry Pi before mounting it all together. We have chosen Raspbian, as it's one of the most advanced OS for the Raspberry with loads of help and tutorials on the internet.
You need to prepare the SD card to be able to run Raspbian on the Raspberry, in order to do this, we recommend following the instructions shown in the following link:
http://elinux.org/RPi_Easy_SD_Card_Setup
==== Enabling camera support in Raspbian ====
sudo apt-get upgrade
sudo apt-get dist-upgrade
sudo raspi-config
Navigate to 'camera' and select 'enable' then select 'Finish' and reboot.
==== Firmware Update ====
In order to keep your Raspberry Pi secure, and to get updated functionality, you should get the firmware and the software updated. The firmware is a small package of code that helps the software know how to talk to the hardware.
Install software needed to perform the update:
sudo apt-get install ca-certificates git-core binutils
Download the script:
sudo wget https://raw.github.com/Hexxeh/rpi-update/master/rpi-update
Copy the script to /usr/local/bin:
sudo cp rpi-update /usr/local/bin/rpi-update
Make the script executable:
sudo chmod +x /usr/local/bin/rpi-update
Run the script:
sudo rpi-update
Every time you want to check for firmware updates, then execute:
sudo rpi-update
==== Setting up Wi-Fi ====
We used a Wi-Fi USB dongle for the Raspberry Pi to be able to connect to a wireless network, in order to make Wi-Fi work properly in the RPi you will need to do some quick additional steps:
Boot the Raspberry Pi without the WiFi adapter plugged in.
Edit the network properties of the Raspberry:
sudo nano /etc/network/interfaces
This opens an editor screen of the wifi configuration file you need to change, that should look like this:
auto lo
iface lo inet loopback
iface eth0 inet dhcp
allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp
wpa-ssid "ssid"
wpa-psk "password"
The two places where you need to make a change are on the last two lines where you should put in your network and password. Note that you need to keep the double-quote characters around your wireless network name and password.
When you have finished press [ctrl]x. This will ask if you want to save the modified files.
Press 'Y' and then Return to save the file with the same name.
Shut down your Raspberry Pi, plug the WiFi adapter in and start it up again. You should find that the Raspberry Pi connects using the WiFi adapter as it boots up.
==== Fixing a static IP address ====
To log in to your Raspberry Pi remotely, you'll need the IP of the Raspberry Pi. By default, the Raspberry Pi will be given an IP automatically by the router when you connect to a network. However, this can change whenever you remove the Pi from the network e.g. turn it off.
Having a static IP isn't essential, however it will make repeated access to the Raspberry Pi via SSH much simpler, as you'll always know that the Raspberry Pi has the same address.
In order to do so, we need to grab some information from our router and Pi. There's a couple of commands we need to run to get this info:
ifconfig
This reveals your router information, the bit you want is after wlan0 (the wireless connection):
eth0 Link encap:Ethernet HWaddr 80:lf:02:bf:lf:2a
inet addr:192.168.0.107 Bcast:192.168.0.255 Mask:255.255.255.0
Write down the following information:
inet addr – 192.168.0.107 (Pi's Current IP Address)
Bcast – 192.168.0.255 (The Broadcast IP Range)
Mask – 255.255.255.0 (Subnet Mask Address)
We need a little more information before we proceed. Use the command:
route -n
Write down the following:
gateway addr - 192.168.0.1
destination addr - 192.168.0.0
Now edit the /etc/network/intefaces file:
sudo nano /etc/network/interfaces
When you do this, as seen in the last section, you will see something like this:
auto lo
iface lo inet loopback
iface eth0 inet dhcp
allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp
wpa-ssid "my_network_name"
wpa-psk "my_password"
The line:
iface eth0 inet dhcp
Implies that we're currently getting out IP address via DHCP, meaning it's being dynamically registered by the router. This is what we want to change.
That line should now look like these:
iface eth0 inet static
Then directly below this line enter the following:
address 192.168.0.107
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255
gateway 192.168.0.1
Save the changes and reboot the Pi.
==== Installing and configuring Motion ====
Motion is a program that monitors the video signal from cameras. It is able to detect if a significant part of the picture has changed; in other words, it can detect motion.
Some of the features it allows you to monitor are:
* Capture motion
* Manage multiple cameras
* Live streaming
* Create mpeg videos using ffmpeg
* Capture images every 'x(s)' time
* Run certain commands when motion is detected
* Use data bases like MYSQL or PostgresQL to save the captures
* Manage and configure options from a web navegator
* Define motion sensibility to fit your needs
Before installing Motion ensure your Raspberry Pi is up-to-date with the latest software and firmware.
To update your RaspPi’s software, execute the following command.
sudo apt-get update && sudo apt-get upgrade
Once the updates are completed successfully, install Motion by issuing the following command:
sudo apt-get install motion
As the installation completes, you should see a warning in the command shell about Motion being disabled by default.
To enable Motion (the motion daemon), we need to edit the /etc/default/motion file.
sudo nano /etc/default/motion
Change the ‘start_motion_daemon‘ parameter to ‘yes’.
Motion is easy to customize, with a plethora of parameters you can tweak based on your needs. Since Motion has no GUI, configuration is all done through Motion’s configuration file (/etc/motion/motion.conf).
Before editing the configuration file we need to change the permissions on it, so Motion can access it. We will also change permissions on the folder where Motion stores images.
sudo chmod -R 777 /etc/motion/motion.conf
sudo chmod -R 777 /tmp/motion
Open the configuration file in Nano with the following command.
sudo nano /etc/motion/motion.conf
Motion’s configuration file is lengthy, but broken down into sections to make finding the setting you are looking for, easy.
The first thing you will want to change is Motion’s default setting that restricts image streaming to ‘localhost‘, only. This means you can only view images in a web browser on the RaspPi, not remotely on your LAN. Change that line of code to read:
webcam_localhost off
The default port for video streaming is port 8081, if you want you can change that by changing the line of code that reads:
stream_port: 8081
In order to be able to update parameters remotely via the web config interface set the control_localhost to OFF:
control_localhost off
The port that you will access the web config interface can also be changed, the default port is 8080:
control_port: 8080
You should read this file carefully and change some of the parameters to see how they behave according to your needs, it has a lot of important features that need to be taken care of.
For further information on the Motion software and its options, we recommend you check out these links:
http://www.lavrsen.dk/foswiki/bin/view/Motion/WebHome
http://www.lavrsen.dk/foswiki/bin/view/Motion/ConfigFileOptions
It’s important to remember, each time you make changes to Motion’s configuration file, you must restart Motion, using the following command.
sudo /etc/init.d/motion restart
==== Getting Motion started ====
Once we´re finished with the motion config file modifications, we´re going to test if it works properly by running motion
sudo motion
Now motion will activate and start making captures, to access them we type in our PC navegator:
http://RPi_IP:8081
Were RPi_IP refers to the IP adress of the Raspberry Pi that we found out earlier in this post.
In order to be able to update parameters remotely via the web config interface we change the port from 8080 to 8081 (that´s the way we configured it):
http://RPi_IP:8080
To make motion start up on boot:
sudo nano /etc/rc.local
This is how the rc.local file should look like:
#!/bin/sh -e
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi
# Start motion
motion
exit 0
Insert “motion” into it, then save.
==== Capturing video with the RPi camera module ====
The command used in the LXTerminal to capture video with the Raspberry Pi using the Raspberry Pi camera module is “raspivid”, which is a pretty easy command, as you will see next:
raspivid -o myvid.h264
This line records a 5 seconds video and saves it with the name myvid.
If you want more than 5 seconds, you just add the “t” option and specify a time :
raspivid -o myvid.h264 -t 60000
This will give you 60 seconds (60000 milliseconds) of video.
The default resolution is 1920×1080 with a bitrate of 17Mbs giving files of 115MB per minute. To change the video resolution to 1280×720 you can use:
raspivid -o myvid.h264 -w 1280 -h 720
and to set a custom bitrate you can use:
raspivid -o myvid.h264 -w 1280 -h 720 -b 8000000
where “8000000″ is a bitrate of 8000Kbs (kilo bits per second) or 8Mb (8 mega bits per second).
The default is usually 17000000.
As with capturing stills using raspistill there are a number of other advanced options you can use.
-w, --width : Set image width . Default 1920
-h, --height : Set image height . Default 1080
-b, --bitrate : Set bitrate. Use bits per second
-o, --output : Output filename
-t, --timeout : Duration of video (in ms)
-d, --demo : Demo mode(cycle through range of camera options, no capture)
-fps, --framerate : Specify the frames per second to record
-p, --preview : Preview window settings <'x,y,w,h'>
-f, --fullscreen : Fullscreen preview mode
-n, --nopreview : Do not display a preview window
-sh, --sharpness : Set image sharpness (-100 to 100)
-co, --contrast : Set image contrast (-100 to 100)
-br, --brightness : Set image brightness (0 to 100)
-sa, --saturation : Set image saturation (-100 to 100)
-vs, --vstab : Turn on video stablisation
-ex, --exposure : Set exposure mode
-ifx, --imxfx : Set image effect
-cfx, --colfx : Set colour effect (U:V)
-mm, --metering : Set metering mode
-rot, --rotation : Set image rotation (0, 90, 180, 270)
-hf, --hflip : Set horizontal flip
-vf, --vflip : Set vertical flip
To list all available options you can type :
raspivid | less
===== Implementation =====
==== Auto Start & Auto Login ====
Edit the file /etc/inittab and comment out the line:
1:2345:respawn:/sbin/getty -noclear 38400 tty1
Below it add the line:
1:2345:respawn:/bin/login -f pi tty1 /dev/tty1 2>&1
This does is an automatic login on tty1 (the first terminal), so a sudo reboot should now login the user pi automatically.
To start a script off when the RPi boots, follow the next steps.
Edit .bashrc and add this code to the end of the file:
if [ -z "$DISPLAY" ] && [ $(tty) == /dev/tty1 ]; then
./dashcam.sh &
fi
After those modifications the Raspberry Pi will auto-boot when powered up and our dashcam application will then auto-run.
==== dashcam.sh ====
This is a shell script that is run automatically, when the Raspberry Pi boots up. It does a few initialisation tasks and runs our dashcam.py Python code in the background.
It has a control loop that records 5 minute video segments, each with a filename that is based on the start time and date (e.g. 2013_12_11_16:34:45.h264). After each recording the allocated storage space is measured and older files deleted to bring usage down below a pre-set limit (in our case it´s 6 GB).
The program loop runs until the contents of a file called dashcam.mode (which is created the first time the program runs in the directory /home/pi) are changed from 'exit' or 'shutdown' to 'record' or 'parked'.
#!/bin/sh
echo `date +%s` "! started dashcam.sh"
# Start the dashcam python code
sudo python dashcam.py &
# Set limit of rolling videos to 6GB
limit=6000000
echo "standby" > dashcam.mode
# Creates a file named dashcam.mode and adds the content "standby" on it
mode=$(cat dashcam.mode)
# The variable mode saves the content that is currently in the dashcam.mode file
previous="dummy.h264"
current="dummy.h264"
# Variables destined to set the videos names
# Main process
while [ true ]; do
# check Video folder disk space used
used=$(du Video | tail -1 | awk '{print $1}')
echo `date +%s` "U Video" $used
# Compare $used with $limit
# Free up disk space if needed
while [ $limit -le $used ]; do
remove=$(ls -1tr Video | grep .h264 | head -n 1)
echo `date +%s` "-" $remove
rm Video/$remove
# Calculate disk space used
used=$(du Video | tail -1 | awk '{print $1}')
done
# Check commands
# if exit is requested, then stop and shutdown
mode=$(cat dashcam.mode)
if [ "$mode" = "exit" ]
then
echo `date +%s` "! stopped dashcam.sh"
# Shutdown the RPi, so we can safely remove power
sudo shutdown -h now
exit
fi
# if car ignition is on or if motion is detected then record video
if [ "$mode" = "record" ] || [ "$mode" = "parked" ]
then
# New file name
previous=$current
current=$(date +"%Y_%m_%d_%H:%M:%S.h264")
echo `date +%s` "+" $current
# Capture a 5 minute segment of video
raspivid -n -b 9000000 -w 1280 -h 720 -o Video/$current -t 300000
fi
done
==== dashcam.py ====
This is a Python script that is also auto-started. It monitors the GPIO pins and writes control commands to the dashcam.mode file.
#!/usr/bin/env python
import datetime
import RPi.GPIO as GPIO
import time
import pytransfer as pt
def Log(t, s):
print time.time(),t,s
Log("!", "started dashcam.py")
internet=False
# Set mode
GPIO.setmode(GPIO.BCM)
# Hide warnings
GPIO.setwarnings(False)
# Setup inputs
# Record = Button1 = GPIO24 = Board 18
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
#Ignition cut
GPIO.setup(25, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
#Parking move sensor
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
#set outputs
# Record led
GPIO.setup(18, GPIO.OUT)
GPIO.output(18, GPIO.LOW)
#Parking led
GPIO.setup(22, GPIO.OUT)
GPIO.output(22, GPIO.LOW)
#IGNICION CUT led
GPIO.setup(17, GPIO.OUT)
GPIO.output(17, GPIO.LOW)
# Intialise dashcam
print "mode Standby"
mode = 'stdby'
#Log("M", "%s" % mode)
ignition=GPIO.input(24)
ignition_cut=GPIO.input(25)
parking_sens=GPIO.input(23)
while True:
internet=pt.check_internet()
while internet == False:
while True:
if (ignition==True):
print "detectado record"
global mode
mode = "record"
with open("dashcam.mode", "w") as the_file:
the_file.write(mode)
time.sleep(1)
GPIO.output(18, GPIO.HIGH)
GPIO.output(22, GPIO.LOW)
GPIO.output(17, GPIO.LOW)
if (ignition_cut==True):
print "ignition cut"
global mode
mode = "exit"
with open("dashcam.mode", "w") as the_file:
the_file.write(mode)
time.sleep(1)
GPIO.output(18, GPIO.LOW)
GPIO.output(22, GPIO.LOW)
GPIO.output(17, GPIO.HIGH)
if (parking_sens==True):
print "move detected"
print "start record"
global mode
mode = "record"
with open("dashcam.mode", "w") as the_file:
the_file.write(mode)
time.sleep(1)
GPIO.output(18, GPIO.LOW)
GPIO.output(22, GPIO.HIGH)
GPIO.output(17, GPIO.LOW)
ignition=GPIO.input(24)
ignition_cut=GPIO.input(25)
parking_sens=GPIO.input(23)
internet=pt.check_internet()
==== pytransfer.py ====
This python code contains the functions that sends the video file through a FTP connection and checks if there is an internet connection. Then this program is shown:
#!/usr/bin/env python
mport urllib2 #Library that allows opening URLs
import ftplib #Python FTP protocol client
import datetime as d #Module that supplies classes for manipulating dates and times
import sys #Module that provides specific system functions
def check_internet(): #Check if there is an internet connection
try:
response=urllib2.urlopen('http://www.google.com',timeout=1)
return True
except urllib2.URLError as err:
pass
return False
def transfer(filename): #Transfer file via FTP
# FTP Data
ftp_server='192.168.X.X' # Server IP
ftp_user='fabiolamuug'
ftp_pass='12345'
ftp_route='/home/fabiolamuug/videos' # Destination directory
dest_file=filename
try:
s=ftplib.FTP(ftp_server, ftp_user, ftp_pass)
try:
f=open("video/"+filename, 'r+')
except:
print "File not found " + "video/"+filename
sys.exit(0)
try:
s.cwd(ftp_route)
s.storbinary('STOR ' + dest_file, f)
f.close()
s.quit()
except:
print "Transfer error"
sys.exit(0)
else:
print "Successful transfer"
except:
print "Error in connection to server " + ftp_server
sys.exit(0)
The function “check_internet()” is connected to the page http://www.google.com and expects a satisfactory answer, if after a second it does not, an error occurs and it is interpreted as there is not internet connection, otherwise states that there is a connection to the network.
This function is called in dashcam.py. To transfer files via FTP it is used the function “transfer” that receives the argument “filename”. Here you assign the server user name, password, the path to keep the video and IP address.
It is important to note that the file transfer is only allowed on a local network, to transmit a file from another network you have to properly configure your FTP server. The function has multiple errors catchings for the different errors that can occur during the transferring and prints the corresponding message.
.