Steve's Webcam Monitor



Introduction
I first bought my webcam a number of years ago so that I could occasionally peek in on my house from home. My daughter often plays with my computer, and it's neat to be able to peek in and see her during the day. I bought an old Logitech QuickCam Express on eBay for about 8 dollars. Only a few models of Logitech QuickCam Express are supported on Linux, my chosen webserver operating system, so you have to be careful which camera to buy. For the purposes of this webcam monitor, however, the type of webcam is not relevant. After having the webcam installed and live for a few months, I decided to take a look in my apache log files, and found that I was getting hits on the webcam from all over the place. Sometimes, people would sit and watch the webcam for hours at a time. I can only imagine what I was doing at my computer when they were watching me. I got the idea that I really would like to know when I was being watched, and I wanted a quick and easy way to shut the webcam off when I didn't want to be on camera. While I was looking for a good solution, I came across this page describing a device that would allow a user to shut down a server safely, without having to log in. The device looked like it could be easily modified to my purposes, so starting with his design, I created my webcam monitor.

What is it?
What I came up with is a small black box that sits next to my monitor. Whenever someone hits my webcam, a red light flashes on the box. This informs me that someone is viewing my webcam, and I should be presentable. In addition, there is a toggle switch on the box that, when flipped to the Off position, turns off the webcam, and replaces the picture with a still image. This is useful for when I get paged and have to connect to work early in the morning. I don't want to have to get dressed and comb my hair before fixing a server problem at work. Instead, I just come in, flip the switch off, and continue. When the switch is flipped off, the red light turns on and stays on. This is a visual reminder that my webcam is currently turned off. Following Guido Schorr's example, all that I am really doing to flash the LEDs is raising and lowering DTR and RTS. By raising and lowering these pins, I can control a small 5v charge that I can use to light an LED. The switch is merely a line tied to the Carrier Detect pin. When the switch is in the active position, I send power to the Carrier Detect pin. In my script, I simply check for carrier to determine if the switch is open or closed.

Hardware
For this project, I used the following pieces, bought from our local Radio Shack:
For my project, I didn't buy any wire. I had a small spool of RJ-45 networking cable, so I just cut off a piece, and pulled the wires out. They worked great. I'm using a SPDT toggle switch, only because my local Radio Shack didn't have an SPST toggle switch. For more information about the different types of toggle switches, I suggest Wikipedia. I am using a 1.2k resistor for the Green LED because the Green LED I bought is a slightly higher voltage than the Red LED I bought. When I used a 1.5k resistor on both, the Red LED burned much more brightly than the Green. Lowering the resistance to 1.2k made both LEDs burn at about the same intensity. Also, the D-Sub connector I bought did not have female screw threads for my DB-9 serial cable to screw into. I had an old serial card in a box in my closet, so I ripped the posts off of it and screwed them into this project. If you don't have an old card to canibalize, you can use a drop of hot glue to hold the D-Sub in place, and just don't worry about screwing the DB-9 cable into the D-Sub.

Procedure
Now for the fun part. The first thing I did was take out my Dremel tool and drilled three small holes in the project enclosure. Two holes at the top for the LEDs to poke through, and one hole in the center for the switch. To get these holes the right size, I just drilled them smaller than they had to be, then used one of the cone attachments for the Dremel to widen the hole, testing for size until I had it right. When assembled, the front of the device looks like this.


Now, again using the dremel, I cut out the D-Sub hole that is pre-scored in the back of the project enclosure. Don't worry about being totally exact with this cut, just come as close as you can. The D-Sub itself will hide any imperfections as long as they aren't too glaring. When complete, the back of the enclosure will look like this.


Next, I again used the Dremel (I really like that thing) to cut the circuitboard in half. I bought the smallest sized circuit board I could find at my local Radio Shack, but it was still about twice the size it needed to be.
Next, I soldered my LEDs and resistors in place. It is hard to tell in the picture, but each LED has had its leads bent 90 degrees, and is extending just beyond the edge of the circuit board. To get this right, I placed them in the board and bent them, then placed them unsoldered into the project enclosure, making sure they fit the holes I had previously drilled.


Now it's time to start connecting the wires. Notice that I am not using a wire to connect the LEDs to the 1.5k and 1.2k resistors. Instead, I just positioned the resistors in the next hole over from the LEDs, and let my solder drift until it was making the connection. For my project, I am using four colors of wire:

Below are a few more pictures of the project from different angles to help see what is going on. Notice the two holes for the LEDs in the enclosure. Also notice that this enclosure has a guide slot on either side that perfectly fits this circuit board. It holds the whole thing firmly in place.



And, here is a simple wiring diagram that shows how everything is hooked up. Note, the colors on the diagram match the colors on the wires in the project.



Software
Of course, the device is only half of the project. The rest is done with a couple of small scripts. First, I will describe my webcam setup. As mentioned earlier, I am using a Logitech QuickCam Express. The Linux drivers for that camera can be found here. In addition, I am using a program called 'webcam' which can be obtained here. The webcam program reads from the camera and dumps a jpeg into a specified directory. My WebcamMonitor script is responsible for starting and stopping the webcam daemon.

My .webcamrc configuration file can be obtained here. The program takes images from the camera and places them in the directory /www/webcam. This location is outside of my website directory, so it is impossible for a web user to view this image directly. Instead, the webuser has to use a perl script to view the image.

All the script does is displays the image, and creates a file in the /tmp directory called 'webcam'. You can see the script I use here. On my server, this script is called showpic.cgi. In my Apache configuration, I have a line reading

AddHandler cgi-script .cgi

What this does is tells apache that any file ending in .cgi is a script and should be executed instead of displayed. A neat trick you can do with apache is call a script as if it was a directory. The way I generally refer to the current jpg from my webcam is:

http://www.redcloud.org/webcam/showpic.cgi/webcam.jpg

I do it this way so that the browser can't tell I'm not pointing directly to a jpg. If a user was to right click on the file and Save Image As, they would get a file called webcam.jpg, just as though they drove directly to the file. However, they're actually running my script. So, why is it so important that they run my script instead of accessing the file directly? Well, I use the /tmp/webcam file that the script creates to tell me that a user has hit my webcam.

The last part of the script is my WebcamMonitor daemon. This is a perl script that I run from /etc/rc.local. The script can be obtained here. In the script, /dev/led is a symbolic link to /dev/ttyS0, where my black box is located. The first thing that the script does is creates a serial connection to the webcam monitor, and raises DTR. By raising DTR, I am lighting the green LED. This serves two purposes. First, it provides me with a lit LED telling me that the system is active. Second, it gives me a known 5v source that I can use to drive the other LED, and to send down the Carrier Detect line when the switch is turned on. The next thing the script does is goes into a loop looking for either a change in carrier detect status, or the presence of /tmp/webcam. If /tmp/webcam exists, and carrier is not detected, this means that a web user has viewed the webcam. The script then flashes the red LED for one half of a second and deletes the /tmp/webcam file.

Like many other Linux daemons, the WebcamMonitor is started and stopped through an rc.d script. The rc.d script I use for the WebcamMonitor daemon can be found here. It takes start and stop parameters. On my system, I can type /etc/rc.d/rc.webcammonitor start to start the webcam, and /etc/rc.d/rc.webcammonitor stop to stop the monitor and turn off the camera. Since these scripts get run at boot time, this also ensures that the webcam monitor program is running when the machine reboots.

Conclusion
That's really all there is to it. It was a really fun project to build, and it's come in very handy.