BeagleBone as a Webcam

Note: I have not really gotten this to work yet and am currently asking StackOverflow. No matter what webcam I use (I tried three: Logitech C920, HP 3100, and a non-descript el-cheapo SD webcam), the BeagleBone Black freezes after a few (el-cheapo) or after a few dozen (the brand-name cams) acquisitions. I don't know what error causes it, but I occasionally see the following errors in dmesg, before it actually freezes completely:

dmesg | tail -n 3
-> [ 220.258214] musb_host_rx 1762: Rx interrupt with no errors or packet!
-> [ 490.302277] musb_ep_program 896: broken !rx_reinit, ep13 csr 0003
-> [ 490.308731] musb_host_rx 1762: Rx interrupt with no errors or packet!

Generally, it is recommended to switch the BeagleBone to a beefier power supply in these situations, but that did not help for me (I tried four powersupplies; two USB and two via barrel connector). I also tried two different distributions (Ubuntu + official Debian, where I also updated to the latest Kernel), and three different BeagleBones (two Rev. A5A and one A5C). I suspect an error on the hardware side of the BeagleBone - there have always been problems with USB support.

Update: Using the RevA5C BeagleBone does seem to work, at least in some of the configuration. dmseg still reports the same errors, and 1 in 4 images are bad (black), but at least the BeagleBone does not crash so often anymore. This is still an unsatisfactory result.

The setup:

Install fswebcam

sudo apt-get install fswebcam

Add yourself to the video group (your name is Bob, of course)

sudo adduser bob video

Log out and back in for the change to take effect.

Attach webcam via USB and make sure that the BeagleBone sees it:

lsusb
 -> Bus 002 Device 002: ID 056e:032a Logitech, Inc. HD Pro Webcam C920

Take a test picture. If the picture is bad, try a delay of one second so that the camera has time to set itself up. You may also try to skip a few frames (option -S).

fswebcam test-pic.png
fswebcam -D 1 test-pic.png

Make a config file for fswebcam - otherwise the commands can get quite long.

makedir ~/webcam
nano ~/webcam/fswebcam.conf

Add the following lines to it (or something similar):

background
loop 10
resolution 1920x1080
scale 1280x720
title "Fishcam"
timestamp "%d.%m.%Y %H:%M:%S (%Z)"
jpeg 70
banner-colour #FF000000
line-colour #FF000000
no-shadow
save /tmp/aquarium.jpg

This makes fswebcam run in the background, take a picture every 10 seconds at a high resolution, but downscales it before saving it as jpg. It adds a title and a timestamp to the picture.

Call fswebcam with path to config file

fswebcam -c ~/webcam/fswebcam.conf

End it using pkill.

pkill fswebcam

The beaglebone uses flash storage as its "hard drive", and its best not to write to it too often. So in order to not write a new image to disk every ten seconds, we will create a small RAM-disk. This is a "virtual hard drive" that stays inside RAM at all times. We'll put the command to create this disk into fstab, so that it is created during each boot.

sudo nano /etc/fstab

Append the following line to create a 10 Megabyte RAM-disk and mount it on folder /tmp:

tmpfs /tmp tmpfs defaults,noatime,nosuid,nodev,noexec,mode=1777,size=10M 0 0

Make sure that the mount point /tmp exists, if not create it:

sudo mkdir /tmp

Reboot so that your system can create the RAM-disk. (You can also do it from command line using mount -t tmpfs -o size=2048M tmpfs /tmp/).

In order to make the pictures available on the web, install apache webserver (link to article goes here) and add a symbolic link to the file that fswebcam will save:

sudo ln -s /tmp/aquarium.jpg /var/www/html/aquarium.jpg

Start fswebcam and enter the IP adress of your Beaglebone into the adressbar of your browser (on a PC that is in the same local network, of course). For me that is at

http://192.168.0.123/aquarium.jpg

You can either update manuall every 10 seconds or write a small script that makes the browser refresh every 10 seconds:

sudo nano /var/www/html/fishcam.html

Enter the following file contents:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>FishCam</title>
    <meta name="description" content="">
  </head>
  <body>
    <img src="aquarium.jpg" id="aquarium" />
    <div id="message">Image is updated every 10 seconds.</div>
    <div id="last-update"></div>
    <noscript>Enable JavaScript for automatic updates.</noscript>
    <script>
      var myVar = setInterval(function(){reloadImage()}, 10000);
      function reloadImage() {
        var aquariumElement = document.getElementById('aquarium');
        aquariumElement.src = 'aquarium.jpg?rand=' + Math.random();
        var d = new Date();
        var t = d.toLocaleTimeString();
        document.getElementById("last-update").innerHTML = t;
      }
    </script>
  </body>
</html>

Now, in the browser, go to /fishcam.html and bask in the glory of your new webcam. All that is left is to make the BeagleBone accessible from the internet (forward port 80 on your router).