Dropbox Sync

Once the Pi camera is setup you can configure the Pi to use the motion software package to detect movement and upload images to Dropbox.  Follow the steps below to first setup sending data to Dropbox with a script, then install and configure motion to use the Dropbox sync script when it detects motion from the camera.

Dropbox is one of many popular consumer cloud storage services.  By sending the Pi images to Dropbox you can easily view them from any computer using Dropbox's sync client or its web interface.  If you don't have one already you'll need to sign up for a free account with Dropbox before continuing.

To do the actual image uploading we'll use Andrea Fabrizi's excellent Dropbox Uploader shell script.  This script can run from a Pi or any other Linux/Unix machine and send data to Dropbox with a simple command.  By configuring the motion software to call Dropbox Uploader you'll have a camera uploading images to Dropbox with almost no work.

Note that you can use a different cloud storage service to store camera images.  You'll need to make sure there is a script or command that the Pi can run to upload an image to the service.  For Dropbox the mentioned Dropbox Uploader script makes the setup and upload process easy, but for other cloud storage services consider:

Dropbox Uploader Setup

Start by installing and configuring the Dropbox Uploader script.  Make sure the Pi is connected to the Internet and open a terminal on it, then run the following commands to download and install the script:

sudo apt-get update
sudo apt-get install -y curl
cd ~
git clone https://github.com/andreafabrizi/Dropbox-Uploader.git
cd Dropbox-Uploader
chmod a+x dropbox_uploader.sh
sudo cp dropbox_uploader.sh /usr/local/bin/dropbox_uploader

Once installed you should be able to invoke the dropbox_uploader command to run the script.  For example have it print its usage by running the command:

dropbox_uploader

You should see something like the following displayed:

Dropbox Uploader v0.16
Andrea Fabrizi - andrea.fabrizi@gmail.com

Usage: /usr/local/bin/dropbox_uploader COMMAND [PARAMETERS]...

Commands:
	 upload   <LOCAL_FILE/DIR ...>  <REMOTE_FILE/DIR>
	 download <REMOTE_FILE/DIR> [LOCAL_FILE/DIR]
	 delete   <REMOTE_FILE/DIR>
	 move     <REMOTE_FILE/DIR> <REMOTE_FILE/DIR>
	 copy     <REMOTE_FILE/DIR> <REMOTE_FILE/DIR>
	 mkdir    <REMOTE_DIR>
	 list     [REMOTE_DIR]
	 share    <REMOTE_FILE>
	 saveurl  <URL> <REMOTE_DIR>
	 info
	 unlink

Optional parameters:
	-f <FILENAME> Load the configuration file from a specific file
	-s            Skip already existing files when download/upload. Default: Overwrite
	-d            Enable DEBUG mode
	-q            Quiet mode. Don't show messages
	-p            Show cURL progress meter
	-k            Doesn't check for SSL certificates (insecure)

For more info and examples, please see the README file.

If you see an error that the dropbox_uploader command is not found carefully check you followed the steps above to install it and try again.

Once the script is installed you'll need to do a one time setup to configure it to talk to your Dropbox account.  Start the process by running the upload command:

dropbox_uploader upload

The Dropbox uploader script will see that it has not been connected to a Dropbox account and walk through the process of setting it up.  You should see a screen like the following:

Follow the instructions and open a browser to the https://www.dropbox.com/developers/apps URL.  Note that you might need to be logged in to Dropbox before you access this URL.  The page should look something like the following:

Click the blue Create app button in the upper right corner.  This should load a page to create a new application that can access your Dropbox account.  Fill in the details as follows:

  • Under Choose an API select Dropbox API.
  • Under Choose the type of access you need select Full Dropbox for access to any folder in your Dropbox account.
  • For Name your app enter a unique name for this application.  App names are global across all users so I recommend a name like "(your username)_CloudCam" where "(your username)" is your username.  For example I chose "tdicola_CloudCam" for the app name.
  • If there's a 4th option to Choose the Dropbox account that will own your app select the appropriate owner like your Personal account.  Don't worry if this option doesn't exist for you, you can skip it and move on.

The page should look something like this for example:

Now click the blue Create app button at the bottom of the page.  You should see a new page load that describes details of the application:

You'll need to copy out a few pieces of information from this page and enter them in the Dropbox uploader script.  Specifically you'll want:

  • App key value
  • App secret value (click the show button to see it)

Grab these values and enter them in the Dropbox uploader script's prompts.  The script should be asking first for the app key value, then the app secret value, and finally if you set the app to have partial/app permissions or full permissions (you used full permissions if you've followed everything exactly to now).

After entering these values you should be at a confirmation prompt like the following:

Type y and press enter to confirm the settings.  You should see the script direct you to a new web page similar to the following:

As the script instructs you open a browser and navigate to the URL it provides (make sure you're logged into Dropbox already).  You should see a page similar to the following that asks to confirm the app permission request (your page might look different depending on what Dropbox accounts you have setup):

Click the appropriate button to authorize the application to access your Dropbox account.  In this case I clicked the Personal button to authorize it to access my personal Dropbox account.  The page should inform you the application is now connected to Dropbox:

Now go back to the Dropbox uploader script prompt and press enter to continue.  The script should retrieve an auth token and finish successfully:

If you receive an error go back and carefully check all the application settings, etc. were setup as expected and try again.

Once the script finishes it will save the Dropbox application details in a hidden file under your home directory: ~/.dropbox_uploader  If you ever need to redo the authentication process again just delete this file (rm ~/.dropbox_uploader) and run the dropbox_uploader script again.

One important thing you must do is make the ~/.dropbox_uploader file readable by all users on the Pi.  This is necessary because the motion package runs under a different user account and needs to be able to read the Dropbox authentication in the file.  Run the following command to make this change:

chmod a+r ~/.dropbox_uploader

Don't skip running the chmod command above!  If you don't make the ~/.dropbox_uploader file readable by all users then motion won't save pictures to Dropbox.

Now that the script is connected to your Dropbox account you can test uploading a document with it.  From still inside the Dropbox-Uploader folder try uploading its README.md file to a new Cloud Cam folder on your Dropbox account.  Do this by running the command:

dropbox_uploader upload README.md "Cloud Cam/"

Make sure to include the trailing slash (/) in the "Cloud Cam/" string!  If you forget this slash then the README.md file will be saved to a file called "Cloud Cam" and not a folder!

The script should run and upload the file to your Dropbox:

 > Uploading "/home/pi/Dropbox-Uploader/README.md" to "/Cloud Cam/README.md"... DONE

Open your Dropbox account and look for the Cloud Cam folder.  You should see the README.md file there:

If the upload script failed with an error go back and check access to Dropbox has been enabled with the steps above and try again.

Woo hoo!  At this point the Pi is ready to start sending data to Dropbox.  Now follow the steps below to setup the camera motion detection software and upload data to Dropbox.

Motion Setup

To detect motion with the Pi camera you can use the excellent motion software package.  This program will turn the Pi into a dedicated security camera that can monitor a connected camera to look for motion or periodically capture images.

Be careful to follow the steps below to setup motion on the Raspberry Pi.  If you search the internet you might find older instructions for installing a custom build of motion on the Pi.  However those instructions won't work with the current Jessie version of Raspbian.  You'll need to follow the steps below to load a special Pi camera kernel module, and then you can install and use motion right from the Raspbian package repository.

Pi Camera V4L2 Kernel Module

Before you can use the motion package you'll need to load a special kernel module that will make it work with the Pi camera.  Normally the Pi camera talks directly to the Pi's GPU so programs have to be written to specifically use the Pi camera--i.e. the camera doesn't appear like a webcam or other video source.  However the Pi foundation created a special kernel module to make the Pi camera work with Linux's Video4Linux 2 API and look like a normal video source.  Using the Pi camera V4L2 module you can use the Pi camera with motion and most other Linux video programs.

To load this module first make sure you're using the latest Raspbian Jessie image on the Pi.  Then connect to the Pi and run the following command to edit the /etc/modules configuration file:

sudo nano /etc/modules

This file controls what extra kernel modules are loaded on boot and we need to add a new line to include the special Pi camera V4L2 module.  Scroll down to the bottom of the file and add the following line:

bcm2835_v4l2

There might be other lines in the file so leave them alone and add the bcm2835_v4l2 line at the end of the file.  For example here's how a modified configuration file should look:

Save the file and exit the editor by pressing Ctrl-o then enter and then Ctrl-x.

Now reboot the Pi by running:

sudo reboot

After the Pi boots again connect in a SSH terminal and run the following command to check the module successfully loaded and created a video source for the Pi camera:

ls -l /dev/video*

You should see a /dev/video0 source listed, like:

crw-rw----+ 1 root video 81, 0 Nov  4 04:46 /dev/video0

If you don't see the /dev/video0 source you can run the lsmod command to list all the active kernel modules and check if the bcm2835_v4l2 modules is loaded.  You can attempt to manually load the module by running sudo modprobe bcm2835_v4l2.  If all else fails check the kernel log by running the dmesg command to see if there are any error messages which might indicate a problem loading the module.  The Pi camera V4L thread on the Raspberry Pi forums might be able to troubleshoot and provide more insight into problems loading the module.

Once you've confirmed the Pi camera V4L kernel module is loaded and a /dev/video0 device exists move on to the next section to setup the motion package.

Motion Install & Configuration

With the Pi camera configured as a Linux video source you can now use it with software like motion.  First you'll want to install motion by running the following command:

sudo apt-get update
sudo apt-get install -y motion

You should see text similar to the following as motion is installed:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
Suggested packages:
  mysql-client postgresql-client
Recommended packages:
  ffmpeg
The following NEW packages will be installed:
  motion
0 upgraded, 1 newly installed, 0 to remove and 15 not upgraded.
Need to get 0 B/230 kB of archives.
After this operation, 746 kB of additional disk space will be used.
Preconfiguring packages ...
Selecting previously unselected package motion.
(Reading database ... 123293 files and directories currently installed.)
Preparing to unpack .../motion_3.2.12+git20140228-4+b2_armhf.deb ...
Unpacking motion (3.2.12+git20140228-4+b2) ...
Processing triggers for man-db (2.7.0.2-5) ...
Processing triggers for systemd (215-17+deb8u2) ...
Setting up motion (3.2.12+git20140228-4+b2) ...

After the package installs you'll want to run a command to fix an issue with the motion package not setting the right ownership for the location where it stores images:

sudo mkdir /var/lib/motion
sudo chown motion:motion /var/lib/motion

Now you'll need to edit the global configuration file for motion to customize its behavior.  First skim this page on motion's configuration options to get an overview of the available options.  Then run the following command to start editing the /etc/motion/montion.conf file:

sudo nano /etc/motion/motion.conf

Most options you'll want to leave the same as the default, but scroll down to these lines that control the size of the captured image:

# Image width (pixels). Valid range: Camera dependent, default: 352
width 320

# Image height (pixels). Valid range: Camera dependent, default: 288
height 240

Bump the size of the captured image up to 1280x720 pixels (720p)  by making those lines look like:

# Image width (pixels). Valid range: Camera dependent, default: 352
width 1280

# Image height (pixels). Valid range: Camera dependent, default: 288
height 720

Another option to change is the motion threshold.  This setting controls how many pixels have to change between frames before motion is detected.  The default value is 1500 pixels, but that's a relatively small value for a 720p frame (which has almost 1 million pixels).  Increase the value to 3000 to start:

# Threshold for number of changed pixels in an image that
# triggers motion detection (default: 1500)
threshold 3000

If the camera is too sensitive you can increase this threshold to a larger value, or if the camera isn't sensitive enough try droppping it to a lower value.  You might need to experiment with different values to see what works best for your setup.

The minimum_motion_frames setting is another useful setting to help control the sensitivity of motion detection.  The default setting looks like:

# Picture frames must contain motion at least the specified number of frames
# in a row before they are detected as true motion. At the default of 1, all
# motion is detected. Valid range: 1 to thousands, recommended 1-5
minimum_motion_frames 1

You can increase this value to require more than 1 consecutive changed frame before triggering motion.  For example if you set this to 3 then there must be 3 consecutive frames that differ by the threshold amount of pixels before motion is detected.

This setting can help deal with false positives where motion is detected from random camera noise, dust, etc.  The trade off is that very fast motion that only occurs for a frame or two won't be detected.

I like setting the value to 2 so that two consecutive frames must have motion before the motion event is triggered.  This prevents a random blip or dust particle from triggering motion, but should still pick up most quick events.  Change the value to look like:

# Picture frames must contain motion at least the specified number of frames
# in a row before they are detected as true motion. At the default of 1, all
# motion is detected. Valid range: 1 to thousands, recommended 1-5
minimum_motion_frames 2

Another setting to change is the video capture setting.  Scroll down to this part of the configuration:

# Use ffmpeg to encode movies in realtime (default: off)
ffmpeg_output_movies on

To keep this project simple we'll disable video output--change the setting to off:

# Use ffmpeg to encode movies in realtime (default: off)
ffmpeg_output_movies off

Feel free to explore enabling movies later, but be aware it might require other software to be installed or use a lot of the Pi's CPU (particularly if the resolution is high like 720p or 1080p).

The snapshot_interval setting allows you to have the camera take a photo at a certain frequency regardless of there being motion or not:

# Make automated snapshot every N seconds (default: 0 = disabled)
snapshot_interval 0

You probably don't want to turn this setting on because it can generate a lot of data and overload your Dropbox account, however it's good to know that it exists and is an option if you don't need motion detection.

The target_dir setting controls where captured images are stored locally on the Pi.  You don't need to change this setting, but it is good to know that a copy of captured images will be stored in this location (the default is /var/lib/motion):

# Target base directory for pictures and films
# Recommended to use absolute path. (Default: current working directory)
target_dir /var/lib/motion

You can enable a video stream of the camera by changing the stream_localhost setting:

# Restrict stream connections to localhost only (default: on)
stream_localhost on

By setting stream_localhost to off then any computer on your network can view a video stream from the Pi's camera.  This is useful for setting up the camera and making sure it has a good view of what you want to capture.  You can enable the stream by setting the value to off:

# Restrict stream connections to localhost only (default: on)
stream_localhost off

Be aware that anyone on your network can view the stream!  By default there is no authentication or other login required to see the stream.

Finally the last important setting and one that you must change is the on_picture_save setting which controls what action happens when the camera takes a picture (either from detecting motion or as part of a periodic picture capture):

# Command to be executed when a picture (.ppm|.jpg) is saved (default: none)
# To give the filename as an argument to a command append it with %f
; on_picture_save value

By default there is no action defined for this setting and it is commented out with a semicolon.  To enable the sync of photos to Dropbox we can insert a call to the Dropbox uploader script (that was setup in the previous section).

Modify the on_picture_save configuration to look exactly like the following:

# Command to be executed when a picture (.ppm|.jpg) is saved (default: none)
# To give the filename as an argument to a command append it with %f
on_picture_save dropbox_uploader -f /home/pi/.dropbox_uploader upload %f "Cloud Cam/"

This will tell motion to call the dropbox_uploader command and upload the picture to the "Cloud Cam" folder on Dropbox.  Notice the -f parameter is used to point to the configuration file that was created during the Dropbox app setup (which lives as a hidden file in the pi user's home directory).

That's all you need to change to setup motion!  Save the configuration file and exit the text editor by pressing Ctrl-o then enter and then Ctrl-x.

Now test that motion runs and uploads pictures to Dropbox.  Manually run motion by executing: 

sudo motion -n

You should see motion start and print some initialization that looks similar to:

[0] [NTC] [ALL] conf_load: Processing thread 0 - config file /etc/motion/motion.conf
[0] [ALR] [ALL] conf_cmdparse: Unknown config option "sdl_threadnr"
[0] [NTC] [ALL] motion_startup: Motion 3.2.12+git20140228 Started
[0] [NTC] [ALL] motion_startup: Logging to syslog
[0] [NTC] [ALL] motion_startup: Using log type (ALL) log level (NTC)
[0] [NTC] [ENC] ffmpeg_init: ffmpeg LIBAVCODEC_BUILD 3670016 LIBAVFORMAT_BUILD 3670272
[0] [NTC] [ALL] main: Thread 1 is from /etc/motion/motion.conf
[0] [NTC] [ALL] main: Thread 1 is device: /dev/video0 input -1
[0] [NTC] [ALL] main: Stream port 8081
[0] [NTC] [ALL] main: Waiting for threads to finish, pid: 1875
[1] [NTC] [ALL] motion_init: Thread 1 started , motion detection Enabled
[1] [NTC] [VID] vid_v4lx_start: Using videodevice /dev/video0 and input -1
[1] [NTC] [VID] v4l2_get_capability: 
------------------------
cap.driver: "bm2835 mmal"
cap.card: "mmal service 16.1"
cap.bus_info: "platform:bcm2835-v4l2"
cap.capabilities=0x85200005
------------------------
[1] [NTC] [VID] v4l2_get_capability: - VIDEO_CAPTURE
[1] [NTC] [VID] v4l2_get_capability: - VIDEO_OVERLAY
[1] [NTC] [VID] v4l2_get_capability: - READWRITE
[1] [NTC] [VID] v4l2_get_capability: - STREAMING
[1] [NTC] [VID] v4l2_select_input: name = "Camera 0", type 0x00000002, status 00000000
[1] [NTC] [VID] v4l2_select_input: - CAMERA
[0] [NTC] [STR] httpd_run: motion-httpd testing : IPV4 addr: 127.0.0.1 port: 8080
[1] [WRN] [VID] v4l2_select_input: Device doesn't support VIDIOC_G_STD
[0] [NTC] [STR] httpd_run: motion-httpd Bound : IPV4 addr: 127.0.0.1 port: 8080
[1] [NTC] [VID] v4l2_do_set_pix_format: Testing palette YU12 (1280x720)
[0] [NTC] [STR] httpd_run: motion-httpd/3.2.12+git20140228 running, accepting connections
[1] [NTC] [VID] v4l2_do_set_pix_format: Using palette YU12 (1280x720) bytesperlines 1280 sizeimage 1382400 colorspace 00000001
[0] [NTC] [STR] httpd_run: motion-httpd: waiting for data on 127.0.0.1 port TCP 8080
[1] [NTC] [VID] v4l2_scan_controls: found control 0x00980900, "Brightness", range 0,100 
[1] [NTC] [VID] v4l2_scan_controls: 	"Brightness", default 50, current 50
[1] [NTC] [VID] v4l2_scan_controls: found control 0x00980901, "Contrast", range -100,100 
[1] [NTC] [VID] v4l2_scan_controls: 	"Contrast", default 0, current 0
[1] [NTC] [VID] v4l2_scan_controls: found control 0x00980902, "Saturation", range -100,100 
[1] [NTC] [VID] v4l2_scan_controls: 	"Saturation", default 0, current 0
[1] [NTC] [VID] v4l2_scan_controls: found control 0x0098090e, "Red Balance", range 1,7999 
[1] [NTC] [VID] v4l2_scan_controls: 	"Red Balance", default 1000, current 1000
[1] [NTC] [VID] v4l2_scan_controls: found control 0x0098090f, "Blue Balance", range 1,7999 
[1] [NTC] [VID] v4l2_scan_controls: 	"Blue Balance", default 1000, current 1000
[1] [NTC] [VID] vid_v4lx_start: Using V4L2
[1] [NTC] [ALL] image_ring_resize: Resizing pre_capture buffer to 1 items
[1] [NTC] [STR] http_bindsock: motion-stream testing : IPV4 addr: 0.0.0.0 port: 8081
[1] [NTC] [STR] http_bindsock: motion-stream Bound : IPV4 addr: 0.0.0.0 port: 8081
[1] [NTC] [ALL] motion_init: Started motion-stream server in port 8081 auth Disabled
[1] [NTC] [ALL] image_ring_resize: Resizing pre_capture buffer to 2 items

If you see an error go back and carefully check that motion was installed, and that the configuration was updated as described above and try again.

Now move something in front of the camera.  After a few moments you should see a motion event start:

[1] [NTC] [ALL] motion_detected: Motion detected - starting event 1
[1] [NTC] [EVT] event_newfile: File of type 1 saved to: /var/lib/motion/01-20151104082928-00.jpg
[1] [NTC] [EVT] event_newfile: File of type 1 saved to: /var/lib/motion/01-20151104082928-01.jpg
 > Uploading "/var/lib/motion/01-20151104082928-00.jpg" to "/Cloud Cam/01-20151104082928-00.jpg"...  > Uploading "/var/lib/motion/01-20151104082928-01.jpg" to "/Cloud Cam/01-20151104082928-01.jpg"... DONE
DONE

Notice the lines that look like " > Uploading "/var/lib/motion/01-20151104082928-00.jpg" to "/Cloud Cam/01-20151104082928-00.jpg"...  DONE", that means the dropbox_uploader script successfully uploaded the image to Dropbox.  If you open your Dropbox Cloud Cam folder you should see the image file is now there--woo hoo!

If you see an error or don't see the image in Dropbox go back and check the dropbox_uploader script was installed and setup as described above.  Make sure you can manually use the script to upload to your Dropbox account.  Also be certain that you ran the chmod a+r command to make the ~/.dropbox_uploader file readable by all users as described above.

If you're curious about the meaning of the file names that motion writes, for example '01-20151104082928-00.jpg', the file name is composed of these parts:

  • Event number - This is a numer that increases every time there is a new motion event since the motion program started running.  This is the value 01 in the example above.
  • Dash
  • Date - The date in year, month, day format.  The example above is November 4th, 2015.
  • Time - The time in hour, minute, second format.  The example above is 8:29:28 AM.
  • Dash
  • Frame number - This is just a numeric ID of the frame within this motion event.  Larger values are further in the future than smaller values.  The example above is a frame number 00.

You can actually change this file format by modifying the jpeg_filename option in motion's config file.

One final thing you can check with motion running is the output of its video stream.  From a web browser access http://raspberrypi:8081/ (note that you might need to substitute raspberrypi in the URL with the IP address of your Raspberry Pi).  You should see the video from the camera, for example:

Now stop motion by pressing Ctrl-c in the terminal.  After a few moments it will terminate and return you to the console.  In the next section you'll configure motion to automatically start on boot.

Run Motion on Boot

To configure motion to run on boot you'll need to run a few commands that enable its init script.

First edit the /etc/default/motion file to enable its daemon mode by running:

sudo nano /etc/default/motion

Change the start_motion_daemon=no line to yes.  The file should look like the following:

Save and exit by pressing Ctrl-o then enter and then Ctrl-x.

Now enable the motion service with Raspbian Jessie's systemd service by running:

sudo systemctl enable motion

You should see this command print information about synchronizing the state of the motion.service:

Synchronizing state for motion.service with sysvinit using update-rc.d...
Executing /usr/sbin/update-rc.d motion defaults
Executing /usr/sbin/update-rc.d motion enable

Now reboot the Pi and check that the red camera light turns on to show that motion is running.  You should also be able to move in front of the camera and see images uploaded to Dropbox.  You can also connect to motion's video stream in a browser to check what the camera is seeing.

Finally connect to the Pi in a terminal again to see some commands that control and troubleshoot motion.  First you can see motion's log using systemd's journalctl tool:

sudo journalctl -u motion

After running the command all of the output of motion will be printed.  Press down or page down to page through results, and q to quit.  If you have problems or motion doesn't run check the log file to see if there is an error that can help fix the problem.

You can also check the status of the motion service by running:

sudo systemctl status motion

This will print out information about the motion process and is useful to check if it's running (look for the 'active (running)' status).

You can stop motion by running:

sudo systemctl stop motion

Note that this will only stop motion until the next boot.  If you want to permanently disable motion so that it doesn't run at boot anymore run:

sudo systemctl disable motion

If you're curious you can use other systemd commands to manipulate the motion service.  You can learn more about systemd's commands from this great Arch Linux systemd wiki page (even though it's for a different Linux distribution the information still pertains to Raspbian Jessie).

That's all there is to running the motion package and uploading images to Dropbox with the cloud cam!

Last updated on 2016-01-28 at 03.17.29 PM Published on 2015-11-05 at 03.00.35 PM