Table of Contents
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:
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:
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 <size>. Default 1920 -h, --height : Set image height <size>. Default 1080 -b, --bitrate : Set bitrate. Use bits per second -o, --output : Output filename <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 >/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. .