When the Raspberry Pi Zero v1.3 announced they were going to have a camera port I immediately bought one along with a camera. I got the pieces, put it together, took a few pictures and forgot about it for a while. Then, The PiHut came out with their ZeroView and I got a new idea for the camera.
I had been having a problem with our mailman throwing packages, literally. I work from home and my office is in the front of the house. I noticed that whenever the USPS mailman was delivering a package he would walk across my yard, to the edge of my front walk and throw packages across the sidewalk and up my stairs at my door. There was only one guy doing it and everyone else was doing their job correctly, but his delivery method was very irritating.
I put the system together, got the video recording, attached it to my front window, and got a couple videos of the mailman in action. But, this setup had a lot of pain points. First, it was difficult to get power to the system. There are no plugs that are close to my front door. Second, there was no WiFi on the Zero v1.3, so it was a pain to transfer the video to another system. Needless to say, this project didn't stay attached to my front window long and it was added to the pile of SBCs.
After I pulled all my SBCs out of my closet, this was one of the first projects I decided needed to be updated and finished. Earlier this year, I had bought a JuiceBox Zero when it Kickstarted. I also had a battery just sitting there, so I added them to the parts for the build. I also remember what a pain it was to transfer files, so I picked up a Raspberry Pi Zero W, which has WiFi, to replace the v1.3 from the original build. The complete system now looks like this:
I added the latest version of Rasbian Stretch Lite to the microSD card and off we went.
I only want to record picture and video when there was something happening. There are a ton of articles, projects, custom OS images, etc returned when you search for "raspberry pi camera detect motion". After reading through a number of builds, I decided the Motion project met all of my needs.
I installed Motion using the latest .deb provided by the project and started with a copy of the installed config file (/etc/motion/motion.conf). I opted to run Motion as the "pi" user and used one of the standard locations for my config file: ~/.motion/motion.conf. I want to capture still images with the area of motion highlighted and video of the motion with a few extra seconds added. Motion has a ton of configuration options. I ended up using most of the defaults, but here are a few key settings:
daemon on
logfile /var/log/motion/motion.log
norm 1
width 640
height 480
mmalcam_name vc.ril.camera
event_gap 5
locate_motion_mode preview
locate_motion_style redbox
target_dir /home/pi/MotionCaptures
Next, I copied their example systemd service file over and made it a user service:
cd /etc/systemd/system
cp /usr/share/motion/examples/motion.service motion@.service
Change a couple lines with your favorite editor (- means remove line, + means add line):
After=local-fs.target network.target
[Service]
-PIDFile=/var/run/motion.pid
+User=%i
ExecStart=/usr/bin/motion -n
Type=simple
StandardError=null
Then enable and start the service (as pi user):
systemctl enable motion@pi.service
systemctl start motion@pi.service
Now, motion runs as pi with your local configuration:
pi@picam:~/.motion $ systemctl status motion@pi.service
● motion@pi.service - Motion daemon
Loaded: loaded (/etc/systemd/system/motion@.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2018-09-14 20:52:50 EDT; 14h ago
Main PID: 321 (motion)
CGroup: /system.slice/system-motion.slice/motion@pi.service
└─321 /usr/bin/motion -n
Sep 14 20:52:50 picam systemd[1]: Started Motion daemon.
Sep 14 20:53:03 picam motion[321]: [26342936:motion] [NTC] [ALL] conf_load: Processing thread 0 - co
Sep 14 20:53:03 picam motion[321]: [26342936:motion] [NTC] [ALL] motion_startup: Motion 4.1.1 Starte
Sep 14 20:53:03 picam motion[321]: [26342936:motion] [NTC] [ALL] motion_startup: Logging to file (/v
pi@picam:~/.motion $ ps -ef | grep [m]otion
pi 321 1 5 Sep14 ? 00:38:58 /usr/bin/motion -n
The final pain point was being able to get the files off the Pi to a system with a monitor. I decided to use syncthing which I use for a number of other file synchronization tasks. It is available in the regular apt repos and installs as usual. I closely followed the excellent docs for configuration and setting up the systemd service. It is set up very similar to Motion as above.
pi@picam:~ $ systemctl status syncthing@pi.service
● syncthing@pi.service - Syncthing - Open Source Continuous File Synchronization for pi
Loaded: loaded (/lib/systemd/system/syncthing@.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2018-09-14 20:52:50 EDT; 14h ago
Docs: man:syncthing(1)
Main PID: 324 (syncthing)
CGroup: /system.slice/system-syncthing.slice/syncthing@pi.service
└─324 /usr/bin/syncthing -no-browser -no-restart -logflags=0
pi@picam:~ $ ps -ef | grep [s]yncthing
pi 324 1 1 Sep14 ? 00:07:29 /usr/bin/syncthing -no-browser -no-restart -logflags=0
After syncthing was setup, I added one of my home systems as a remote device. The system I chose has cloud backup in case I need a file later. I then set up synchronization on /home/pi/MotionCaptures which is configured (see above) to be the target directory for all Motion images and video. Again, see the syncthing docs for the remote device and synchronization setup.
Finally, I tested the JuiceBox Zero to see how long this system could run on battery. It turns out it is only about 10 hours with the battery I purchased, so I think this is going to be a power backup solution for now. Just in case I do have an extended outage, I wanted to be sure my filesystem doesn't get corrupted by a hard shutdown. I installed the LowBatteryShutdown script provided by JuiceBox Zero using their directions. After I installed the script, I noticed that the system was being a lot less responsive. There was definitely something going on with the shutdown script:
pi@picam:~ $ top
top - 08:38:10 up 3 min, 2 users, load average: 1.41, 1.41, 0.66
Tasks: 99 total, 2 running, 67 sleeping, 0 stopped, 1 zombie
%Cpu(s): 98.7 us, 1.3 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 378904 total, 50872 free, 120048 used, 207984 buff/cache
KiB Swap: 102396 total, 102396 free, 0 used. 203500 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
309 root 20 0 17376 5036 3348 R 90.1 1.3 2:33.96 python
pi@picam:~ $ ps -ef | grep 309
root 309 294 55 08:34 ? 00:01:13 python /home/pi/LowBatteryShutdown/LowBatteryShutdown.py
Once you look at the code, the culprit is pretty obvious:
...
# Now we wait here for something amazing to happen
while True:
# Do Nothing
pass
This busy wait is VERY busy. So, I fixed the problem and sent a pull request.
This little system will be living on the window of my office, and will be incorporated into the design of my final SBC mounting solution.