Introduction: Raspberry Pi Cloud IP Camera With POE

Picture of Raspberry Pi Cloud IP Camera With POE

I was inspired by scavix's work with the instructable Raspberry Pi as low-cost HD surveillance camera so I decided to make my own Raspberry PI based IP camera that also features POE and supports integration with the Google Drive.

The video streaming can be simply viewed from a web browser. Most desktop browsers should work, I have also tested with Firefox for Android and it seems to work fine. It is also possible to view the video stream from multiple cameras the same time by making a simple HTML file, but more about that later.

The camera footage is saved in the form of JPEG images instead of video files in order to make the uploading to the Google Drive easier for Internet connections with low upload speeds. To prevent Google Drive from running out of space, every one hour the system checks for any images that are older from a specific threshold (e.g. 2 days) and automatically deletes them. After that it syncs the local footage directory with the Google Drive.

All the partitions on the microSD are read-only to prevent corruption from power failures. An external USB drive is also used to keep the /var and /home partitions which they both need to be read-write. That way the system is unlikely to become unbootable from a power failure since the microSD is 100% read-only.

I built two of those IP cameras a while ago and they have been tested on production environment (a small retail store) for more than a year and they have shown absolutely no issues. Since the day they have been installed both cameras have 100% uptime. So I'm pretty confident that they can be used as low cost alternative to commercial IP cameras in a small business.

Step 1: Tools and Parts

Picture of Tools and Parts

To build the camera you will need the following parts:

  • A Raspberry Pi Model B+[30€] - It will also work with a Model B but it won't fit in the housing I used. I haven't tested it with a Raspberry Pi 2 but I think it should work.
  • A Raspberry Pi Camera Module[30€] - Plus at least two screws that fit its mounting holes.
  • An 8GB Class10 MicroSD[5€] - I used a Kingston SDC10. A larger capacity MicroSD can also be used but it won't make a big difference.
  • A TP-LINK TL-POE10RPOE Splitter[16€] - You can use any POE Splitter that supports the 802.3af POE standard but this particular one fits perfectly inside the housing I used.
  • A POE Injector (or a POE Switch) - This is not part of the camera itself but you will need it to power the camera. I used a TP-LINK TL-SF1008P POE Switch [40€] since I have more that one IP camera (it supports up to four), but for just one camera I recommend the TP-LINK TL-POE150S POE Injector [25€]. If you can't find either of those, any injector or switch that supports the 802.3af POE standard should work.
  • 1 x Dummy IP Camera for the housing [9€] - I highly recommend getting the same with me because all the hardware fits perfectly inside. You can find it fairly easily if you search on ebay for “dummy ip ir camera” (you can find it in either silver or black color).
  • 2 x RJ45 jacks plus a small piece of UTP cable (Cat5e or Cat6) [less than 1€]
  • 2 x Female to Female Jumper Wires [less than 1€]
  • 1 x Hot Glue Stick
  • Solder Wire and Solder Wick

And the following tools:

  • A Soldering Iron
  • A Hot Glue Gun
  • A Desoldering Pump - Optional if you have solder wick.
  • A Dremel with a disk that can cut plastic plus drill bits
  • An RJ45 Crimping Tool

The total cost of the camera parts (excluding the POE Injector/Switch and the tools) is around 100€. The prices can vary depending where you live and from where you bought them.

Step 2: Preparing the MicroSD

Burning the Installer Image to the microSD:

As base for the system I decided to use a bare minimum Raspbian install and on top of it install only the required packages. That way the system is going to be more secure, more stable and there will be no waste of resources for things that are not required.

To get started first download the Raspbian NetInstall image from Githuband burn it to your microSD.

If you are using Linux just download the latest raspbian-ua-netinst-<latest-version-number>.img.xz file and use the following command:

xzcat /path/to/raspbian-ua-netinst-<latest-version-number>.img.xz > /dev/sdX

Where X is the letter of the device that corresponds to your microSD e.g. c. Before running the command make sure that there are no mounted partitions that belong to the microSD. In case there are use the following command to unmount each one of them:

umount /dev/sdXY

In case you got a permission denied error try the following command:

xzcat /path/to/raspbian-ua-netinst-<latest-version-number>.img.xz | sudo tee /dev/sdX > /dev/null

But be extremely carefully here, using the wrong letter in place of X may do irreversible damage to your system and ruin your day. Before running the command double check that the letter you typed in place of X is really the one that corresponds to the microSD.

If you are using Windows download the raspbian-ua-netinst-<latest-version-number>.zip file instead. Format then your microSD as FAT32 and extract the installer files in it.

Installing the System:

When the installer is finally written to the microSD it's time to install the system. The installation process is completely automated and non-interactive, the only thing you need to do is to insert the microSD to your Raspberry Pi, plug it in to your router using an Ethernet cable, connect the camera module, plug the power cable and it will automatically start to download and install the packages. The installation process takes around 45 to 60 minutes depending on the speed of your Internet connection. If you have an HDMI cable and a monitor you can keep an eye to the installation process. If you don't have a display attached you can monitor the Ethernet controller LEDs to guess activity.

Step 3: Establishing an SSH Connection

When the installation is finally complete the Raspberry Pi will automatically reboot and then you will be able to connect to it through SSH. On the first boot the Pi is going to get dynamically an IP address from the DHCP server of your router, so at first you will need to discover its IP address. On Linux this is fairly easy, you can just run the following nmap command as root:

nmap -sn x.x.x.x/y

Where x.x.x.x is the IP address of your private network e.g. 192.168.1.0 and the y is the number of ones (in binary) of the network mask e.g. for the network mask 255.255.255.0 the number of ones is 24. So, for that particular network you would run:

nmap -sn 192.168.1.0/24

An example output for this command is the following:

Starting Nmap 6.47 (  http://nmap.org  ) at 2015-09-08 17:29 EEST
Nmap scan report for 192.168.1.1 Host is up (0.00059s latency). MAC Address: 12:95:B9:47:25:4B (Intracom S.A.) Nmap scan report for 192.168.1.2 Host is up (0.0075s latency). MAC Address: 1D:B8:77:A2:58:1F (HTC) Nmap scan report for 192.168.1.4 Host is up (0.00053s latency). MAC Address: 88:27:F9:43:11:EF (Raspberry Pi Foundation) Nmap scan report for 192.168.1.180 Host is up. Nmap done: 256 IP addresses (4 hosts up) scanned in 2.13 seconds

As you can see in my case the Pi has the IP address 192.168.1.4.

Another way to obtain the IP address of your Pi is to check the logs of the DHCP server of your router. Every router is different so I'm not going to describe that process. There is also a version of nmap for Windows that you can try.

When you obtain the IP address of your Pi you can SSH to it using the following command on Linux:

ssh root@<ip-address-of-raspberry-pi>

Or by using PuTTY on Windows.

The default root password is raspbian.

Step 4: Configuring the System

On the first boot the system is almost completely unconfigured so there are some tasks you will need to do first.

The very first thing you need to do is to change the default root password by running:

passwd

Then, you will have to configure the locales. You can do this by running the following command:

dpkg-reconfigure locales

Go ahead and select all the en_US locales by using the space bar plus any other locales you want. When you are done hit Enter. Lastly, select the en_US.UTF-8 as the default locale and hit Enter.

Next you will need to configure the timezone. To do this run the following command:

dpkg-reconfigure tzdata

At this point it's a good idea to do some updates:

apt-get update
apt-get upgrade
apt-get dist-upgrade

Next thing you need to do, is to install a text editor in order to be able to edit configuration files. One of the easiest to use terminal text editors is nano:

apt-get install nano

When you are done editing a file using nano hit Ctrl-X to exit, type y and finally hit Enter to save the changes.

Next you need to create a normal user to use instead of root to make the system more secure and also reduce the risk of human error:

useradd raspcam
passwd raspcam
mkdir /home/raspcam
chown raspcam:raspcam /home/raspcam

And to change the default shell to bash run:

nano /etc/passwd

And replace /bin/sh with /bin/bash on the line that starts with raspcam.

Now you need to give that user the ability to do things that require root access so you need to install sudo:

apt-get install sudo

Then to give your user the ability to use sudo run:

visudo

And right after the line:

root    ALL=(ALL:ALL) ALL

put the following line:

raspcam    ALL=(ALL:ALL) ALL

Finally, run:

su - raspcam

From now on you will use that user for anything you want to do and when you need root access you will use sudo.

Next to make the system a little more secure it's a good idea to prevent root login through SSH. So, run:

sudo nano /etc/ssh/sshd_config

And on the line:

PermitRootLogin yes

Change the yes to no.

Next, install the raspi-copies-and-fills package for improved memory management performance:

sudo apt-get install raspi-copies-and-fills

Now it's a good time to give your Pi a static IP so you won't have to search what IP address it has all the time. To do so you need to edit the /etc/network/interfaces configuration file:

sudo nano /etc/network/interfaces

Your /etc/network/interfaces needs to have the following format:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address x.x.x.x
    netmask y.y.y.y
    gateway z.z.z.z

In order for the Raspberry Pi to be able to communicate with the rest of the network (including your own computer) you need to make sure that the netmask, and the gateway fields are exactly the same with your own computer. The address can be any valid IP address as long as it belongs to the same network with your own computer and does not conflict with another one, that has been already allocated from the DHCP server of your router to another device.

To figure out what to use for the address, the netmask, and the gateway, you need to check the network configuration of your own computer.

If you are using Linux run the following command as root:

ifconfig 

And you will get an output similar to the following:

eth0      Link encap:Ethernet  HWaddr 11:22:33:aa:bb:cc  
          inet addr:192.168.1.4  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::2a10:7bff:fec5:6bc4/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1917143 errors:0 dropped:1 overruns:0 frame:0
          TX packets:2092796 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:642211523 (612.4 MiB)  TX bytes:1122273820 (1.0 GiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:72892 errors:0 dropped:0 overruns:0 frame:0
          TX packets:72892 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:11713024 (11.1 MiB)  TX bytes:11713024 (11.1 MiB)

As you can see in this example this particular machine has the IP address 192.168.1.4, the broadcast address of the current network is 192.168.1.255 and the network mask is 255.255.255.0. From that information you already know what to use for the netmask field.

Now to find out the gateway IP address (which is the IP address of your router) you can run the following command as root:

route -n

This will give you an output similar to the following:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG    1024   0        0 eth0
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0

The gateway is the IP address that has as its destination the IP address 0.0.0.0. In this example the gateway IP is 192.168.1.1.

Lastly, for the address field you can use any IP address between 192.168.1.1 and 192.168.1.254 as long as it's not the gateway address and it does not conflict with the IP of another device on the network. I suggest using an IP address like for example 192.168.1.100 so the risk of conflict will be very small. Furthermore, an IP address like this will be easier to remember.

If you want to be extra sure that the IP of the Pi will never conflict with the IP address of another device, you will need to configure the DHCP server of your router to exclude that IP from its address pool. Unfortunately, I cannot describe how to do that since every router is different.

If you are using Windows you can find out what address, netmask, and gateway to use in the same way by running the following command on the command line:

ipconfig /all

So, for our example the /etc/network/interfaces would look like the following:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 192.168.1.100
    netmask 255.255.255.0
    gateway 192.168.1.1

Next you need to set the nameservers. To do that run:

sudo nano /etc/resolv.conf

Typically, the primary nameserver will be your router, for the secondary nameserver you can use the Google Public DNS which is 8.8.8.8. To add the Google Public DNS as the secondary nameserver, at the end of the config file add the following line:

nameserver 8.8.8.8

Finally, for the changes to take effect you need to restart the networking service:

sudo /etc/init.d/networking restart

After restarting the networking service the SSH session is going to hang, because the IP of the Raspberry Pi has now changed so you will have to reconnect, but this time using the new user you created instead of root.

After reconnecting to your Pi you need to enable the camera module. To do so first you need to install raspi-config:

sudo apt-get install raspi-config

And run it as root:

sudo raspi-config

Select the Enable Camera option and then select Enable. Finally, answer yes to the question if you want to restart the Raspberry Pi now. After the reboot reconnect to it through SSH.

Step 5: Installing Motion

At this point you are finished with the basic system configuration, now it's time to setup the video steaming. To do that you are going to use motion:

sudo apt-get install motion

After installing motion you will also need to install some more libraries:

sudo apt-get install -y libjpeg62 libjpeg62-dev libavformat53 libavformat-dev libavcodec53 libavcodec-dev libavutil51 libavutil-dev libc6-dev zlib1g-dev libmysqlclient18 libmysqlclient-dev libpq5 libpq-dev

There is a known issue with motion and the Raspberry Pi Camera Module which can be fixed by replacing the original binary of motion with the one from this fork. To do that just run the following commands:

wget https://www.dropbox.com/s/jw5r1wss32tdibb/motion-mmal-opt.tar.gz
tar -xvf motion-mmal-opt.tar.gz
sudo cp motion-mmal/motion /usr/bin/motion
rm -rf motion-mmal motion-mmal-opt.tar.gz

Now you need to configure motion. First make a directory to keep the camera footage and a second one for the log files:

mkdir ~/logs/
mkdir -p ~/data/cloud
chmod -R 775 ~/data
sudo chgrp -R motion ~/data

Next, you need to create a log file in /var/log directory and give motion write access to it:

sudo touch /var/log/motion.log
sudo chown motion:motion /var/log/motion.log

Enable the motion daemon by running:

sudo nano /etc/default/motion

And changing the no to yes.

Now download the attached motion.conf file and put it in the /etc directory:

sudo wget https://www.instructables.com/files/orig/FCB/2PVD/IE7J5E20/FCB2PVDIE7J5E20.conf
sudo mv FCB2PVDIE7J5E20.conf /etc/motion.conf

There are a couple of things you may need to edit in the configuration file:

sudo nano /etc/motion.conf

First, go on the line:

stream_authentication username:password

And change the username and password to what you want. You are going to use that username / password pair to access the video stream later from your web browser.

By default motion is going to take a snapshot image every 6 seconds and save it in the /home/raspcam/data/cloud directory. You can change that interval if you want by editing the following line.

snapshot_interval 6

Bare in mind though that the smaller the snapshot interval is the larger the USB drive and the available space on Google Drive need to be.

The settings I provide you are what I found it works best for me after a lot of adjusting and tweaking but that does not mean you have to keep it as is, there are many other options you may want to play around with. So, feel free to play around with the settings and if you mesh up something you can always redownload the configuration file.

Now that everything is configured you need to start the motion daemon by running:

sudo /etc/init.d/motion start

If everything went as expected you should see the LED from the camera module to turn on. At this point you should be able to see the live streaming from the camera module if you go to the URL http://<ip-of-second-raspberry-pi>:8081 from your web browser.

If you made more than one cameras and you want to view the video stream from both the same time you can use the attached HTML file. The only thing you need to do is to replace the:

<ip-of-first-raspberry-pi>

And:

<ip-of-second-raspberry-pi>

With the actual IP addresses of your cameras.

Step 6: Adding Google Drive Support

Now that the live streaming is working, it's time to add Google Drive support. To do so you need to install the drive utility. To install it, run the following commands:

wget https://github.com/odeke-em/drive/releases/download/v0.2.8-arm-binary/drive-armv6l-sha256.bf9ad9cda93af2f05162eb48d92896f7bd5633c9676e805db8ed7070e50cb539
sudo mv drive-armv6l-sha256.bf9ad9cda93af2f05162eb48d92896f7bd5633c9676e805db8ed7070e50cb539 /usr/local/bin/drive
chmod +x /usr/local/bin/drive
sudo chown root:root /usr/local/bin/drive

Now if you run:

drive version

You should see an output like the following:

drive version: 0.2.8
Commit Hash: '906eb82d1bc7662f3c503ca9213980f7523e5199'
Go Version: go1.3.1
OS: linux/arm
BuildTime: 2015-08-28 02:42:01.299545786 +0000 UTC

After installing drive you need to pair it with a Google account so it can access Google Drive. I strongly recommend creating a new Google account for each IP camera because the snapshot images are going to occupy a lot of space.

To pair it with a Google account first login to it from your browser and then run the following command:

drive init ~/data/cloud/

Copy and paste the generated authorization link to your browser, copy and paste back to the terminal the authorization code and hit Enter.

Now run:

cd ~/data/cloud/ && drive about

If you see an output like the following, it means everything went as expected:

Account type:    LIMITED
Bytes Used:    0                    (0.00B)
Bytes Free:    16106127360          (15.00GB)
Bytes InTrash:    0                    (0.00B)
Total Bytes:    16106127360          (15.00GB)

* Space used by Google Services *
Service                              Bytes                               
DRIVE                                0.00B                               
GMAIL                                0.00B                               
PHOTOS                               0.00B                               
Space used by all Google Apps        0.00B                               

* Maximum upload sizes per file type *
FileType                                           Size                
application/vnd.google-apps.document               10.00MB             
application/vnd.google-apps.spreadsheet            100.00MB            
application/vnd.google-apps.presentation           100.00MB            
application/vnd.google-apps.drawing                2.00MB              
application/pdf                                    4.77TB              
*                                                  4.77TB              

Feature                        Request limit (queries/second)
ocr                            0.000000                      
translation                    2.000000

Now you need to make a cronjob that will delete the snapshot images that are older from a specific threshold e.g. 2 days and then it will sync the ~/data/cloud directory to Google Drive. So, run:

crontab -e

And insert the following lines:

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin/go/bin:/home/raspcam/go/bin
50 * * * * yes | find /home/raspcam/data/cloud/ -name *.jpg -type f -mtime +2 -exec rm {} \; > /home/raspcam/logs/cleanold.log 2>&1
0 * * * * yes | drive push /home/raspcam/data/cloud/ > /home/raspcam/logs/cloudsync.log 2>&1 && cd /home/raspcam/data/cloud/ && yes | drive emptytrash

Yes, you need to empty the trash every time after you push the new images to the Google Drive because even if the old images are trashed they still occupy space on Google Drive. And that is the second reason why you should create a new Google account for the IP camera instead of using your own, you don't want the automatic emptying of the trash to also delete personal files that you manually deleted.

If you want to keep images older than 2 days you can replace the +2 with the number of days you want, but be careful the total images not to exceed the total size of your Google Drive or the size of your USB drive minus 1.5GB for the /var partition.

Step 7: Configuring the Firewall

Now it's time to configure the firewall, to do it the easy way you can use UFW which is a front-end for iptables:

sudo apt-get install ufw

And to configure it run the following commands:

sudo ufw allow 22/tcp
sudo ufw allow 8081/tcp
sudo ufw default deny
sudo ufw enable

The only ports that you need to be accessible are the port 22 so you will be able to SSH to your camera when you need to and 8081 so you can access the video steam of the camera, the rest of the ports are blocked.

Step 8: Boosting the Performance

There are a couple of things you can do to enhance the performance of your IP camera. The first is to disable the motion's motion detection if you don't need it. This is done through a web interface accessible on port 8080 but for security reasons this port has been blocked from the firewall. But, you can still access it locally so you can disable the motion detection using a simple curl command:

sudo apt-get install curl
curl http://admin:admin@127.0.0.1:8080/0/detection/pause

But you don't want to run this command by hand every time the Pi reboots. So you can simply add it in your rc.local by running:

sudo nano /etc/rc.local

And just before the line:

exit 0

Put the line:

curl http://admin:admin@127.0.0.1:8080/0/detection/pause 1>&2 > /home/raspcam/logs/disable_motion_detection.log

A second thing you can do is to overclock the Raspberry Pi. To do this run:

sudo raspi-config

From the menu select the Overclock option and then the Modest setting. Finally, select Finish to save the changes and answer yes to the questing if you want to reboot now. After the reboot reconnect to your Pi again through SSH.

Step 9: Making the File System Read-Only

Now it's time to move the /var and /home partitions to an external USB drive and make the rest of the system read-only.

First thing you need to do is to temporally stop the motion, cron, ufw and rsyslog daemons so you will be able to move /home and /var partitions without having issues:

sudo /etc/init.d/motion stop
sudo /etc/init.d/ufw stop
sudo /etc/init.d/cron stop
sudo /etc/init.d/rsyslog stop

Next insert the USB drive to your Pi and create two ext4 partitions in it. One with 1.5GB size for the /var and a second one with the rest of the capacity for the /home. First you need to find the device name of the USB drive, so run:

sudo fdisk -l

You will get an output like the following:

Disk /dev/mmcblk0: 7860 MB, 7860125696 bytes
4 heads, 16 sectors/track, 239872 cylinders, total 15351808 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk0p1              16      250047      125016    b  W95 FAT32
/dev/mmcblk0p2          250048    15351807     7550880   83  Linux

Disk /dev/sda: 8004 MB, 8004304896 bytes
35 heads, 21 sectors/track, 21269 cylinders, total 15633408 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1              32    15633407     7816688    b  W95 FAT32

In my case the USB drive is the /dev/sda.

Next run fdsik to manage the partitions of the USB drive:

sudo fdisk /dev/sdX

Where X is the letter that corresponds to the USB drive device e.g. a.

Then delete any existing partitions by running:

d /dev/sdXY

e.g.

d /dev/sda1

Now you need to create a new partition. To do that type:

n

And hit Enter. Then:

p

And hit Enter. Type:

1

And hit Enter again. Hit Enter once again to accept the default sector, which is the first free sector on the disk.

Type:

+1536M

And hit Enter. Now the partition for /var is ready. Likewise for the partition for /home:

n <Enter>
p <Enter>
2 <Enter>
<Enter>
<Enter>

And a second partition with the remaining space is going to get created. If you now type p and hit Enter you should see an output similar to the following:

Disk /dev/sda: 8004 MB, 8004304896 bytes
35 heads, 21 sectors/track, 21269 cylinders, total 15633408 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1            2048     3147775     1572864   83  Linux
/dev/sda2         3147776    15633407     6242816   83  Linux

If everything seems OK save the changes and exit fdisk by typing:

w <Enter>

Now that the partitions have been created you need to format them as ext4. To do that run the following commands:

sudo mkfs.ext4 /dev/sdX1
sudo mkfs.ext4 /dev/sdX2

Now you need to update fstab to point the mounting points of /var and /home to the new partitions. But before doing that you need first to know the UUIDs of the two partitions you just created. To list all the UUIDs run:

sudo blkid

You will get an output like the following:

/dev/mmcblk0p1: SEC_TYPE="msdos" UUID="63E4-85SE" TYPE="vfat" 
/dev/mmcblk0p2: UUID="eefa3c42-1n08-4107-a6b7-84f3d6ec1bed" TYPE="ext4" 
/dev/sda1: UUID="07794ca2-2091-4de2-c7fb-6871af55nd3c" TYPE="ext4" 
/dev/sda2: UUID="db6p8bcc-66e6-4cb8-88e0-70d4b38bc628" TYPE="ext4"

To edit the fstab run:

sudo nano /etc/fstab

And replace its contents with the following:

# microSD
/dev/mmcblk0p1 /boot vfat defaults,ro 0 2
/dev/mmcblk0p2 / ext4 ro,errors=remount-ro,noatime 0 1

# USB Drive
UUID=<the-UUID-of-/dev/sdX2> /home ext4 defaults 0 2
UUID=<the-UUID-of-/dev/sdX1> /var ext4 defaults,noatime 0 2

Make sure to put the appropriate UUIDs where needed.

Next, you need to move all the files from /var to the /dev/sdX1 partition and all the files from /hometo the /dev/sdX2 partition. First mount temporarily /dev/sdX1 to /mnt.

sudo mount /dev/sdX1 /mnt

And then:

sudo cp -rp /var/* /mnt/
sudo rm -rf /var/*
sudo umount /mnt

After that do the same for /home:

sudo mount /dev/sdX2 /mnt
sudo cp -rp /home/* /mnt/
sudo rm -rf /home/*
sudo umount /mnt

Now reboot you Raspberry and after the reboot reconnect again to it through SSH:

sudo reboot

After you have connected to your Pi once again, run:

df -h

You should get an output like the following:

Filesystem      Size  Used Avail Use% Mounted on
rootfs          7.0G  406M  6.2G   7% /
udev             10M     0   10M   0% /dev
tmpfs            38M  116K   38M   1% /run
/dev/mmcblk0p2  7.0G  406M  6.2G   7% /
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            75M     0   75M   0% /run/shm
/dev/mmcblk0p1  122M   40M   82M  33% /boot
/dev/sda2       5.8G   51M  5.4G   1% /home
/dev/sda1       1.5G  185M  1.2G  14% /var
tmpfs            75M     0   75M   0% /tmp

Now all the partitions in the microSD are read-only and only the partitions on the USB drive are read-write. But, there is one last thing that would be useful to do. Since Raspberry Pi is actually a fully functional computer that runs an actual operating system, you may want from time to time to install new software using apt-get or do updates. But since the file system is now read-only you will have to remount it as read-write every time and when you are done remount is as read-only again. This might be a little annoying so to get rid of this problem you can create a simple script that will run every time you use apt and do all the job for you.

At fist, temporarily make the root file system read-write so you can create the script:

sudo mount -o remount,rw /

Then run:

sudo nano /etc/apt/apt.conf

And paste inside the following lines:

DPkg {
    // Auto re-mounting of a readonly /
    Pre-Invoke { "mount -o remount,rw /"; };
    Post-Invoke { "test ${NO_APT_REMOUNT:-no} = yes || mount -o remount,ro / || true"; };
};

Finally, remount as read-only the root partition again:

sudo mount -o remount,ro /

Now you will be able to use apt-get to run updates and install or remove new software without having to worry about making the root partition read-write first. But be careful, this script will make read-write temporarily only the root partition but not the /boot, that means if you want to update the kernel the apt-get is going to fail. In that case before running apt-get you will have to make the /boot manually read-write by running:

sudo mount -o remount,rw /boot

And when you are done you can run the following command to make the /boot partition again read-only

sudo mount -o remount,ro /boot

Updating the kernel on an embedded system that you may not have physical access is somewhat risky, so this will prevent accidental updating of the kernel unless you are sure you want to do it.

And you are finally done! At this point I highly recommend backing up your microSD card so you will be able to easily restore the system if you mesh something up in the future or clone it to another microSD if you want to make a second camera. Make sure to do a raw backup of your microSD that will also include the partition table and not just the files. If you don't now how to do a raw image backup of your microSD you may want to give this article a read. In the same way also make a raw backup of the USB drive.

Step 10: Assembling the Camera

Picture of Assembling the Camera

Now that you are done with the software part is time to assemble the camera.

Preparing the POE Splitter:

First thing you need to do it to take the POE splitter and crack it open to remove its PCB. You are interested only in the PCB so you can throw the plastics away.

Next you need to modify the PCB a little, start by desoldering the barrel power jack and the slide switch. Then, take the two female to female jumper wires and cut them in half. In place of the power jack solder two of the half jumper wires on the negative side and the two other on the positive side. The reason for using two jumper wires on each side instead of just one is to increase the maximum current they can deliver.

Finally, take a small piece of solid core wire and solder it between the first and the third contact of the slide switch you just desoldered (see the second attached photo). That way the POE splitter will be set to supply constantly 5V.

Preparing the Housing:

Next you need to prepare the housing for the camera. Start by completely disassembling the dummy camera you are going to use for the housing.

When you are done, take the piece of the housing that has the AA battery holder on it and using your dremel cut around the edges to remove it. You have to remove the battery holder because it occupies a lot of space inside the housing and with it in the way you can't fit both PCBs inside.

After that, you need to make a square hole for the input Ethernet connector of the POE splitter on the back piece of the housing. So take the POE splitter PCB, place it on top of the back piece so see where exactly you need to make the hole (is going to be on the upper right corner, see photo) and using your dremel again cut the square hole. Finally, check that the connector fits in the hole.

Connecting the Raspberry Pi with the POE Splitter:

To connect your Pi with the POE splitter first you need a very small Ethernet cable. The cable must be around 9cm including the RJ45 plugs. I'm not going to describe how to crimp a UTP cable because this not the subject of this instructable, but there are already many tutorials on the web that demonstrate the process. Because the length of the cable is critical take your time, if you don't succeed on the first try don't worry just try again.

After you have crimped and tested the cable connect the one end to your Pi and the other end to the output of your POE splitter, then fold them in order to form a U shape. Now put the two PCBs on top of the back piece of the housing and verify that they fit. Finally, disconnected the Ethernet cable from the POE splitter and your Pi, get the POE splitter, secure it in place with hot glue and let it cool.

After the hot glue has cooled before doing anything else plug in the microSD to your Pi if you haven't already. Ir order to earn some extra space the Raspberry Pi is going to get powered through the GPIO header instead of the micro USB connector. To power your Pi though the GPIO header connect the two positive jumper wires to the pins 2 and 4 of the GPIO header, and the two ground jumper wires to the pins 6 and 9.

Next, connect the two PCBs together with the small Ethernet cable you made. Finaly, plug the USB drive to the Pi if you haven't already.

Attaching the Camera Module:

Next step is to attach the camera module to the housing. First take the plastic piece with the fake LEDs and put the camera module in the hole to mark were you need to open the holes. Drill the holes and using screws secure into place the camera module.

Now, take all the front pieces of the housing and reassemble them. Lastly, connect the camera module to the Raspberry Pi using the ribbon cable.

Next, get the top and bottom piece of the housing, attach them to the back piece of the housing and screw them in place. On the other side screw in place the front side of the housing. Assemble the remaining parts of housing the base and you are done!

Step 11: So What's Next?

Don't forget that this IP camera is not just any IP camera but a fully functional Linux computer. You can do with it anything you can with a normal computer that runs Linux, the only limit is your imagination.

Some ideas about extending the project are the following:

  • Stream and/or record audio - You can very easily add a microphone to the camera and apart from streaming video also stream sound. You can also record audio files and upload them to Google Drive together with the snapshots that motion takes.
  • Talk to people - Another idea is to add a small speaker to your camera so you can talk to people remotely. This would be useful if you own for example a small business and you want to easily interact with your employees when you are not there. e.g. In case you notice something wrong while watching the video stream you can directly talk to your employees without having to call them.
  • Add motors! - A third idea is to add motors to your camera and control them remotely through a simple web interface. The only problem is that I don't see an easy way to mount motors on the housing I used, but you can search for another housing or even make your own if you have access to a 3D printer.
  • Add any sensor you want - You can add any sensor you can image to your camera (e.g. a temperature sensor) and make it take periodically measurements. Then you can make the measurements accessible through a web interface or even upload them to Google Drive.

You've got an idea about extending the project? Leave it in the comments!

Comments

Mike Fury 2 (author)2017-09-09

Totally Awesome !

elencheN (author)2017-03-17

Great project, I'm planning to try it. I just want to know whether motion takes pictures only when motion is detected, or the whole time that it's running? Thanks

magkopian (author)elencheN2017-03-18

Motion can be configured to do that, I just have disabled that particular feature because it's a bit too CPU intensive for a Raspberry Pi 1B+ and I didn't really need it.

AyyangarN (author)2016-12-05

Can this be accessed by the devices in external network or www?

If so how can we configure it to access the PI?

magkopian (author)AyyangarN2017-01-29

Yes, this can be done, you will need to configure your router to forward the combination of your Pi IP address with the port 8081 to an external port e.g. 17895. Then using the public IP address of your router and the port that you've set you can access the video feed over the Internet.

SunilT6 (author)2016-11-18

Hello Everyone,

I am using my RasPi with a IP Camera with Ethernet communication

While running this command xzcat /path/to/raspbian-ua-netinst-.img.xz > /dev/sdX to write Image on SD card it had run for almost 10 minutes then it shows 62,9,6C,62,9,6C for a time and stops with some files not found line.

Can anyone suggest how to write raspian-ua-netinst v1.0.9 to my SD card and how to communicate IP camera with RasPi using Ethernet

Please suggest your Ideas.

RustamS2 (author)2016-07-15

great project! Im going to build it for my school's project;) Could you help me please how do i add a small speaker and talk remotely? and one more question if i want to have more that 1 camera, do i have to own 1 rapsberry pi for each camera? Thanks a lot

magkopian (author)RustamS22016-07-15

Hi, good to hear that my project inspired you to make something yourself. Now to your question, adding a speaker should be pretty much straightforward as the Pi already has an audio output jack, streaming audio though is going to be a bit more complicated. One solution to achieve this is by using the gStreamer framework, there is already plenty of information available on the Web about this topic and I'm pretty sure you will have no issue getting started.

As for your second question, well the problem is that the Raspberry Pi has only one camera connector. You could of course try using USB webcams instead, but the performance will me much worse so better to stick to camera modules and one Pi per camera. I you really need two camera modules on the same Pi, you could buy a Raspberry Pi Compute Module Kit but it is fairly expensive, so probably not worth it.

RustamS2 (author)magkopian2016-07-15

Thanks for your reply:) one more question which Raspbbery Pi would be the best for this project since there are many models and new model 3 release recently, or should i stick with model B+?

magkopian (author)RustamS22016-07-17

I'd say since this is mostly for the purpose of learning, go for the Raspberry Pi 2 and also use the latest version of Raspbian which is Jessie instead of Wheezy as I did. The RPi2 will give you much better performance in comparison to a RPi B+, RPi3 is a bit more powerful that RPi2 but I wouldn't recommend it based on the fact that it has overheating issues and because of that I wouldn't trust it to be reliable enough for continuous operation.

RustamS2 (author)magkopian2016-11-04

hello, could you help me, i cant see stream on website

here what im getting

cat /var/log/motion.log | tail -n 100

[1] [NTC] [ALL] [Nov 04 15:00:16] motion_init: Started motion-stream server in port 8081 auth Enabled

[0] [ERR] [ALL] [Nov 04 15:00:46] main: Thread 1 - Watchdog timeout, trying to do a graceful restart

[0] [ERR] [ALL] [Nov 04 15:01:46] main: Thread 1 - Watchdog timeout, did NOT restart graceful,killing it!

[0] [NTC] [STR] [Nov 04 15:01:46] stream_stop: Closing motion-stream listen socket & active motion-stream sockets

[0] [NTC] [STR] [Nov 04 15:01:46] stream_stop: Closed motion-stream listen socket & active motion-stream sockets

[0] [ALR] [VID] [Nov 04 15:01:46] MMAL Camera cleanup

[0] [NTC] [ALL] [Nov 04 15:01:47] main: Motion thread 1 restart

[1] [NTC] [ALL] [Nov 04 15:01:47] motion_init: Thread 1 started , motion detection Enabled

[1] [ALR] [VID] [Nov 04 15:01:47] mmalcam_start: MMAL Camera thread starting... for camera (vc.ril.camera) of 440 x 330 at 30 fps

[1] [ALR] [VID] [Nov 04 15:01:47] mmalcam_start: MMAL Camera using video capture

[1] [NTC] [VID] [Nov 04 15:01:47] MMAL camera component created

[1] [NTC] [ALL] [Nov 04 15:01:47] image_ring_resize: Resizing pre_capture buffer to 1 items

[1] [NTC] [STR] [Nov 04 15:01:47] http_bindsock: motion-stream testing : IPV4 addr: 0.0.0.0 port: 8081

[1] [NTC] [STR] [Nov 04 15:01:47] http_bindsock: motion-stream Bound : IPV4 addr: 0.0.0.0 port: 8081

[1] [NTC] [ALL] [Nov 04 15:01:47] motion_init: Started motion-stream server in port 8081 auth Enabled

[0] [ERR] [ALL] [Nov 04 15:02:17] main: Thread 1 - Watchdog timeout, trying to do a graceful restart

[0] [ERR] [ALL] [Nov 04 15:03:17] main: Thread 1 - Watchdog timeout, did NOT restart graceful,killing it!

[0] [NTC] [STR] [Nov 04 15:03:17] stream_stop: Closing motion-stream listen socket & active motion-stream sockets

[0] [NTC] [STR] [Nov 04 15:03:17] stream_stop: Closed motion-stream listen socket & active motion-stream sockets

[0] [ALR] [VID] [Nov 04 15:03:17] MMAL Camera cleanup

[0] [NTC] [ALL] [Nov 04 15:03:18] main: Motion thread 1 restart

[1] [NTC] [ALL] [Nov 04 15:03:18] motion_init: Thread 1 started , motion detection Enabled

[1] [ALR] [VID] [Nov 04 15:03:18] mmalcam_start: MMAL Camera thread starting... for camera (vc.ril.camera) of 440 x 330 at 30 fps

[1] [ALR] [VID] [Nov 04 15:03:18] mmalcam_start: MMAL Camera using video capture

[1] [NTC] [VID] [Nov 04 15:03:18] MMAL camera component created

[1] [NTC] [ALL] [Nov 04 15:03:18] image_ring_resize: Resizing pre_capture buffer to 1 items

[1] [NTC] [STR] [Nov 04 15:03:18] http_bindsock: motion-stream testing : IPV4 addr: 0.0.0.0 port: 8081

[1] [NTC] [STR] [Nov 04 15:03:18] http_bindsock: motion-stream Bound : IPV4 addr: 0.0.0.0 port: 8081

[1] [NTC] [ALL] [Nov 04 15:03:18] motion_init: Started motion-stream server in port 8081 auth Enabled

[0] [ERR] [ALL] [Nov 04 15:03:48] main: Thread 1 - Watchdog timeout, trying to do a graceful restart

[0] [ERR] [ALL] [Nov 04 15:04:48] main: Thread 1 - Watchdog timeout, did NOT restart graceful,killing it!

[0] [NTC] [STR] [Nov 04 15:04:48] stream_stop: Closing motion-stream listen socket & active motion-stream sockets

[0] [NTC] [STR] [Nov 04 15:04:48] stream_stop: Closed motion-stream listen socket & active motion-stream sockets

[0] [ALR] [VID] [Nov 04 15:04:48] MMAL Camera cleanup

[0] [NTC] [ALL] [Nov 04 15:04:49] main: Motion thread 1 restart

[1] [NTC] [ALL] [Nov 04 15:04:49] motion_init: Thread 1 started , motion detection Enabled

[1] [ALR] [VID] [Nov 04 15:04:49] mmalcam_start: MMAL Camera thread starting... for camera (vc.ril.camera) of 440 x 330 at 30 fps

[1] [ALR] [VID] [Nov 04 15:04:49] mmalcam_start: MMAL Camera using video capture

[1] [NTC] [VID] [Nov 04 15:04:49] MMAL camera component created

[1] [NTC] [ALL] [Nov 04 15:04:49] image_ring_resize: Resizing pre_capture buffer to 1 items

[1] [NTC] [STR] [Nov 04 15:04:49] http_bindsock: motion-stream testing : IPV4 addr: 0.0.0.0 port: 8081

[1] [NTC] [STR] [Nov 04 15:04:49] http_bindsock: motion-stream Bound : IPV4 addr: 0.0.0.0 port: 8081

[1] [NTC] [ALL] [Nov 04 15:04:49] motion_init: Started motion-stream server in port 8081 auth Enabled

[0] [ERR] [ALL] [Nov 04 15:05:19] main: Thread 1 - Watchdog timeout, trying to do a graceful restart

[0] [ERR] [ALL] [Nov 04 15:06:19] main: Thread 1 - Watchdog timeout, did NOT restart graceful,killing it!

[0] [NTC] [STR] [Nov 04 15:06:19] stream_stop: Closing motion-stream listen socket & active motion-stream sockets

[0] [NTC] [STR] [Nov 04 15:06:19] stream_stop: Closed motion-stream listen socket & active motion-stream sockets

[0] [ALR] [VID] [Nov 04 15:06:19] MMAL Camera cleanup

[0] [NTC] [ALL] [Nov 04 15:06:20] main: Motion thread 1 restart

[1] [NTC] [ALL] [Nov 04 15:06:20] motion_init: Thread 1 started , motion detection Enabled

[1] [ALR] [VID] [Nov 04 15:06:20] mmalcam_start: MMAL Camera thread starting... for camera (vc.ril.camera) of 440 x 330 at 30 fps

[1] [ALR] [VID] [Nov 04 15:06:20] mmalcam_start: MMAL Camera using video capture

[1] [NTC] [VID] [Nov 04 15:06:20] MMAL camera component created

[1] [NTC] [ALL] [Nov 04 15:06:20] image_ring_resize: Resizing pre_capture buffer to 1 items

[1] [NTC] [STR] [Nov 04 15:06:20] http_bindsock: motion-stream testing : IPV4 addr: 0.0.0.0 port: 8081

[1] [NTC] [STR] [Nov 04 15:06:20] http_bindsock: motion-stream Bound : IPV4 addr: 0.0.0.0 port: 8081

[1] [NTC] [ALL] [Nov 04 15:06:20] motion_init: Started motion-stream server in port 8081 auth Enabled

[0] [ERR] [ALL] [Nov 04 15:06:50] main: Thread 1 - Watchdog timeout, trying to do a graceful restart

[0] [ERR] [ALL] [Nov 04 15:07:50] main: Thread 1 - Watchdog timeout, did NOT restart graceful,killing it!

[0] [NTC] [STR] [Nov 04 15:07:50] stream_stop: Closing motion-stream listen socket & active motion-stream sockets

[0] [NTC] [STR] [Nov 04 15:07:50] stream_stop: Closed motion-stream listen socket & active motion-stream sockets

[0] [ALR] [VID] [Nov 04 15:07:50] MMAL Camera cleanup

[0] [NTC] [ALL] [Nov 04 15:07:51] main: Motion thread 1 restart

[1] [NTC] [ALL] [Nov 04 15:07:51] motion_init: Thread 1 started , motion detection Enabled

[1] [ALR] [VID] [Nov 04 15:07:51] mmalcam_start: MMAL Camera thread starting... for camera (vc.ril.camera) of 440 x 330 at 30 fps

[1] [ALR] [VID] [Nov 04 15:07:51] mmalcam_start: MMAL Camera using video capture

[1] [NTC] [VID] [Nov 04 15:07:51] MMAL camera component created

[1] [NTC] [ALL] [Nov 04 15:07:51] image_ring_resize: Resizing pre_capture buffer to 1 items

[1] [NTC] [STR] [Nov 04 15:07:51] http_bindsock: motion-stream testing : IPV4 addr: 0.0.0.0 port: 8081

[1] [NTC] [STR] [Nov 04 15:07:51] http_bindsock: motion-stream Bound : IPV4 addr: 0.0.0.0 port: 8081

[1] [NTC] [ALL] [Nov 04 15:07:51] motion_init: Started motion-stream server in port 8081 auth Enabled

[0] [ERR] [ALL] [Nov 04 15:08:21] main: Thread 1 - Watchdog timeout, trying to do a graceful restart

[0] [ERR] [ALL] [Nov 04 15:09:21] main: Thread 1 - Watchdog timeout, did NOT restart graceful,killing it!

[0] [NTC] [STR] [Nov 04 15:09:21] stream_stop: Closing motion-stream listen socket & active motion-stream sockets

[0] [NTC] [STR] [Nov 04 15:09:21] stream_stop: Closed motion-stream listen socket & active motion-stream sockets

[0] [ALR] [VID] [Nov 04 15:09:21] MMAL Camera cleanup

[0] [NTC] [ALL] [Nov 04 15:09:22] main: Motion thread 1 restart

[1] [NTC] [ALL] [Nov 04 15:09:22] motion_init: Thread 1 started , motion detection Enabled

[1] [ALR] [VID] [Nov 04 15:09:22] mmalcam_start: MMAL Camera thread starting... for camera (vc.ril.camera) of 440 x 330 at 30 fps

[1] [ALR] [VID] [Nov 04 15:09:22] mmalcam_start: MMAL Camera using video capture

[1] [NTC] [VID] [Nov 04 15:09:22] MMAL camera component created

[1] [NTC] [ALL] [Nov 04 15:09:22] image_ring_resize: Resizing pre_capture buffer to 1 items

[1] [NTC] [STR] [Nov 04 15:09:22] http_bindsock: motion-stream testing : IPV4 addr: 0.0.0.0 port: 8081

[1] [NTC] [STR] [Nov 04 15:09:22] http_bindsock: motion-stream Bound : IPV4 addr: 0.0.0.0 port: 8081

[1] [NTC] [ALL] [Nov 04 15:09:22] motion_init: Started motion-stream server in port 8081 auth Enabled

[0] [ERR] [ALL] [Nov 04 15:09:52] main: Thread 1 - Watchdog timeout, trying to do a graceful restart

[0] [ERR] [ALL] [Nov 04 15:10:52] main: Thread 1 - Watchdog timeout, did NOT restart graceful,killing it!

[0] [NTC] [STR] [Nov 04 15:10:52] stream_stop: Closing motion-stream listen socket & active motion-stream sockets

[0] [NTC] [STR] [Nov 04 15:10:52] stream_stop: Closed motion-stream listen socket & active motion-stream sockets

[0] [ALR] [VID] [Nov 04 15:10:52] MMAL Camera cleanup

[0] [NTC] [ALL] [Nov 04 15:10:53] main: Motion thread 1 restart

[1] [NTC] [ALL] [Nov 04 15:10:53] motion_init: Thread 1 started , motion detection Enabled

[1] [ALR] [VID] [Nov 04 15:10:53] mmalcam_start: MMAL Camera thread starting... for camera (vc.ril.camera) of 440 x 330 at 30 fps

[1] [ALR] [VID] [Nov 04 15:10:53] mmalcam_start: MMAL Camera using video capture

[1] [NTC] [VID] [Nov 04 15:10:53] MMAL camera component created

[1] [NTC] [ALL] [Nov 04 15:10:53] image_ring_resize: Resizing pre_capture buffer to 1 items

[1] [NTC] [STR] [Nov 04 15:10:53] http_bindsock: motion-stream testing : IPV4 addr: 0.0.0.0 port: 8081

[1] [NTC] [STR] [Nov 04 15:10:53] http_bindsock: motion-stream Bound : IPV4 addr: 0.0.0.0 port: 8081

[1] [NTC] [ALL] [Nov 04 15:10:53] motion_init: Started motion-stream server in port 8081 auth Enabled

[0] [ERR] [ALL] [Nov 04 15:11:23] main: Thread 1 - Watchdog timeout, trying to do a graceful restart

eleyes (author)2015-12-04

I cannot get daemon running - it says it starts but it is not in the processes and there are no log files. Camera module is functioning so I assume there is some problem with motion package itself.

Could it be that some of the packages I was not able to acquire are missing for it to function? For libjpeg62 i used the turbo version, but didnt help.

Package libjpeg62-dev is not available, but is referred to by another package.

This may mean that the package is missing, has been obsoleted, or

is only available from another source

However the following packages replace it:

libjpeg9-dev libjpeg8-dev libjpeg62-turbo-dev

E: Package 'libjpeg62-dev' has no installation candidate

E: Unable to locate package libavformat53

E: Unable to locate package libavcodec53

E: Unable to locate package libavutil51

magkopian (author)eleyes2015-12-05

That's very odd these packages are actually available in the Wheezy repositories so you shouldn't get a "has no installation candidate" error message. Try running a "sudo apt-get update" and then again install the dependencies. If that doesn't solve the issue please post your source.list so I can take a look.

eleyes (author)magkopian2015-12-05

Tried it - didn't work.

Here is content of /etc/apt/sources.list
deb http://mirrordirector.raspbian.org/raspbian jessie main firmware
deb http://archive.raspberrypi.org/debian jessie main

I replaced "jessie" which was by default to "wheezy", did apt-get update and tried installing packages - that worked - I got all the packages, but daemon is till not running. I am not sure if that was right thing to do what I did above.

magkopian (author)eleyes2015-12-05

In this Instructable I use Wheezy and I haven't tested on Jessie to see if everything works the same. From your sources.list it seems that you use Jessie. With that being said I'll try my best to help you make it work on Jessie but since I haven't done in myself I can't make any promises.

Anyway, after some digging in Debian repositories I discovered that libavformat53, libavcodec53 and libavutil51 have been removed from Jessie and they are only still available on Wheezy. On Jessie though I found that there where available libavformat56, libavcodec56 and libavutil54, so the most logical move would be to try installing them instead (don't forget use the -y flag with apt-get install).

Also, according to Apt, the packages libjpeg9-dev, libjpeg8-dev and libjpeg62-turbo-dev replace libjpeg62-dev, so you should try installing them instead (again using the -y flag).

After everything is installed do the following,

sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade

to make sure that all the packages are updated to the latest versions.

eleyes (author)magkopian2015-12-05

I am aware that project was built on wheezy. I did exactly according to your guide and it probably got automatically updated to jessie during installation.

I have already installed ibavformat56, libavcodec56 and libavutil54.

Packages libjpeg9-dev, libjpeg8-dev and libjpeg62-turbo-dev substitute each other and therefore cannot installed side by side. I had installed ibjpeg62-turbo-dev.

Updates on these packages:
libcupsfilters1 libssl-dev libssl-doc libssl1.0.0 openssl

Pardon my noob question - isnt it possible to compile required packages for particular distro version?

I really appreciate your help. Respect.

magkopian (author)eleyes2015-12-06

You mentioned that you replaced "wheezy" with "jessie" in your source.list, that was the reason why your system got updated to jessie when you ran and "apt-get install" command.

Compiling and installing packages manually on Debian is a recipe for disaster, don't even think about it. Also, don't even think about installing packages from different releases e.g. from Wheezy repositories on a Jessie system, if you don't know exactly what you are doing you will very quickly mess up your system.

I suspect that you currently have a mixed Wheezy/Jessie system and that will most likely lead to many issues later. I know you are not going to like what I'm going to say, but at this point I highly recommend starting over. Just this time make sure not to touch the source.list and you will be fine.

NealM11 (author)magkopian2016-05-19

Offhand it looks to me like the proposed patches to motion-mmal at https://github.com/dozencrows/motion/pull/1/files might address the jessie issues with 'Unable to locate package', but I haven't tried them yet.

NealM11 (author)NealM112016-05-19

OK, I've confirmed that the motion binary from lowflyerUK, that corresponds to that pull request, works on a raspberry pi 3 with raspbian based on jessie. See the details at https://www.raspberrypi.org/forums/viewtopic.php?f...

Yay!

magkopian (author)NealM112016-05-19

Great find, that should do the trick for anyone trying to get it work on Jessie.

eleyes (author)magkopian2015-12-06

I had a separate SD on which I experimented with Wheezy sources. I have tried your suggestion on Jessie which is my main project SD card. My last reply was done based on my main system.

RonnyO1 (author)2016-04-17

Where did you buy the dummy camera? Link?

magkopian (author)RonnyO12016-04-18

Just search on eBay for dummy ip ir camera and you will find it in the first page both in silver and black colors, it's available from many different eBay sellers. I didn't want to post a link to a specific eBay listing, because it would became outdated sooner or later.

RonnyO1 (author)magkopian2016-04-18

Ok. Thanks for your response :-)

mangou77 (author)2015-12-09

Finally made it!!!!! thank's alot for this amazing project!! keep it up ;)

i used rsp pi 2 with Whezzy and got 0 error following the steps everything works Great! But i want to add a separate video recorded if a motion is detected, any help? Thank's.

magkopian (author)mangou772015-12-10

Good job, well done!

To answer you question now. In the motion.conf file I provide you I have disabled motion detection in order to earn some CPU cycles. Before you enable it you need to know that if you do it will impact the performance.

Anyway, to enable motion detection the only thing you need to do is to lower the threshold setting on line 207 in your motion.conf. The threshold is the number of changed pixels that need to change from one frame to another in order for the motion detection to get triggered.

After motion detection is enabled, you can either setup motion to save motion triggered images or videos. By default motion already does the first, if you want motion to only save motion triggered images and not take snapshots using an interval, you need to set the setting snapshot_interval on line 384 to 0.

If your Internet upload speed is not very high this is the best way to go. If you want motion triggered video instead of images motion needs ffmpeg to be installed in order to do that. To be honest with you I haven't tried it, but I think the documentation describes it in great detail.

mangou77 (author)magkopian2015-12-16

Thank you very much!!! now everything works as i wanted :D

Thank's for all the details and all the hard work, keep it up ;)

magkopian (author)mangou772015-12-16

Glad to hear it. Have fun with your new IP camera.

eleyes (author)2015-11-30

Bro - totally gona build this - my first project. Is the POE box really necessary? I had the idea to hack the ethernet cable to transmit the power directly instead of having additional electronics on it. I mean - it needs only couple of wires for normal communication - use the rest of the wires to transmit power by hacking the other end with a power supply..? Not sure it that would work though, but it would be much cheaper. Thoughts?

Thanks!

magkopian (author)eleyes2015-12-01

What you just described is called passive PoE and currently no standard exists for it. In my project I used an active PoE splitter that follows the 802.3af PoE standard. If you do it this way you can be sure that your camera is going to be compatible with any commercial PoE injector or switch that follows the 802.3af standard. There are also other pros and cons of active versus passive PoE which I have already discussed with others in the comments bellow, but that is the most important at least for me.

If you plan to make only one camera and keep it for personal use, then you can go with passive PoE if you want.

Lastly, I you go the with the passive PoE keep in mind that you should transmit the power using a relatively high voltage and on the Pi side drop it to 5V using a switching regulator. This becomes more important as the length of the cable increases, the longer the cable the bigger the voltage drop.

collinsarthur (author)2015-11-21

Awesome

DarrenF6 (author)2015-09-03

absolutely cracking instructable.

curious if you thought if making it night vision capable?

great job. think ill give this one a go for sure.

nice one.
D.

magkopian (author)DarrenF62015-09-03

Thank you! Yeah, I've thought of that and it's actually very easy to do. You simply need to replace the normal camera module with the NoIR version. Which is basically the same camera module but without the IR filter. And you also need to replace the fake LEDs with real IR LEDs and add some circuitry to drive them. The 802.3af POE standard provides up to 15.4 W of DC power so powering the LEDs should not be an issue.

The problem becomes evident when you try to use the camera on daylight. The sun also emits infrared radiation and without an IR filter that is going to mesh up the colors. The only solution to this problem is to add an external IR filter to your camera during the day. But adding and removing manually the filter from the camera might not be very convenient (especially if you need a ladder to reach the camera).

I was thinking about adding a servo to put the filter in front of the camera every day when the sun rises and remove it when the sun sets, but I haven't figured out yet how exactly I could do that.

janboddez (author)magkopian2015-11-12

You could easily add a small $3 IR cut filter like http://www.dx.com/p/small-ir-cut-filter-switcher-for-cctv-camera-black-362506. (Drive it using 3 GPIO pins and a small H-bridge chip.)

magkopian (author)janboddez2015-11-12

Also very interesting, thanks for the link. I'll look more into it when I have some time.

DarrenF6 (author)magkopian2015-09-04

nice one. did some.digging since your reply.

http://m.ebay.co.uk/itm/20-22MM-Hole-Distance-CS-IR-CUT-Day-Night-Filter-Switcher-For-CMOS-Cameras-IPC-/171912913239?_trkparms=aid%253D222007%2526algo%253DSIC.MBE%2526ao%253D1%2526asc%253D20150519202351%2526meid%253Dfefc1bd8d75644e897a44f9aff3cabc4%2526pid%253D100408%2526rk%253D1%2526rkt%253D1%2526sd%253D231339792798&_trksid=p2056116.c100408.m2460

looks like a winner!

magkopian (author)DarrenF62015-09-04

That's very interesting. I think something like this could work, the only challenge is to fit it in the housing.

DarrenF6 (author)magkopian2015-09-04

So I'm officially hooked. Just ordered two of the dummy cameras you have :) Will keep ye posted over the coming month or so.

Cheers for the inspiration!

magkopian (author)DarrenF62015-09-04

That's great! I can't wait to see your results.

DarrenF6 (author)magkopian2015-09-15

so I'm mid-build, and had to report my one epic fail so far :D

I overheated the soldering iron when removing the barrel adapter, and somehow managed to short the PoE Splitter. I seem to be getting 12v from the ground, live and neutral when I connect it to the injector :D good job darren, good job..

so now I've ordered two more.. just in case :)

MiikePage (author)DarrenF62015-09-25

Don't worry Darren, I did the same! XD

DarrenF6 (author)MiikePage2015-09-25

hey all.

yeah i meant to update this actually.
after buying two more splitters... turns out its not blown..

i had the wrong mode of 802.3af.... switch was endspan and splitter is midspan.

i bought a second hand midsoan poe linksys switch. and all is well in the world!

will post some pics soon

safe!

magkopian (author)DarrenF62015-09-15

Sorry to hear that. I'm sure you'll be more lucky with the next one.
Just a tip about desoldering, to make the process easier try adding some
fresh leaded solder on the joints before trying to desolder the
components. Also, If you have some extra flux it helps a lot. And as for
the iron, try keeping the temperature around 350°C.

MiikePage (author)magkopian2015-09-25

I think the factory solder is very high temp, I got up to 420°C to de-solder, I used fresh leaded solder with flux which helped a lot. I've read in the comments that keeping the DC jack and splitting that to the Pi is also an option, although I haven't tried that for size, so I am unsure!

JohnL162 (author)2015-10-29

Magkopian,

You have a great instructable here. I have all of the parts, including a RPi 2B. do you have any idea if it will work and if Wheezy or Jessie would be better

Thanks

John

magkopian (author)JohnL1622015-10-29

I haven't tested it with Jessie, but I don't see any reason why it wouldn't work.

Of course Jessie is now the Stable release and it is indeed more up to date, so it would sound logical to just use Jessie. But, the think is that I have tested two different Wheezy based prototypes with the exact same configuration I describe on this instructable, for more than a year on a production environment and they have been proven to work without any issues and 100% uptime. So, maybe Wheezy is older and more outdate but on the other hand it has been tested and proven to work.

My recommendation is if you plan to use those cameras for something serious and you don't have enough time for testing before deployment use Wheezy, and do all the configuration exactly the same way I did. Otherwise, I'd say go for Jessie since it is now the Stable release and more up to date.

Rashid Coder (author)2015-10-24

fantastic (y)

KeithM9 (author)2015-10-20

Take a fake security camera and make it real. I like that!

cehwitham (author)2015-10-17

Thanks for an excellent instructable, great detail.

After updating fstab and rebooting, I could no longer connect to my Pi. I wonder if I got the UUIDs wrong. Could you give an example of your file to show how the lines should be formatted please?

# microSD

/dev/mmcblk0p1 /boot vfat defaults,ro 0 2

/dev/mmcblk0p2 / ext4 ro,errors=remount-ro,noatime 0 1


# USB Drive

4d23c761-f8eb-4a65-a04e-6f25ff5dd069 /home ext4 defaults 0 2

98fa85bb-9a48-4fe1-85e4-679b28ed5711 /var ext4 defaults,noatime 0 2

magkopian (author)cehwitham2015-10-18

You got wrong the UUID part on the last two lines. It should be:

UUID=4d23c761-f8eb-4a65-a04e-6f25ff5dd069 /home ext4 defaults 0 2
UUID=98fa85bb-9a48-4fe1-85e4-679b28ed5711 /var ext4 defaults,noatime 0 2

You forgot the "UUID=" part before the UUIDs of the partitions.