Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save d-schmidt/35e5bf422ed80c0c2826a93c5ec4c4df to your computer and use it in GitHub Desktop.
Save d-schmidt/35e5bf422ed80c0c2826a93c5ec4c4df to your computer and use it in GitHub Desktop.
Directions for setting up a RaspberryPi 4 to act as a generic USB webcam

hardware/software

Webcam parts:

  • Raspberry Pi 4
  • Raspberry Pi High Quality Camera (12.3-megapixel)
  • Raspbian Buster Lite 2021-01-11

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 -y
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 peterbay / uvc-gadget repo

git clone https://github.com/peterbay/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 Feb  7 12:00 fe980000.usb -> ../../devices/platform/soc/fe980000.usb/udc/fe980000.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

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
CONFIGFS: Initial path: /sys/kernel/config/usb_gadget
CONFIGFS: UVC: format: 1, frame: 1, resolution: 1280x720, frame_interval: 666666,  bitrate: [29491200, 29491200]
CONFIGFS: STREAMING maxburst:  0
CONFIGFS: STREAMING maxpacket: 1024
CONFIGFS: STREAMING interval:  1
SETTINGS: Number of buffers requested: 2
SETTINGS: Show FPS: DISABLED
SETTINGS: GPIO pin for streaming status: not set
SETTINGS: Onboard led0 used for streaming status: DISABLED
SETTINGS: Blink on startup: 0 times
SETTINGS: UVC device name: /dev/video1
SETTINGS: V4L2 device name: /dev/video0
DEVICE_UVC: Opening /dev/video1 device
DEVICE_UVC: Device is fe980000.usb on bus gadget
DEVICE_V4L2: Opening /dev/video0 device
DEVICE_V4L2: Device is mmal service 16.1 on bus platform:bcm2835-v4l2-0
DEVICE_V4L2: Getting highest frame size: YUYV 4056x3040
DEVICE_V4L2: Getting highest frame size: MJPG 4056x3040
...

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:

...

open the "Camera" app on Windows

on the RaspberryPi you should see logs like:

UVC: Streaming request CS: PROBE, REQ: GET_CUR
UVC: Streaming request CS: PROBE, REQ: SET_CUR
UVC: Control PROBE, length: 26
UVC: Streaming control: action: SET, format: 1, frame: 1
FRAME: format: 1, frame: 1, resolution: 1280x720, frame_interval: 666666,  bitrate: [29491200, 29491200]
DUMP: uvc_streaming_control: format: 1, frame: 1, frame interval: 666666
...
DEVICE_V4L2: Setting format to: MJPG 1280x720
DEVICE_V4L2: Getting current format: MJPG 1280x720
DEVICE_UVC: Setting format to: MJPG 1280x720
DEVICE_UVC: Getting current format: MJPG 1280x720
DEVICE_V4L2: Buffer 0 mapped at address 0xb6cd3000, length 921600.
DEVICE_V4L2: Buffer 1 mapped at address 0xb6bf2000, length 921600.
DEVICE_V4L2: 2 buffers allocated.
DEVICE_V4L2: STREAM ON success
DEVICE_UVC: 2 buffers allocated.
DEVICE_UVC: STREAM ON success

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