Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save rafaelcaricio/3dcacedad5b416ba3c522c70064a0570 to your computer and use it in GitHub Desktop.
Save rafaelcaricio/3dcacedad5b416ba3c522c70064a0570 to your computer and use it in GitHub Desktop.
Directions for setting up a RaspberryPi to act as a generic USB webcam

hardware/software

Webcam parts:

  • Raspberry Pi Zero W Rev 1.1
  • Raspberry Pi Camera v2 (8-megapixel)
  • Raspberry Pi High Quality Camera (12.3-megapixel)
  • Raspbian Buster Lite 2020-02-13

Webcam works with:

  • Windows 10
  • Windows 10 "Camera" app
  • Google Hangouts via Chrome
  • Zoom

setup

  • start with a fresh install of Raspbian Buster Lite 2020-02-13.
  • enable ssh access & connect to network.
  • connect the camera to the Raspberry Pi.

run updates, install git

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install git -y

enable the camera

sudo raspi-config

Interfacing Options > P1 Camera > Enable

set dwc2 as dtoverlay

Add

dtoverlay=dwc2

to the bottom of /boot/config.txt

(sudo vi /boot/config.txt then add dtoverlay=dwc2 to the end.)

load dwc2 and libcomposite at boot

Add

modules-load=dwc2,libcomposite

after the rootwait in /boot/cmdline.txt

(sudo vi /boot/cmdline.txt then add modules-load=dwc2,libcomposite at the end.)

create the ConfigFS uvc.sh script

vi uvc.sh

then add the following from g.letourneur on raspberrypi.org

#!/bin/bash
mkdir /sys/kernel/config/usb_gadget/pi4

echo 0x1d6b > /sys/kernel/config/usb_gadget/pi4/idVendor
echo 0x0104 > /sys/kernel/config/usb_gadget/pi4/idProduct
echo 0x0100 > /sys/kernel/config/usb_gadget/pi4/bcdDevice
echo 0x0200 > /sys/kernel/config/usb_gadget/pi4/bcdUSB

echo 0xEF > /sys/kernel/config/usb_gadget/pi4/bDeviceClass
echo 0x02 > /sys/kernel/config/usb_gadget/pi4/bDeviceSubClass
echo 0x01 > /sys/kernel/config/usb_gadget/pi4/bDeviceProtocol

mkdir /sys/kernel/config/usb_gadget/pi4/strings/0x409
echo 100000000d2386db > /sys/kernel/config/usb_gadget/pi4/strings/0x409/serialnumber
echo "Samsung" > /sys/kernel/config/usb_gadget/pi4/strings/0x409/manufacturer
echo "PI4 USB Device" > /sys/kernel/config/usb_gadget/pi4/strings/0x409/product
mkdir /sys/kernel/config/usb_gadget/pi4/configs/c.1
mkdir /sys/kernel/config/usb_gadget/pi4/configs/c.1/strings/0x409
echo 500 > /sys/kernel/config/usb_gadget/pi4/configs/c.1/MaxPower
echo "UVC" > /sys/kernel/config/usb_gadget/pi4/configs/c.1/strings/0x409/configuration

mkdir /sys/kernel/config/usb_gadget/pi4/functions/uvc.usb0
mkdir -p /sys/kernel/config/usb_gadget/pi4/functions/uvc.usb0/control/header/h
ln -s /sys/kernel/config/usb_gadget/pi4/functions/uvc.usb0/control/header/h /sys/kernel/config/usb_gadget/pi4/functions/uvc.usb0/control/class/fs
mkdir -p /sys/kernel/config/usb_gadget/pi4/functions/uvc.usb0/streaming/mjpeg/m/720p
cat <<EOF > /sys/kernel/config/usb_gadget/pi4/functions/uvc.usb0/streaming/mjpeg/m/720p/dwFrameInterval
5000000
EOF
cat <<EOF > /sys/kernel/config/usb_gadget/pi4/functions/uvc.usb0/streaming/mjpeg/m/720p/wWidth
1280
EOF
cat <<EOF > /sys/kernel/config/usb_gadget/pi4/functions/uvc.usb0/streaming/mjpeg/m/720p/wHeight
720
EOF
cat <<EOF > /sys/kernel/config/usb_gadget/pi4/functions/uvc.usb0/streaming/mjpeg/m/720p/dwMinBitRate
29491200
EOF
cat <<EOF > /sys/kernel/config/usb_gadget/pi4/functions/uvc.usb0/streaming/mjpeg/m/720p/dwMaxBitRate
29491200
EOF
cat <<EOF > /sys/kernel/config/usb_gadget/pi4/functions/uvc.usb0/streaming/mjpeg/m/720p/dwMaxVideoFrameBufferSize
1843200
EOF
mkdir /sys/kernel/config/usb_gadget/pi4/functions/uvc.usb0/streaming/header/h
cd /sys/kernel/config/usb_gadget/pi4/functions/uvc.usb0/streaming/header/h
ln -s ../../mjpeg/m
cd ../../class/fs
ln -s ../../header/h
cd ../../class/hs
ln -s ../../header/h
cd ../../../../..

ln -s /sys/kernel/config/usb_gadget/pi4/functions/uvc.usb0 /sys/kernel/config/usb_gadget/pi4/configs/c.1/uvc.usb0
udevadm settle -t 5 || :
ls /sys/class/udc > /sys/kernel/config/usb_gadget/pi4/UDC

make the new script executable

chmod +x uvc.sh

setup uvc-gadget

clone whle's uvc-gadget repo

git clone https://github.com/wlhe/uvc-gadget.git

build it

cd uvc-gadget && make

setup complete, reboot

sudo reboot 0

debugging

see video steams (cameras)

ls -ls /dev

should have video0 if your Raspberry Pi Camera is hooked up and enabled.

see if you have a device controler

ls -la /sys/class/udc

should have:

lrwxrwxrwx  1 root root 0 May 11 22:21 20980000.usb -> ../../devices/platform/soc/20980000.usb/udc/20980000.usb

pre-check usb_gadget

ls -la /sys/kernel/config/usb_gadget

should exist.

usage

Start with your Pi just hooked up to power, not connected to another computer.

check camera connections

note which is the physical camera connected

ls /dev/video*

will probably be video0

setup ConfigFS

sudo ./uvc.sh

if it returns with no errors, it worked.

check for new video output

note which one is new from running the uvc.sh script

ls /dev/video*

will probably be video1.

start the uvc-gadget webcam

if your camera is video0 and your UVC gadget is video1:

~/uvc-gadget/uvc-gadget -v /dev/video0 -u /dev/video1 -r 1 -f 1

note the options on the repo, this will output 1280x720 MJPEG

You should have output like this:

pi@campi:~ $ ~/uvc-gadget/uvc-gadget -v /dev/video0 -u /dev/video1 -r 1 -f 1
V4L2 device is mmal service 16.1 on bus platform:bcm2835-v4l2
V4L2: Getting current format: JPEG 1024x768
V4L2: Setting format to: MJPG 1280x720
V4L2: Getting current format: MJPG 1280x720
v4l2 open succeeded, file descriptor = 3
uvc device is 20980000.usb on bus gadget
uvc open succeeded, file descriptor = 4
V4L2: Buffer 0 mapped at address 0xb6cf4000.
V4L2: Buffer 1 mapped at address 0xb6c13000.
V4L2: 2 buffers allocated.

plug the RaspberryPi into a Windows10 computer, as a webcam

connect Raspberry Pi's Micro USB to a USB-A port of a Windows 10 host

you should see a bunch of logs on the rPi when you connect the cable, like:

control request (req 86 cs 04)
control request (req 81 cs 02)
control request (req 86 cs 09)
control request (req 81 cs 02)
control request (req 86 cs 02)

open the "Camera" app on Windows

on the RaspberryPi you should see logs like:

streaming request (req 81 cs 01)
streaming request (req 01 cs 01)
setting probe control, length = 26
streaming request (req 81 cs 01)
streaming request (req 83 cs 01)
streaming request (req 82 cs 01)
streaming request (req 01 cs 01)
setting probe control, length = 26
streaming request (req 81 cs 01)
streaming request (req 01 cs 02)
setting commit control, length = 26
UVC: 2 buffers allocated.
V4L2: Starting video stream.
UVC: Starting video stream.
control request (req 81 cs 02)
control request (req 81 cs 02)
control request (req 81 cs 02)
control request (req 01 cs 02)
setting unknown control, length = 2
V4L2: Brightness control changed to value = 0x7f
Control Request data phase (cs 02 entity 02)
control request (req 81 cs 02)
control request (req 81 cs 02)

stop streaming by pressing ctrl+c on the Pi

Rerunning the script should work fine. You can unplug the Pi and move it to a different computer, etc.

troubleshooting

all white or all black video output

try setting the brightness to something like 65, as it may default to 0 leaving you with an all-black image.

souces

Used these resouces to get this working

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment