Orange Pi Zero and webcam for Octoprint
In a previous blog entry, I explained (in French) that I added Octoprint to my Dagoma DiscoEasy200 thanks to an Orange Pi Zero.
The best guide I found is the one from deloarts.
Remark: when I wrote this article, I discovered that new editions of the Orange Pi Zero exists (Plus / Plus2 H3, H5...). I'm using the basic Orange Pi Zero with 512Mo RAM
Webcam module
I recently dismantled an old Android 2.2 notebook before throwing it away (based on the Wondermedia WM8650). I found a little module with a camera on it, and I asked myself if it could be reused.
The chip on the module is an Etron eSP268.
And 4 wires are connected to the module (red / black / blue / white).
It seems that the module is just connected through an USB interface !
I gave it a shot :
- Red: 5V
- Black: GND
- White: Data positive
- Blue: Data negative
And it works! No driver to install to get it work with Windows 10.
The webcam is an UVC compatible device, which is a good news as it supported by Linux.
Connect the webcam to the Orange Pi Zero
Hardware
As the only USB port socket on the Orange PI Zero is used by the 3D printer, I looked at the Orange PI Zero pinout:
We can see that 2 USB port pins are available (USB-Dx2 / USB-Dx3).
I chose to use the USB-DM2 / USB-DP2 as they are close to 5V and GND pins.
I removed the micro USB breakout board and put some pin headers:
Software
I'm using the following OS:
ARMBIAN 5.38 stable Ubuntu 16.04.4 LTS 4.14.18-sunxi
I found some useful informations on the Sunxi website.
Once that the OS booted, I tried to see if the webcam was recognized:
root@octoprint:/dev# ls -ltrh /dev/video*
ls: cannot access '/dev/video*': No such file or directory
So I checked the USB devices:
root@octoprint:/dev# lsusb
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 002: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
To discover the webcam informations, I had to install hwinfo
root@octoprint:/dev# apt get install hwinfo
root@octoprint:/dev# hwinfo --usb
13: USB 00.1: 0000 Unclassified device
[Created at usb.122]
Unique ID: sjcF.B8XmjCc9XQ2
Parent ID: zPk0.J9mAFna3wT7
SysFS ID: /devices/platform/soc/1c1c000.usb/usb4/4-1/4-1:1.1
SysFS BusID: 4-1:1.1
Hardware Class: unknown
Model: "Cubeternet WebCam"
Hotplug: USB
Vendor: usb 0x1e4e "Cubeternet"
Device: usb 0x0100 "WebCam"
Revision: "12.18"
Driver: "uvcvideo"
Driver Modules: "uvcvideo"
Speed: 480 Mbps
Module Alias: "usb:v1E4Ep0100d1218dcEFdsc02dp01ic0Eisc02ip00in01"
Config Status: cfg=new, avail=yes, need=no, active=unknown
Attached to: #16 (Hub)
I checked on the UVC Linux driver website, and it should be supported:
1e4e:0100 / USB 2.0 Camera / Etron Technologies
After looking around on the web to get it working, I understood that I just had to enable the kernel module:
root@octoprint:/dev# modprobe uvcvideo
root@octoprint:/dev# ls -ltrh /dev/video*
crw-rw---- 1 root video 81, 0 May 12 19:17 /dev/video0
root@octoprint:/dev# lsusb
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 002: ID 1e4e:0100 Cubeternet WebCam
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 002: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Installed and used some tools to see the capacity of the webcam.
root@octoprint:/# apt install v4l-utils
root@octoprint:/# v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'YUYV'
Name : YUYV 4:2:2
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 352x288
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 320x240
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 176x144
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 160x120
Interval: Discrete 0.033s (30.000 fps)
So the webcam can be used at 30 fps with the 640x480 resolution. Enough for a free module.
Use the webcam with Octoprint
To be able to use the webcam with Octoprint, the webcam stream must be exposed over HTTP.
To do that, Octoprint website advise to use mjpg-streamer.
Webcam stream with "mjpg-streamer"
octoprint@octoprint:/home/octoprint$ apt-get install cmake libjpeg8-dev
octoprint@octoprint:/home/octoprint$ git clone https://github.com/jacksonliam/mjpg-streamer.git
octoprint@octoprint:/home/octoprint/mjpg-streamer/mjpg-streamer-experimental$ make
Please note that I installed the tool (make install
) but I think that it's not mandatory.
root@octoprint:/home/octoprint/mjpg-streamer/mjpg-streamer-experimental# make install
Now, it's time to test the stream:
root@octoprint:/# mjpg_streamer -i "input_uvc.so -r 640x480 -f 30" -o "output_http.so"
MJPG Streamer Version: git rev: 821c330ea6bbb5fbed98d48e00aac156e923161b
i: Using V4L2 device.: /dev/video0
i: Desired Resolution: 640 x 480
i: Frames Per Second.: 30
i: Format............: JPEG
i: TV-Norm...........: DEFAULT
i: Could not obtain the requested pixelformat: MJPG , driver gave us: YUYV
... will try to handle this by checking against supported formats.
... Falling back to YUV mode (consider using -yuv option). Note that this requires much more CPU power
UVCIOC_CTRL_ADD - Error at Pan (relative): Inappropriate ioctl for device (25)
UVCIOC_CTRL_ADD - Error at Tilt (relative): Inappropriate ioctl for device (25)
UVCIOC_CTRL_ADD - Error at Pan Reset: Inappropriate ioctl for device (25)
UVCIOC_CTRL_ADD - Error at Tilt Reset: Inappropriate ioctl for device (25)
UVCIOC_CTRL_ADD - Error at Pan/tilt Reset: Inappropriate ioctl for device (25)
UVCIOC_CTRL_ADD - Error at Focus (absolute): Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Pan (relative): Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Tilt (relative): Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Pan Reset: Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Tilt Reset: Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Pan/tilt Reset: Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Focus (absolute): Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at LED1 Mode: Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at LED1 Frequency: Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Disable video processing: Inappropriate ioctl for device (25)
UVCIOC_CTRL_MAP - Error at Raw bits per pixel: Inappropriate ioctl for device (25)
o: www-folder-path......: disabled
o: HTTP TCP port........: 8080
o: HTTP Listen Address..: (null)
o: username:password....: disabled
o: commands.............: enabled
Sadly, this webcam cannot output MJPG, which force the streamer to transcode the stream, and use a lot of CPU power (30% of the CPU of my Orange PI).
The stream is now available!
http://192.168.0.100:8080/?action=stream
(of course, you have to change the IP of my device by yours...)
Before configuring Octoprint, I had to install ffmpeg:
root@octoprint:/# apt-get install ffmpeg
Scripts to be able to start / stop the webcam
As the streamer uses a lot of CPU, I want to be able to start it / stop it directly from Octoprint.
I adapted the scripts that are available on GitHub for my configuration.
webcam.sh
octoprint@octoprint:~$ mkdir scripts
octoprint@octoprint:~$ cd scripts/
octoprint@octoprint:~/scripts$ vim webcam.sh
#!/bin/bash
# Start / stop streamer daemon
case "$1" in
start)
/home/octoprint/scripts/webcamDaemon.sh >/dev/null 2>&1 &
echo "$0: started"
;;
stop)
pkill -x webcamDaemon
pkill -x mjpg_streamer
echo "$0: stopped"
;;
*)
echo "Usage: $0 {start|stop}" >&2
;;
esac
octoprint@octoprint:~/scripts$ chmod a+x webcam.sh
webcamDaemon.sh
octoprint@octoprint:~/scripts$ vim webcamDaemon.sh
#!/bin/bash
MJPGSTREAMER_HOME=/home/octoprint/mjpg-streamer/mjpg-streamer-experimental
MJPGSTREAMER_INPUT_USB="input_uvc.so"
# init configuration
camera="auto"
camera_usb_options="-r 640x480 -f 30"
if [ -e "/boot/octopi.txt" ]; then
source "/boot/octopi.txt"
fi
# runs MJPG Streamer, using the provided input plugin + configuration
function runMjpgStreamer {
input=$1
pushd $MJPGSTREAMER_HOME
echo Running ./mjpg_streamer -o "output_http.so -w ./www" -i "$input"
LD_LIBRARY_PATH=. ./mjpg_streamer -o "output_http.so -w ./www" -i "$input"
popd
}
# starts up the USB webcam
function startUsb {
logger "Starting USB webcam"
runMjpgStreamer "$MJPGSTREAMER_INPUT_USB $camera_usb_options"
}
# echo configuration
echo camera: $camera
echo usb options: $camera_usb_options
# keep mjpg streamer running if some camera is attached
while true; do
if [ -e "/dev/video0" ] && { [ "$camera" = "auto" ] || [ "$camera" = "usb" ] ; }; then
startUsb
elif [ "`vcgencmd get_camera`" = "supported=1 detected=1" ] && { [ "$camera" = "auto" ] || [ "$camera" = "raspi" ] ; }; then
logger "Not supported"
fi
sleep 120
done
octoprint@octoprint:~/scripts$ chmod a+x webcamDaemon.sh
Edit Octoprint configuration
octoprint@octoprint:~/scripts$ vim ~/.octoprint/config.yaml
I had to add the system
section:
system:
actions:
- action: streamon
command: /home/octoprint/scripts/webcam.sh start
confirm: false
name: Start video stream
- action: streamoff
command: /home/octoprint/scripts/webcam.sh stop
confirm: false
name: Stop video stream
Octoprint user rights
Currently the octoprint
user doesn't have the right to use the video devices. When I ran the script with this user, I got an error:
octoprint@octoprint:~/scripts$ ./webcamDaemon.sh
camera: auto
usb options: -r 640x480 -f 30
~/mjpg-streamer/mjpg-streamer-experimental ~/scripts
Running ./mjpg_streamer -o output_http.so -w ./www -i input_uvc.so -r 640x480 -f 30
MJPG Streamer Version: git rev: 821c330ea6bbb5fbed98d48e00aac156e923161b
i: Using V4L2 device.: /dev/video0
i: Desired Resolution: 640 x 480
i: Frames Per Second.: 30
i: Format............: JPEG
i: TV-Norm...........: DEFAULT
ERROR opening V4L interface: Permission denied
Init v4L2 failed !! exit fatal
i: init_VideoIn failed
~/scripts
ls -l /dev/video0
So I add the user to the video
group:
root@octoprint:/home/octoprint# vim /etc/group
By editing this line:
video:x:44:jmd,octoprint
Then, I restarted Octoprint:
octoprint@octoprint:~/scripts$ sudo service octoprint restart
Octoprint configuration
It's now time to changes the setting of Octoprint:
Don't forget to flush the cache of your browser to see the changes in Octoprint.
Now, in the "Control" tab, an area can display the webcam stream. To enable the stream, one new item is also available in the toolbar.
And...
I now have to find the best way to fix the webcam.
The quality is not good, but it is enough to check the printer status remotely.
If you want to open your octoprint on Internet, there is few steps left. But personally, for security reasons, I only check my octoprint through a VPN connection to my home network.