Thursday 2 August 2012

Raspberry Pi with two webcams

Provided they are plugged directly into the Raspberry Pi's two USB ports directly, I've been able to connect it to two web-cameras at once, and stream the pictures using the open source Motion software (which also records images for any movement). Watching a double webcam feed from Safari on my iPad, while controlling the Raspberry Pi using Panic Inc's SSH application Prompt was kind of fun!

As you might guess from past blog posts, I was trying (several) Microsoft Live Vision USB webcams, with the aim of using them via the RPi and a long ethernet cable to monitor my bird nesting box cameras. My plan (outlined back on this post) is to use power-over-ethernet (POE) to supply 5V to the Raspberry Pi, which will be down the garden within USB range of the birdbox or birdboxes. But first, to get this working indoors - which meant initially a long wait before my RPi was delivered.

Meanwhile, other people were also experimenting with using the RPi as an IP-webcam, like Jeremy who tried both ffserver on his RPi and then later switched to using Motion on a battery powered RPi webcam with wifi and more. Nice blog!

Motion under Raspbian

I decided to try the recently released Raspbian-based SD card image, specifically the 2012-07-15-wheezy-raspbian.zip release. During the first boot I used the menu to expand the file system to take the whole SD card, enabled SSH access, and set my keyboard and locale, and opted not to boot to the graphical desktop. I then ran an update, and installed Motion, the Apache webserver, Emacs, etc.

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install motion
$ sudo apt-get install apache2
$ sudo apt-get install emacs

Initial experiments with an un-powered and a powered USB hub were not fruitful - the second webcam wouldn't register - in fact in some configurations even low power devices like my mouse or keyboard wouldn't work. So rather than trying this with a USB keyboard and mouse, I switched to SSH access and used the only two USB ports for two webcams - which worked.

$ ls /dev/vid*
/dev/video0  /dev/video1

I've already been running motion for a while now on an old laptop, so the configuration wasn't too hard - I knew that on my laptop getting several USB cameras running at once meant sticking with the default low resolution of 320x240 pixels. I went with two camera configuration files as ~/webcam/cam1.conf which is just:

videodevice /dev/video0
webcam_port 8081

And likewise for the second camera, configuration file ~/webcam/cam2.conf is just:

videodevice /dev/video1
webcam_port 8082

These are very short because everything else is in /etc/motion/motion.conf, the main configuration file, most of which remains with the default values. The main change is two thread settings pointing at the above per-camera settings:

webcam_localhost off
thread /home/pi/webcam/cam1.conf
thread /home/pi/webcam/cam2.conf

The only other configuration change so far is for making this act like an IP-webcam was to change the default (secure) setting restricting this to the same machine (local host). Note you must also ensure the two camera streams are on different ports (I went for the motion default of 8081, and 8082 for the second camera).

I then setup a minimal webpage by creating the file /var/www/webcam.html showing the two images side by side (which would be served by Apache). Initially I've just hard coded the RPi's hostname to access the two webcams, but I think a little Apache magic is a better solution considering my IP address is allocated by DHCP and will change, but this works for now.

Update: As requested in the comments, here's the simple HTML for the page I access as http://raspberrypi/webcam.html from within my home network (this should be edited if you change the default hostname of raspberrypi):

$ more /var/www/webcam.html
<html>
<head>
<title>Raspberry Pi Webcameras</title>
</head>
<body>
<h1>Raspberry Pi Webcameras</h1>
<a href="http://raspberrypi:8081/">

<img src="http://raspberrypi:8081/" alt="Camera 1" ></a>
<a href="http://raspberrypi:8082/">

<img src="http://raspberrypi:8082/" alt="Camera 2" ></a>
</body>
</html>


Update: If you want motion to auto-start when the computer is rebooted, you need to edit the file /etc/default/motion to say start_motion_daemon=yes and this will happen automatically via the /etc/init.d/motion startup script. I'm using this now that I have installed a Raspberry Pi in my garden. Note I added $all to the Required-Start list to hopefully ensure that the USB system, ethernet, and date-time (via the network) are live before starting Motion.

Data Sync

It would be nice if DropBox could run on the Raspberry Pi - but right now it doesn't. You can go here to vote for DropBox to support Linux on the ARM processor. That rules out one way to automatically collect movement triggered images from the RPi - but there are several other options here, perhaps rsync to a separate image server?

Update - More USB devices?

As I noted in the introduction, I could only get two USB webcams to work when directly connected - and thus had to log into the RPi by SSH to control it. Even trying two cameras and a keyboard via a powered or unpowered hub proved problematic.

Using a powered hub is the recommended solution, so perhaps my hub just wasn't up to the job? However, I've been reading about an alternative hack to bypass the RPi's F1 and F2 polyfuses as described on The IO BlogHimesh's blog, and elsewhere including this forum thread USB Port Current Boost. You would of course still need to use a sufficiently strong power supply.

29 comments:

  1. I use Google Drive from my Raspberry Pi with motion. I wrote a guide and some code a few weeks ago here: http://jeremyblythe.blogspot.com/2012/06/motion-google-drive-uploader-and.html

    ReplyDelete
  2. Just wondering, how many fps are you getting for the video feed? I'm having a hard time getting anything above 15fps.

    ReplyDelete
    Replies
    1. Hi Manis. How are you measuring the frame rate?

      The observed refresh rate in an external browser via motion over my wifi network is quite sluggish, with lags often measured in seconds. However, I was really only using this for testing the basic functionality - I intend to run motion with the webserver disabled, and capture motion-triggered images instead. I have not yet measured the frame rate in this mode.

      Delete
  3. Hi
    I've just bought some Xbox Live Vision webcams to tinker with (£3.50 each new delivered, Ebay) and use with my RPis. I was inspired by your birdbox cams, and thought I'd try setting one up for the kids to watch.
    Thanks to your guide I had the IR filter out within a few minutes, and got the camera running under Motion (I've already used motion with another camera on the RPi) so it was fairly quick.

    However I can only get the Xbox cam to run at 320x240 resolution, whereas my Logitech runs happily at 640x480.
    Have you been able to run yours at 640x480 ?
    I'm not after high framerates, just 2fps would be enough really as I don't want to stream - just take periodic snapshots and capture frames when motion detected.

    I'm using the latest Raspbian image, and have applied all available updates, but still no joy at 640x480.

    If you have managed to get them working at 640x480 at least I know the possibility is there...

    Cheers!

    ReplyDelete
    Replies
    1. I've been using the motion default of 320×240 for two XBox USB cameras at once. With just one camera 640×480 worked, and as I recall even the full native 1280×960 was possible in motion - but at a noticeably lower frame-rate.

      The multiple USB camera resolution limitation appears to be due to the data size, perhaps a Linux driver issue, or in the computer's USB hardware. This is not specific to the RaspberryPi - I had similar trouble trying multiple USB cameras on a Linux laptop and desktop.

      Delete
    2. Thanks for that.

      As it happens, I did manage to get my first Xbox cam running at 640x480 last night. I changed the palette in motion.conf to 2 (I think, whichever one is mjpeg anyway) and that seemed to fix it.

      With a framerate of 3fps and streaming turned off in motion, it settled around 50% CPU load (with framerate set to 30fps, CPU load was around 100%, although I didn't try that framerate with streaming disabled).

      On a separate note - I see you bought some different lenses for your cams - any chance of a link to the items on Ebay (or an equivalent) ? Not sure exactly what to look for.

      Thanks for your help!

      Delete
    3. It would be interesting to try over-clocking the Raspberry Pi to see if that can improve the frame rate.

      On the subject of replacing the Xbox webcam lens with a CCTV lens try looking for "cctv board lens" on eBay.

      Delete
  4. Hi Peter,

    Can you please advise what was ur motion.conf as I am having trouble running two webcam at once. Only one webcam works fine.

    I am using wifi dongle and 2 webcams connected using powered hub. Also, I have modded the raspberry pi for the polyfuses but still could not get 2 webcams working.

    Although did not try plugging ethernet cable directly (i.e. without wifi dongle).

    Sid

    ReplyDelete
    Replies
    1. I could only get two cameras to work when connected directly to the RPi's own USB ports. Using a hub didn't work - there may have been a power supply limitation, but I think the main problem is USB bandwidth limits.

      Try using the ethernet cable so you don't waste a USB port on the wifi dongle.

      Delete
  5. Would you be able to put up the HTML code for your simple webpage

    ReplyDelete
  6. Hello

    I am with trouble in the configuration. I made all your tutorial, but this doesn't work good for me. This is the error, Error selecting input 0 VIDIOC_S_INPUT: Device or resource busy, any suggestions?

    Thanks.

    ReplyDelete
  7. Hello,

    is it also possible to set webcam_localhost = off ?
    The disadvantage currently is that the website which provide the 2 pictures from the webcams refreshed every second.
    This is not so good because some datas will transfer over the network.
    Is it possible to set the webcam_localhost = off and configure motion that for example motion send every 5 minutes the two pictures from the webcams?

    Thanks

    Martin

    ReplyDelete
    Replies
    1. You can leave webcam_localhost = off (which is the default), and then the only a webbrowser running on the RPi itself will be able to see it. Motion can be setup to capture movement, or on a simple timer basis (e.g. every fix minutes).

      Delete
  8. Hello am I missing somethink? I have motion setup with on cam and trying to get the 2nd cam working(both cams works on the pi) what is it I have to do to make the 2nd cam work.

    ReplyDelete
    Replies
    1. First of all have you tested each camera with motion on its own?

      Do both cameras show up under /dev/video0 and /dev/video1? Have you setup motion using two threads, and the two thread specific configuration files are pointing at the two different /dev/ video devices? Does motion give you any error messages?

      Delete
  9. hi, this is a very nice blog. I'm new to raspberry pi. As you said you went with two camera configuration files as ~/webcam/cam1.conf and ~/webcam/cam1.conf which is just videodevice /dev/video0, webcam_port 8081.
    So, how can we open these configuration files?
    I know how to open the main file just type sudo nano /etc/motion/motion.conf
    thanks

    ReplyDelete
    Replies
    1. I'm suggesting creating a 'webcam' folder under the pi user's home directory ('/home/pi/webcam' or in shorthand '~/webcam'), holding the camera specific configuration files ('~/webcam/cam1.conf' and '~/webcam/cam2.conf'). You can create or edit them with 'nano ~/webcam/cam1.conf' for example. You can use a different folder or names, as long as it matches your 'thread' lines in '/etc/motion/motion.conf'.

      Delete
  10. i want to capture image from motion and save it in rpi ..... is it possible?

    ReplyDelete
    Replies
    1. Yes. Saving images is one of the basic functions of Motion - this can either be when it detects movement, or you can configure a regular snapshot (e.g. every 5 minutes or whatever). Please read the Motion documentation.

      Delete
  11. thanks for posting this - it was very helpful

    ReplyDelete
  12. Thanks for the awesome tutorial!

    When I try to view the page from a different WiFi than the Pi is connected to, the images wont load. I believe this is because I am taking the images from http://raspberrypi:8081 and http://raspberrypi:8082 which is a local ip and cannot be viewed from another WiFi network. I have port forwarded the Apache page, and it load fine; Its just the webcam streams that don't when I am on another WiFi.

    Do you know of a way to solve this (other than port forwarding every webcam which would be dangerous)?

    Thanks a bunch!
    -Daniel

    ReplyDelete
    Replies
    1. Sorry Daniel - I only ever tried this from the same wifi network. You could try using fixed IP addresses rather than DHCP, but not sure if that would help...

      Delete
  13. Thanks for this tutorial!!!

    ... by the way, using a PI2, even 4 webcams work nicely
    connected directly to the PI2, using the same scheme

    thread /home/pi/webcam/cam1.conf
    » videodevice /dev/video0
    » webcam_port 8081

    thread /home/pi/webcam/cam2.conf
    » videodevice /dev/video1
    » webcam_port 8082

    thread /home/pi/webcam/cam3.conf
    » videodevice /dev/video2
    » webcam_port 8083

    thread /home/pi/webcam/cam4.conf
    » videodevice /dev/video3
    » webcam_port 8084

    ReplyDelete
    Replies
    1. Nice! I've not tried that yet myself - thanks for posting this tip.

      Delete
    2. Just a quick tip that my config was called 'stream_port' not 'webcam_port'. Works a treat once that is changed. Nice tutorial Peter, thanks!

      Delete
  14. hai peter, how to save two cameras in different folders?

    ReplyDelete
    Replies
    1. I think you could just add different target_dir settings to each camera specific conf file (it defaults to the current directory).

      Delete