Skip to content

Instantly share code, notes, and snippets.

@mcfadden
Created July 25, 2013 23:44
Show Gist options
  • Save mcfadden/6084813 to your computer and use it in GitHub Desktop.
Save mcfadden/6084813 to your computer and use it in GitHub Desktop.
Using a Raspberry Pi + Camera Board as a high resolution IP Camera

Making an IP camera with the Raspberry Pi

Requirements

  • Raspberry Pi (512MB rev2 recommended)
  • Raspberry Pi Camera board
  • SD Card (min 2BG, 8GB recommended for good measure. Class 10)

Optionally, a wifi adapter verified to work with raspberry pi ( I used Edimax Wireless Nano USB Adapter - http://www.amazon.com/gp/product/B005CLMJLU/ )

Prepare the Pi

Image raspbian wheezy to an SD card:
  • Run diskutil list
  • Identify the SD card
  • Unmount the disk: run diskutil unmountDisk <disk> (ex: diskutil unmountDisk /dev/disk2)
  • Image the disk: sudo dd bs=1m if=2013-05-25-wheezy-raspbian.img of=<disk>
  • Remove hidden os x files
    • In terminal: cd /Volumes/boot (disk may be named something other than boot)
      • rm -rf .Trashes
      • rm -rf .fseventsd
Attach peripherals and boot the Pi
  • Attach the camera
  • Attach ethernet
  • Insert the SD card
  • Insert wifi adapter if desired
  • Attach power
Find the IP address of the pi, and SSH into it.
  • ssh pi@192.168.12.201
  • default password is "raspberry"
Run raspi-config
  • sudo raspi-config
  • Expand filesystem
  • Change user password
  • Enable camera
  • Advanced Options
    • hostname
    • memory split (I recommend 16 if running headless)
  • Finish and reboot
  • SSH back in once it's booted
Change the root password
  • sudo passwd root
Fetch any updates
  • sudo apt-get update
  • sudo apt-get upgrade -y
Reboot for good measure
  • sudo shutdown -r now

Test the camera

  • SSH into your raspberry pi: ssh pi@192.168.12.201
  • run raspistill -o test_image.jpg.
  • You should see the red light on your camera light up for a moment and then it should take a photo.
  • ls should reveal a test_image.jpg You can copy this file somewhere if you want to test further

Install mjpg-streamer

First step is to get the source onto the raspberry pi. I chose to get the source on my mac and scp it to the raspberry pi.

On your mac terminal (Not the SSH window)
  • mkdir mjpg-streamer
  • svn co https://mjpg-streamer.svn.sourceforge.net/svnroot/mjpg-streamer mjpg-streamer
  • scp -r ./mjpg-streamer pi@192.168.12.201:mjpg-streamer
Back to the SSH connection:
  • sudo apt-get install libjpeg8-dev imagemagick
  • cd mjpg-streamer/mjpg-streamer
  • make

Setting up the ram disk

In an effort to limit the amount of times your images are written to disk, let's set up a ram disk for the tmp directory. This is important as SD cards have relatively limited write cycles

  • sudo nano /etc/fstab
  • Add this line to the end of that file:
    • tmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0
    • Once you added the line, press ctrl+x it will prompt you to save, say Yes. 
  • Reboot the pi for it to take effect: sudo shutdown -r now

This says to create a virtual disk in ram for the /tmp directory. For our purposes it is totally fine to put the whole tmp directory in ram.

Testing everything

Let's make sure everything is working good here.

First we'll make a tmp directory to store the images:

mkdir /tmp/stream

Next lets start generating images with raspistill:

raspistill -w 1920 -h 1080 -q 5 -o /tmp/stream/image.jpg -tl 100 -t 99999999 &

Then we'll start the mjpg-streamer server:

LD_LIBRARY_PATH=/home/pi/mjpg-streamer/mjpg-streamer /home/pi/mjpg-streamer/mjpg-streamer/mjpg_streamer -i "input_file.so -f /tmp/stream" -o "output_http.so -w /home/pi/mjpg-streamer/mjpg-streamer/www"

You should now be able to visit your raspberry pi on port 8080 and get the mjpg video stream server.

Make a script to start the services

Let's move our process into a shell script:

Run nano ~/start_ip_camera.sh which will create a file called start_ip_camera in your home directory.

Paste this in as the contents of the file:

#!/bin/bash
if [ ! -d /tmp/stream ]
then
	mkdir /tmp/stream
fi

if ps ax | grep -v grep | grep raspistill > /dev/null
then
	echo "raspistill already running"
else
	raspistill -w 1920 -h 1080 -q 5 -o /tmp/stream/image.jpg -tl 100 -t 9999999 -th 0:0:0 &
fi

if ps ax | grep -v grep | grep mjpg_streamer > /dev/null
then
 	echo "mjpg_streamer already running"
else
	LD_LIBRARY_PATH=/home/pi/mjpg-streamer/mjpg-streamer /home/pi/mjpg-streamer/mjpg-streamer/mjpg_streamer -i "input_file.so -f /tmp/stream" -o "output_http.so -w /home/pi/mjpg-streamer/mjpg-streamer/www" -b
fi

Add execute privileges to the file: chmod +x ~/start_ip_camera.sh

And run it: ~/start_ip_camera.sh

You should now be able to access your stream again just as you did when testing on port 8080.

Have it restart automatically (and on boot)

Now we have a working script to start our IP camera! However, we don't want to have to run this every time something crashes, or the raspberry pi restarts. Since the script is pretty fast to run if the processes are running, and we want to minimize any downtime, we'll have cron run it once per minute. To do this, open up your crontab with crontab -e and paste this line at the bottom:

* * * * * /home/pi/start_ip_camera.sh

Save the crontab, and you should be done! You can test this by rebooting and seeing if it starts automatically, or by killing the process and seeing if it restarts within 1 minute.

Get WiFi working

Open sudo nano /etc/network-interfaces

You'll likely see some lines towards the end of that file similar to these:

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

Change those to be like this:

allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp
    wpa-ssid "ssid"
    wpa-psk "password"

Reboot the pi and it should be connected to WiFi now (Note: the IP address it uses to connect with WiFi is different than the one for ethernet)

Other / Optional tasks

Disable camera LED

Personally I don't want this camera to have a bright red LED on the front. Luckily fixing this is pretty easy!

Open your boot config file: sudo nano /boot/config.txt At the bottom, add this: disable_camera_led=1

Save, and reboot. When the system comes back up the camera LED will be disabled.

Change video streaming server files to remove mjpg branding

I wanted to simplify the default web access for the camera and only support two pages: A video stream, and a still image.

The files you want to change are in the ~/mjpg-streamer/mjpg-streamer/www directory. Let's start by making a backup of this directory: cp -r ~/mjpg-streamer/mjpg-streamer/www ~/mjpg-streamer/mjpg-streamer/www_backup

Then cd into the www directory: cd ~/mjpg-streamer/mjpg-streamer/www

edit and remove files in here as you wish, using the existing files as your template.

Adding a username and password

You may not want your camera open to the public. To add a username and password you will want to modify the start_ip_camera.sh script:

nano ~/start_ip_camera.sh

Modify the line that previously looked like this:

LD_LIBRARY_PATH=/home/pi/mjpg-streamer/mjpg-streamer /home/pi/mjpg-streamer/mjpg-streamer/mjpg_streamer -i "input_file.so -f /tmp/stream" -o "output_http.so -w /home/pi/mjpg-streamer/mjpg-streamer/www" -b

And make it look like this:

LD_LIBRARY_PATH=/home/pi/mjpg-streamer/mjpg-streamer /home/pi/mjpg-streamer/mjpg-streamer/mjpg_streamer -i "input_file.so -f /tmp/stream" -o "output_http.so -w /home/pi/mjpg-streamer/mjpg-streamer/www -c my_username:my_password" -b

Replace my_username and my_password with your desired username and password

Reboot the pi or kill the mjpg process and your new username and password will be required.

Changing the resolution, quality, or framerate of the stream

To change the resolution of your stream, edit the startup script and look for this line:

raspistill -w 1920 -h 1080 -q 5 -o /tmp/stream/image.jpg -tl 100 -t 9999999 -th 0:0:0 &

The -w 1920 -h 1080 is specifying the image width and height. You may change these to the size image you desire.

The -q 5 is the quality of the jpg. This is a scale from 0 to 100. Note: This will drastically change the size of your image, and thus the bandwidth requirements for the camera operation.

-tl 100 is saying take a frame every 100ms. This gives us a framerate of approximately 10fps. For a framerate of 3fps you could set it to -tl 333.

@jorge-teixeira
Copy link

hello i have a problem the camera showw the red light but dont turn off. i get : mmal: No data received from sensor. Check all connections, including the Sunny one on the camera board

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment