September 24, 2017
Raspberry Pi Zero W Setup
“You live in a world where an entire operating system can fit on a wafer thin piece of plastic smaller than your finger tip. And you can…

By Andrew Rapp
16 min read
"You live in a world where an entire operating system can fit on a wafer thin piece of plastic smaller than your finger tip. And you can run this on a $5 (or $10) computer that is small enough to give away on the cover of a magazine. You should be amazed, excited, and happy about this." — Adafruit
This is my stream-of-consciousness notes to get a headless (ie no display) raspberry pi zero w up and running and experiment with some of the features, including: Bluetooth, Camera and perhaps GPIO.
Starting with a Pi zero w, a power supply and an SD card I followed this guide to get a bootable Pi on Raspbian Jessie lite https://learn.adafruit.com/raspberry-pi-zero-creation/install-os-on-to-sd-card. Raspian stretch had just been released during this time however I used Jessie since it is presumably is more stable.
Update: The Raspberry Pi Imager simplifies this process by optionally configuring your wifi network, machine name and ssh keys. After booting (wait a few minutes) you should be able to ssh with: ssh pi@
Deviations
- I'm using a mac and found the Etcher app to write Raspbian to the SD card. One click
- ssh pi@raspberrypi.local did not work. Had to go to the router's dhcp table to find the ip address
Bluetooth
I've never worked with Bluetooth before so I thought I would poke around with the Pi Bluetooth. I'd like to use Bluetooth as an out of band connection so that I can configure the Pi without needing to plug in a serial cable. For example, if I want to connect to a new wifi network. I can also see Bluetooth being useful for communicating with the Pi from my mobile phone.
The Raspbian Jessie image seems to come standard with Bluetooth installed but some configuration changes are in order.
Config changes gathered from various forum posts — not entirely sure if these are relevant.
Support serial port profile
sudo vi /etc/systemd/system/dbus-org.bluez.service
ExecStart=/usr/lib/bluetooth/bluetoothd -C
ExecStartPost=/usr/bin/sdptool add SPsudo vi /etc/systemd/system/dbus-org.bluez.service
ExecStart=/usr/lib/bluetooth/bluetoothd -C
ExecStartPost=/usr/bin/sdptool add SPOne post on the raspi forum suggested disabling pnat, so
sudo vi /etc/bluetooth/main.conf
DisablePlugins = pnatsudo vi /etc/bluetooth/main.conf
DisablePlugins = pnatNow for the pairing: Open Bluetooth in phone settings, making the phone discoverable. Then,
pi@raspberrypi:~ $ bluetoothctl
[NEW] Controller B8:27:EB:08:88:DF raspberrypi [default]
[NEW] Device 64:BC:0C:E2:9C:A5 Nexus 5X
[bluetooth]# power on
Changing power on succeeded
[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:08:88:DF Discovering: yes
[NEW] Device 00:0D:4B:E7:41:2E Roku Player
[bluetooth]# agent on
Agent registered
[CHG] Device 64:BC:0C:E2:9C:A5 RSSI: -53
[bluetooth]# pair 64:BC:0C:E2:9C:A5
Attempting to pair with 64:BC:0C:E2:9C:A5
[CHG] Device 64:BC:0C:E2:9C:A5 Connected: yes
Request confirmation
[agent] Confirm passkey 551234 (yes/no): yes
[CHG] Device 64:BC:0C:E2:9C:A5 Paired: yes
Pairing successful
[CHG] Device 64:BC:0C:E2:9C:A5 Connected: no
[CHG] Device 64:BC:0C:E2:9C:A5 RSSI: -62pi@raspberrypi:~ $ bluetoothctl
[NEW] Controller B8:27:EB:08:88:DF raspberrypi [default]
[NEW] Device 64:BC:0C:E2:9C:A5 Nexus 5X
[bluetooth]# power on
Changing power on succeeded
[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:08:88:DF Discovering: yes
[NEW] Device 00:0D:4B:E7:41:2E Roku Player
[bluetooth]# agent on
Agent registered
[CHG] Device 64:BC:0C:E2:9C:A5 RSSI: -53
[bluetooth]# pair 64:BC:0C:E2:9C:A5
Attempting to pair with 64:BC:0C:E2:9C:A5
[CHG] Device 64:BC:0C:E2:9C:A5 Connected: yes
Request confirmation
[agent] Confirm passkey 551234 (yes/no): yes
[CHG] Device 64:BC:0C:E2:9C:A5 Paired: yes
Pairing successful
[CHG] Device 64:BC:0C:E2:9C:A5 Connected: no
[CHG] Device 64:BC:0C:E2:9C:A5 RSSI: -62Note: I've found It take take a minute or so to see your device show up after starting the discovery sequence.
You can also pair with a Mac. In system preferences, open bluetooth and it should display "Now discoverable as xxxxxx". Now after following the same sequence on the Pi the mac should show up as a [New] Device. My newer mac paired easily but my older 2011 Mac was not visible to the Pi when connecting from a different level in the house and when in the same room it took several minutes to be discovered.
Once paired, the raspberry pi should show up as a serial port on the mac as /dev/tty.raspberrypi-SerialPort Now you can connect to it using any serial port app (e.g. screen /dev/tty.raspberrypi-SerialPort)
If needed, to get the Bluetooth address of the client
- Android: System -> About Phone -> Status
- Mac: from About This Mac->System Report -> Bluetooth
Reference: https://www.element14.com/community/docs/DOC-81266/l/setting-up-bluetooth-on-the-raspberry-pi-3?CMP=SOM-TWITTER-PRG-BLOG-CSTANTON-BTPI3# (you'll want to disable javascript for this site because annoying popups)
Make Phone and Pi Talk via Bluetooth Serial Port
pi@raspberrypi:~ $ sudo sdptool add sp
pi@raspberrypi:~ $ sudo rfcomm watch hci0
Waiting for connection on channel 1
Connection from 64:BC:0C:E2:9C:A5 to /dev/rfcomm0
Press CTRL-C for hanguppi@raspberrypi:~ $ sudo sdptool add sp
pi@raspberrypi:~ $ sudo rfcomm watch hci0
Waiting for connection on channel 1
Connection from 64:BC:0C:E2:9C:A5 to /dev/rfcomm0
Press CTRL-C for hangupOn Android install Bluetooth Terminal App (apparently Iphone will not work due to lack of support for SPP profile)
Connect to pi (secure or insecure) from BlueTerm. After the BlueTerm connects, the serial port (/dev/rfcomm0) will be present. On the Pi, Install screen and
sudo screen /dev/rfcomm0sudo screen /dev/rfcomm0Now should be able to type in the terminal and see it on the other device. Quit screen with ctrl + A + D. The Android client is a little flaky and sometimes requires multiple connection attempts.
Bluetooth Login
This Pi is headless so the only way I can connect to it without a cable is via ssh. But that won't work if it's not on a wifi network so to solve this problem we can login over Bluetooth instead — out of band.
Run the following commands on the Pi
sudo sdptool add sp
sudo mknod -m 666 /dev/rfcomm0 c 216 0
sudo rfcomm watch /dev/rfcomm0 1 /sbin/agetty rfcomm0 115200 linuxsudo sdptool add sp
sudo mknod -m 666 /dev/rfcomm0 c 216 0
sudo rfcomm watch /dev/rfcomm0 1 /sbin/agetty rfcomm0 115200 linuxAdmittedly, I'm not sure exactly what's going on with the mknod command, though it seems to modify the attributes of the serial device and persists across boots.
From mknod man docs "make block or character special files" and "Both MAJOR and MINOR must be specified when TYPE is b, c, or u, and they must be omitted when TYPE is p. If MAJOR or MINOR begins with 0x or 0X, it is interpreted as hexadecimal; otherwise, if it begins with 0, as octal; otherwise, as decimal" Okay sure.
On a Mac or other Bluetooth client that is already paired
screen /dev/tty.zero-SerialPortscreen /dev/tty.zero-SerialPort
I ignored a few bash errors that streamed by however it didn't seem to affect the login functionality
-bash: cannot set terminal process group (30587): Inappropriate ioctl for device
-bash: no job control in this shell-bash: cannot set terminal process group (30587): Inappropriate ioctl for device
-bash: no job control in this shellNow I can take my headless Pi anywhere and use my mobile phone for communication, or bring it to any wifi network, power up, connect via Bluetooth and configure wifi (boom)!
sudo vi /etc/wpa_supplicant/wpa_supplicant.conf
sudo service networking restartsudo vi /etc/wpa_supplicant/wpa_supplicant.conf
sudo service networking restartAt least once when I quit screen and attempted to reconnect, I got resource busy error. Not sure what's going on here but this was solved by power cycling bluetooth on the Mac.
Next steps are to figure out how to config the bluetooth login to start when the Pi boots and Android Bluetooth experimentation so I can control Pi apps from my phone.
Pybluez
Pybluez provides a bluetooth api from Python. I'm not sure I need this as I can create a serial port with Linux tools and connect to that from any platform that supports serial access.
pybluez setup http://www.kinmanlam.com/2017/05/the-5-minute-guide-to-setup-raspberry.html
libbluetooth does not exist so instead
sudo apt-get install libbluetooth3sudo apt-get install libbluetooth3After pybluez install:
sdptool add spsdptool add spRun the rfcomm-server example (root apparently required apparently)
karulis/pybluez pybluez - Bluetooth Python extension module
Now can connect from Android (blueterm)
Bluetooth programming with Python - PyBluez Python is a versatile and powerful dynamically typed object oriented language, providing syntactic clarity along with…
Some android/python bluetooth http://blog.davidvassallo.me/2014/05/11/android-linux-raspberry-pi-bluetooth-communication/
Java Bluetooth is a thing apparently but looks painful: https://github.com/intel-iot-devkit/tinyb/ This guy seemed to get it working http://fam-haugk.de/starting-with-bluetooth-le-on-the-raspberry-pi
GPIO
Control gpio: use python (highly supported). There is also a java project http://pi4j.com/
Camera
The camera setup is well documented in the Pi docs https://www.raspberrypi.org/documentation/usage/camera/
Most importantly however, is to make sure the camera is enabled:
sudo raspi-configsudo raspi-configselect interfacing options and enable the camera
I installed both python-picamera and python3-picamera but this should only be necessary if you want to control the camera from a Python app
Here's a write up how to capture time-lapse with your Pi
Raspberry Pi Zero W as a headless time-lapse camera tl;dr: There are many ways to capture time-lapse videos. But this one is cheap, completely wireless, and mine. If you…
With the Python api it's easy to snap photos and record videos
3. Quick Start - Picamera 1.10 documentation Note that you should always ensure you call on the PiCamera object to clean up resources. The following example…
Python picamera - Raspberry Pi Documentation We've provided some basic examples to help you discover possible uses for your Raspberry Pi and to get started with…
Lens Adjustment
The default camera focus is no-bueno for me. I need it to focus at infinity but the factory focus is too close.
Update
tl;dr when removing the camera from a SparkFun case, be very careful. Use tweezers if necessary to slowly pop the board off the mounts or this happens
I attempted to glue it back but in doing so I seemed to have destroyed the camera, such that it is not longer identified by the Pi. So this was a bummer but it did give me an opportunity to play around with the lens adjustment. Cameras found on pretty much any phone have auto focus built-in but the Pi camera is fixed focus. The lens is threaded into the lens housing but it's hard to turn because there are only very slight indentations on the lens. Adafruit at one time sold a tool for adjustment but it is sold out as of this time.
Now, a few weeks later and I have two replacement cameras to break again: another Pi v2 and I bought a generic Arducam (pi v1). I remembered I had a snap ring pliers, and these worked pretty good for turning the lens without mauling the plastic on the lense.
Rotating the lens counter clockwise will zoom-in the focus for close ups. The uv4l stream server is useful for getting the focus correct. I found my camera, as it came from the factory was focused for landscape/infiniti. At this position it can really only turn counter-clockwise. But this focusing nonsense is really inconvenient. It would be nice if they would offer a auto-focus camera for the pi.
UV4L
Install uv4l described in https://www.linux-projects.org/uv4l/installation/ Install the extras and server. Allows web streaming of camera
I performed the following install/updates:
sudo apt-get install uv4l uv4l-raspicam
sudo apt-get install uv4l-raspicam-extras
sudo rpi-update
sudo apt-get install uv4l-server uv4l-uvc uv4l-xscreen uv4l-mjpegstream uv4l-dummy uv4l-raspidispsudo apt-get install uv4l uv4l-raspicam
sudo apt-get install uv4l-raspicam-extras
sudo rpi-update
sudo apt-get install uv4l-server uv4l-uvc uv4l-xscreen uv4l-mjpegstream uv4l-dummy uv4l-raspidispEnabled the streaming server by uncommenting server-option. If using motion it may be a good idea to choose a different port, like 9080 since Motion uses 8080.
sudo vi /etc/uv4l/uv4l-raspicam.conf
server-option = — port=9080sudo vi /etc/uv4l/uv4l-raspicam.conf
server-option = — port=9080also you may want to increase the resolution by changing width/height to something larger, like 1280/960
Restart
sudo service uv4l_raspicam restartsudo service uv4l_raspicam restartNow you should be able to stream from the camera at
http://<pi ip address:9080/stream
If you are not seeing anything from the video, it's possible the cable connector is not seated properly as was the case for me. There's a Broadcom utility to help troubleshoot (I could only run this command successfully when logged in as the "pi" user. I learned later you can solve this by adding your user to the video group sudo usermod -aG video <username>)
vcgencmd get_cameravcgencmd get_cameraand if everything is good it should return
supported=1 detected=1supported=1 detected=1When my cable was not seated it reported
supported=1 detected=0.supported=1 detected=0.Motion
Motion is a Linux service that connects to a camera and detects motion based in images; it can capture motion events from the camera as photos or videos.
Install motion
sudo apt-get install motionsudo apt-get install motionUpdate: Second time around installing motion on raspbian stretch did not result in any errors or configuration mismatch.
everything seemed fine except
The home directory
/var/lib/motion' already exists. Not copying from/etc/skel'.
So
sudo chown motion:motion /var/lib/motion
UV4L provides a motion.conf but I don't recommend it since it is not compatible with the version of Motion installed as of July 2017
wget https://www.linux-projects.org/home/wp-content/uploads/2016/06/motion.conf
As of this writing you get motion Version 3.2.12+git20140228. Several of the config names have changed. If you startup with this config you'll see motion report config that it is unable to parse:
[0] [ALR] [ALL] conf_cmdparse: Unknown config option "despeckle" [0] [ALR] [ALL] conf_cmdparse: Unknown config option "max_mpeg_time" [0] [ALR] [ALL] conf_cmdparse: Unknown config option "output_all" [0] [ALR] [ALL] conf_cmdparse: Unknown config option "output_normal" [0] [ALR] [ALL] conf_cmdparse: Unknown config option "output_motion"
For example, gap becomes event_gap and webcam_* needs to become stream_*. The online config reference (http://www.lavrsen.dk/foswiki/bin/view/Motion/ConfigFileOptions) appears to not be up to date so best to refer to the motion.conf that is installed with Motion (/etc/motion/motion.conf).
I made the following changes (my version on left)
< v4l2_palette 8
---
> v4l2_palette 17
< #input -1
---
> input -1
< width 1280
---
> width 320
86c93
< height 960
---
> height 240
< framerate 100
---
> framerate 2
# this setting is very application dependent. with text_changes on (below) it will print the number of pixels changed on the photo which is very useful for adjusting the threshold so you can ignore false-positives
< threshold 30000
---
> threshold 1500
< lightswitch 80
---
> lightswitch 0
< event_gap 10
---
> event_gap 60
# this option disables motion from creating avi (video) files
< ffmpeg_output_movies off
---
> ffmpeg_output_movies on
#show number of pixels that changed on the photo
< text_changes on
---
> text_changes off
< text_double on
---
> text_double off
< target_dir /home/arapp/motion-files
---
> target_dir /var/lib/motion
< stream_localhost off
---
> stream_localhost on< v4l2_palette 8
---
> v4l2_palette 17
< #input -1
---
> input -1
< width 1280
---
> width 320
86c93
< height 960
---
> height 240
< framerate 100
---
> framerate 2
# this setting is very application dependent. with text_changes on (below) it will print the number of pixels changed on the photo which is very useful for adjusting the threshold so you can ignore false-positives
< threshold 30000
---
> threshold 1500
< lightswitch 80
---
> lightswitch 0
< event_gap 10
---
> event_gap 60
# this option disables motion from creating avi (video) files
< ffmpeg_output_movies off
---
> ffmpeg_output_movies on
#show number of pixels that changed on the photo
< text_changes on
---
> text_changes off
< text_double on
---
> text_double off
< target_dir /home/arapp/motion-files
---
> target_dir /var/lib/motion
< stream_localhost off
---
> stream_localhost onOther useful parameters:
lightswitch 80 — ignores sudden light changes, for example, turning off a light at night time. I'm guessing on 80%.
text_changes on — writes the number of pixels changed on the top right. This is helpful in tuning the threshold parameter.
text_double on — with higher resolution (e.g. 1280x960), the timestamp in the lower right corner is almost unreadable, so this setting makes it larger.
Restart the uv4l service
sudo service uv4l_raspicam restartsudo service uv4l_raspicam restartStart motion
sudo LD_PRELOAD=/usr/lib/uv4l/uv4lext/armv6l/libuv4lext.so motionsudo LD_PRELOAD=/usr/lib/uv4l/uv4lext/armv6l/libuv4lext.so motionOnly one service can use uv4l at a time so if running motion then the uv4l stream does not function. You can watch live video via the motion streaming server
If running motion as a service:
Edit /etc/default/motion and set daemon to true
sudo systemctl enable motionsudo systemctl enable motionreboot
Motion has been reliable so far except for one issue where it lost the camera. This seems to be a UV4L issue and it was around the time I was attempting to build Tensorflow.
syslog shows
Sep 24 16:25:51 zero motion: [1] [CRT] [VID] mjpegtoyuv420p: Corrupt image … continue
Sep 24 16:25:59 zero motion: [1] [CRT] [VID] mjpegtoyuv420p: Corrupt image … continue
Sep 24 16:26:31 zero motion: [1] [CRT] [VID] mjpegtoyuv420p: Corrupt image … continue
Sep 24 16:26:41 zero motion: [1] [CRT] [VID] mjpegtoyuv420p: Corrupt image … continue
Sep 24 16:28:08 zero motion: [0] [ERR] [ALL] main: Thread 1 — Watchdog timeout, trying to do a graceful restart
Sep 24 16:28:16 zero kernel: [2058625.700059] INFO: task kworker/0:0:23748 blocked for more than 120 seconds.
Sep 24 16:28:17 zero kernel: [2058625.700078] Not tainted 4.9.45+ #1031
Sep 24 16:28:20 zero kernel: [2058625.700083] “echo 0 > /proc/sys/kernel/hung_task_timeout_secs” disables this message.
Sep 24 16:28:20 zero kernel: [2058625.700091] kworker/0:0 D 0 23748 2 0x00000000
Sep 24 16:28:20 zero kernel: [2058625.700136] Workqueue: events_freezable mmc_rescan
Sep 24 16:28:20 zero kernel: [2058625.700287] [<c05d1d14>] (__schedule) from [<c05d20ac>] (schedule+0x50/0xa8)
Sep 24 16:28:20 zero kernel: [2058625.700312] [<c05d20ac>] (schedule) from [<c0479528>] (__mmc_claim_host+0x98/0x210)
Sep 24 16:28:20 zero kernel: [2058625.700330] [<c0479528>] (__mmc_claim_host) from [<c04796d0>] (mmc_get_card+0x30/0x34)
Sep 24 16:28:20 zero kernel: [2058625.700346] [<c04796d0>] (mmc_get_card) from [<c0482530>] (mmc_sd_detect+0x2c/0x80)
Sep 24 16:28:20 zero kernel: [2058625.700361] [<c0482530>] (mmc_sd_detect) from [<c047c6e4>] (mmc_rescan+0x288/0x488)
Sep 24 16:28:20 zero kernel: [2058625.700380] [<c047c6e4>] (mmc_rescan) from [<c0038b2c>] (process_one_work+0x11c/0x398)
Sep 24 16:28:20 zero kernel: [2058625.700395] [<c0038b2c>] (process_one_work) from [<c0038de4>] (worker_thread+0x3c/0x508)
Sep 24 16:28:20 zero kernel: [2058625.700416] [<c0038de4>] (worker_thread) from [<c003e944>] (kthread+0xf8/0x114)
Sep 24 16:28:20 zero kernel: [2058625.700440] [<c003e944>] (kthread) from [<c000fec8>] (ret_from_fork+0x14/0x2c)
Sep 24 16:28:20 zero motion: [1] [CRT] [VID] mjpegtoyuv420p: Corrupt image … continue
Sep 24 16:28:20 zero motion: [1] [NTC] [ALL] motion_loop: Thread exiting
Sep 24 16:28:20 zero motion: [1] [NTC] [STR] stream_stop: Closing motion-stream listen socket & active motion-stream sockets
Sep 24 16:28:20 zero motion: [1] [NTC] [STR] stream_stop: Closed motion-stream listen socket & active motion-stream sockets
Sep 24 16:28:20 zero motion: [1] [NTC] [VID] vid_close: Closing video device /dev/video0Sep 24 16:25:51 zero motion: [1] [CRT] [VID] mjpegtoyuv420p: Corrupt image … continue
Sep 24 16:25:59 zero motion: [1] [CRT] [VID] mjpegtoyuv420p: Corrupt image … continue
Sep 24 16:26:31 zero motion: [1] [CRT] [VID] mjpegtoyuv420p: Corrupt image … continue
Sep 24 16:26:41 zero motion: [1] [CRT] [VID] mjpegtoyuv420p: Corrupt image … continue
Sep 24 16:28:08 zero motion: [0] [ERR] [ALL] main: Thread 1 — Watchdog timeout, trying to do a graceful restart
Sep 24 16:28:16 zero kernel: [2058625.700059] INFO: task kworker/0:0:23748 blocked for more than 120 seconds.
Sep 24 16:28:17 zero kernel: [2058625.700078] Not tainted 4.9.45+ #1031
Sep 24 16:28:20 zero kernel: [2058625.700083] “echo 0 > /proc/sys/kernel/hung_task_timeout_secs” disables this message.
Sep 24 16:28:20 zero kernel: [2058625.700091] kworker/0:0 D 0 23748 2 0x00000000
Sep 24 16:28:20 zero kernel: [2058625.700136] Workqueue: events_freezable mmc_rescan
Sep 24 16:28:20 zero kernel: [2058625.700287] [<c05d1d14>] (__schedule) from [<c05d20ac>] (schedule+0x50/0xa8)
Sep 24 16:28:20 zero kernel: [2058625.700312] [<c05d20ac>] (schedule) from [<c0479528>] (__mmc_claim_host+0x98/0x210)
Sep 24 16:28:20 zero kernel: [2058625.700330] [<c0479528>] (__mmc_claim_host) from [<c04796d0>] (mmc_get_card+0x30/0x34)
Sep 24 16:28:20 zero kernel: [2058625.700346] [<c04796d0>] (mmc_get_card) from [<c0482530>] (mmc_sd_detect+0x2c/0x80)
Sep 24 16:28:20 zero kernel: [2058625.700361] [<c0482530>] (mmc_sd_detect) from [<c047c6e4>] (mmc_rescan+0x288/0x488)
Sep 24 16:28:20 zero kernel: [2058625.700380] [<c047c6e4>] (mmc_rescan) from [<c0038b2c>] (process_one_work+0x11c/0x398)
Sep 24 16:28:20 zero kernel: [2058625.700395] [<c0038b2c>] (process_one_work) from [<c0038de4>] (worker_thread+0x3c/0x508)
Sep 24 16:28:20 zero kernel: [2058625.700416] [<c0038de4>] (worker_thread) from [<c003e944>] (kthread+0xf8/0x114)
Sep 24 16:28:20 zero kernel: [2058625.700440] [<c003e944>] (kthread) from [<c000fec8>] (ret_from_fork+0x14/0x2c)
Sep 24 16:28:20 zero motion: [1] [CRT] [VID] mjpegtoyuv420p: Corrupt image … continue
Sep 24 16:28:20 zero motion: [1] [NTC] [ALL] motion_loop: Thread exiting
Sep 24 16:28:20 zero motion: [1] [NTC] [STR] stream_stop: Closing motion-stream listen socket & active motion-stream sockets
Sep 24 16:28:20 zero motion: [1] [NTC] [STR] stream_stop: Closed motion-stream listen socket & active motion-stream sockets
Sep 24 16:28:20 zero motion: [1] [NTC] [VID] vid_close: Closing video device /dev/video0Then, loops
Sep 24 16:29:19 zero motion: [1] [ERR] [VID] v4l2_next: VIDIOC_QBUF:
Sep 24 16:29:19 zero motion: [1] [ERR] [ALL] motion_loop: Video device fatal error — Closing video device
Sep 24 16:29:19 zero motion: [1] [NTC] [VID] vid_close: Closing video device /dev/video0
Sep 24 16:29:30 zero motion: [1] [WRN] [ALL] motion_loop: Retrying until successful connection with camera
Sep 24 16:29:30 zero motion: [1] [NTC] [VID] vid_v4lx_start: Using videodevice /dev/video0 and input -1
Sep 24 16:29:30 zero motion: [1] [ALR] [VID] vid_v4lx_start: Failed to open video device /dev/video0:Sep 24 16:29:19 zero motion: [1] [ERR] [VID] v4l2_next: VIDIOC_QBUF:
Sep 24 16:29:19 zero motion: [1] [ERR] [ALL] motion_loop: Video device fatal error — Closing video device
Sep 24 16:29:19 zero motion: [1] [NTC] [VID] vid_close: Closing video device /dev/video0
Sep 24 16:29:30 zero motion: [1] [WRN] [ALL] motion_loop: Retrying until successful connection with camera
Sep 24 16:29:30 zero motion: [1] [NTC] [VID] vid_v4lx_start: Using videodevice /dev/video0 and input -1
Sep 24 16:29:30 zero motion: [1] [ALR] [VID] vid_v4lx_start: Failed to open video device /dev/video0:I've been syncing my motion files to my mac (when it's on) and placing them in a folder that gets uploaded to google photos. This is best method I've come up with so far to view the motion photos from phone/web.
rsync — stats -avz -e “ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null” — remove-source-files — progress /home/pi/motion-capture/ host@address:/path/to/motionrsync — stats -avz -e “ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null” — remove-source-files — progress /home/pi/motion-capture/ host@address:/path/to/motionThis post contains some good info on running Motion on a pi http://www.richardmudhar.com/blog/2015/02/raspberry-pi-camera-and-motion-out-of-the-box-sparrowcam/
Go Drive
I was using Google Photos since it is an excellent UI for viewing/editing but it is not supported on Linux and requires a separate, non-Linux machine for upload. The next best thing would be Google Drive but even that is not available on Linux (application). I found a Go command line drive app https://github.com/odeke-em/drive
First I need to install Go
wget https://storage.googleapis.com/golang/go1.7.linux-armv6l.tar.gz
sudo tar -C /usr/local -xzfv go1.7.linux-armv6l.tar.gz
export PATH=$PATH:/usr/local/go/binwget https://storage.googleapis.com/golang/go1.7.linux-armv6l.tar.gz
sudo tar -C /usr/local -xzfv go1.7.linux-armv6l.tar.gz
export PATH=$PATH:/usr/local/go/binApparently I need Git for go-get
Setup go environment. Add to .profile
export GOPATH=$HOME/go
export GOBIN=$GOPATH/bin
export PATH=$PATH:$GOBIN:/usr/local/go/binexport GOPATH=$HOME/go
export GOBIN=$GOPATH/bin
export PATH=$PATH:$GOBIN:/usr/local/go/binThen install drive
go get -u github.com/odeke-em/drive/cmd/drivego get -u github.com/odeke-em/drive/cmd/driveI want to backup some files and the motion photos however noticing some weird behavior. It seems that the drive push command only works if running the command from where the file exists. But if the command specifies a file in another directory:
open /home/piuser/.gd/credentials.json: no such file or directoryopen /home/piuser/.gd/credentials.json: no such file or directoryNot sure why this was removed but drive init resolves.
I created a local Google\ Photos folder and pushed to it with the idea these would appear in the Google Photos app. The local file gets synced but does not show up in Google Photos. It does appear under the Google Photos in My Drive, e.g
drive push -verbose -destination Google\ Photos ss.png
So looks like Google Photos under My Drive is only a read-only view of Google Photos, not the source location.
I can now push files to my Google Drive with
drive push -no-clobber -no-prompt -ignore-name-clashes -verbose -destination raspberry-pi-zero ~/motion-filesdrive push -no-clobber -no-prompt -ignore-name-clashes -verbose -destination raspberry-pi-zero ~/motion-fileswhere "raspberry-pi-zero" is a root level folder in my Drive and I'm pushing ~/motion-files to it. Unfortunately this has O(n) performance. At first the uploads were fast but now getting slower (minutes) with a few thousand files in the folder. I've disabled sync (files not on pi that exist on remote should not be deleted from remote) so it should just be uploading new files and that should be fast but is not the case. If I can't get this app to scale then I'll probably build something with the Google Drive API, however I'd hoped to avoid that. To upload only when new files appear I'm using ls and wc
ls -l ~/motion-files | wc -lls -l ~/motion-files | wc -land comparing to the count from the previous run to detect changes.
There is also a hook available with Motion that will run an arbitrary command at the end of a motion event, which might be a better option
# Command to be executed when an event ends after a period of no motion
# (default: none). The period of no motion is defined by option event_gap.
;# Command to be executed when an event ends after a period of no motion
# (default: none). The period of no motion is defined by option event_gap.
;Serial Ports
The pi zero w has two serial ports, one of which is connected to bluetooth and the other defaults is designated as a linux console login. They can be repurposed to serve as a serial port on the GPIO pins 14/15 however you'll lose either Bluetooth or linux console. This is described in detail in the Pi docs https://www.raspberrypi.org/documentation/configuration/uart.md Currently I don't have a need for a serial port, however if I did my initial thought is I'd forgo the linux console since I definitely want Bluetooth. The downside is if the pi is unreachable via ssh and needs troubleshooting, you don't have a console and maybe you could use Bluetooth but failing that you'd need to pull the sd card, mount on another host and modify the boot config to enable the uart for the console and boot.
Java
Java can be installed with
sudo apt-get install oracle-java8-jdksudo apt-get install oracle-java8-jdkBackup
After getting everything setup and configured the Pi failed to start SSH at some point and was unreachable. I didn't have the gpio header soldered on yet, so with no way to get to the console I decided to wipe the SD card and start over. Would have been nice to have a backup and avoid this extra work. The smart thing to do would be to learn Ansible or a similar tool to automate the setup but who has time for that!
I haven't found any easy/seamless backup solution for the Pi, something similar to time machine for mac. Some have had success with Dropbox and Dropbox Uploader https://github.com/andreafabrizi/Dropbox-Uploader Another approach is to backup the entire SD card image, however this can result in a corrupted image if the OS is writing to files during the copy. A SD card backup will also be the size of the sd card, regardless of how much storage is used. It does have the benefit of an easy restore if the sd card fails — simply copy the image to a new sd card, plug in and boot.
As a stop-gap, I'm syncing my scripts and configuration to google drive via the drive (Go) command-line app.
Misc
Configure timezone and locale in raspi-config
Change the pi user password. Also you may want to create personal user. I created a new user and only allow that user for ssh. Then advantage to this approach is now an attacker would need to guess your username and password. With the default pi username then only need to guess the password
How To Add, Delete, and Grant Sudo Privileges to Users on a Debian VPS | DigitalOcean Adding and deleting users are basic tasks that you will have to preform on most servers. Granting sudo privileges to…
You may also want sudo access for this user, like the pi user
sudo adduser newuser
How To Create a Sudo User on Ubuntu [Quickstart] | DigitalOcean The sudo command provides a mechanism for granting administrator privileges, ordinarily only available to the root…
Verify you can ssh with the new user
Then change the ssh config to not allow ssh for the the pi user, e.g
sudo vi /etc/ssh/sshd_config
add
AllowUsers newusername
sudo service ssh restart
Now only newusername can login via ssh. If you ever forwarded port 22 (ssh) to your pi box from your router and had a default pi account or other system user with common password, you can bet your pi will get hacked and it won't take long.
Passwords are annoying to type all the time so you may want to setup place your ssh key from your notebook or where ever you connect from on your pi
Create keys on the connecting-from computer, if necessary. And install on the pi. Then, you should not get prompted for a password when ssh'ing
How To Set Up SSH Keys | DigitalOcean SSH keys provide a more secure way of logging into a virtual private server with SSH than using a password alone. With…
What Else/TODO?
Configure a static ip address
Note: apple-option-6 (medium code format)