As some of you may have noticed, we here at the flat have a cat. Her name is Mica and she is very sweet and friendly. Of course, being around geeks, she has her own profile (linky coming soon). Anyway, she ended up getting pregnant, started swelling up like a balloon and eventually had 5 adorable kittens. They were so adorable that people kept calling and asking how they were, what they were up to and for photos of them. As a result I decided to set up a webcam so that people can just go visit. This page gives an overview of the system.
First I needed a webcam, I decided to dig out my old Logitech Quickcam 3000 (USB1.1) that I had since abandoned (I can't say I ever used it much) and mounted it above the kittens, like so:
The machine I used for this was a Thinkpad T23 that I bought faulty off eBay and fixed (same pulsating fans and all that).The laptop was not originally supposed to be used, it was just for spares, but with the arrival of the kittens I decided to repurpose it. I got it working by using some parts from old X21 and X23 Thinkpads, installed Archlinux and plugged in the ethernet and webcam.
Well, one of the things about the setup is that almost half of the photos are wasted at night, we only get black pictures. As such I thought about setting up a night vision system. First thing I did was read up on whether or not cats can actually see infrared. I thought it would be rather mean to blast them with light every 30 seconds while they are trying to sleep. Luckily it seems that they do not see infrared. Rather they have a much larger number of Rods in their eyes, which give them the ability to see so much better in the dark. So I decided to alter my program to provide night-vision support.
The first thing I did was to design a circuit to fire the LEDs. I decided on using the parellel port of my PC, as it's the easiest and cheapest thing to interface to. The port cannot directly drive all the LEDs (I got ten of them) so I used a transistor as a switch. The transistor is a TIP122 Darlington pair I bought for a stepper driver; it's serious overkill for the project (60V @ 25A max) but I have a glut of them, so it was used anyway. Substitute for any Darlington pair (or NPN type) that meets or exceeds the voltage and current specs for the LEDs. The infrared LEDs I bought were 10mm size, with the following specs:
|
Min |
Typical |
Max |
Units | |
| Forward Voltage |
1.35 |
1.6 |
1.8 |
V |
| Output |
10 |
35 |
- |
mW/sr |
| Wavelength |
920 |
940 |
950 |
nm |
| View Angle |
40 |
degrees | ||
Before wiring all of the LEDs in, first I tested with one. As infrared LEDs are a bit hard to see with the naked eye, I used a yellow one of similar specs for testing.
To run one of these LEDs on 12V I needed a 520 ohm resistor in series, so the circuit looks something like this (note this one shows a S9014 NPN transistor, rather than the TIP122: that's because I drew the schematic while working with the S9014):
The transistor is set up in common emitter mode, the P1 is the pin of the parallel port, D1 is the LED and R1 is the 520 ohm resistor. As 520 ohms is not a standard resistor value, I picked the one closest to it (I think 523), The closest I had to it was a 472ohm resistor, which was fine for testing.
The code used for testing:
>>> import parallel
>>> p = parallel.Parallel()
>>> import time
>>> while True:
... p.setData(1)
... time.sleep(1)
... p.setData(0)
...
It was a success, the LED off:
And on:
Now, on to the Infrared LEDs!
First I worked out what resistance would be needed with 5 LEDs in series. Unfortunately the person I bought these LEDs from didn't mention what their forward current was, so I was left to guess. I tried 20mA, but found it to be way too dim, now I'm trying with 120mA. The calculations are as follows:
Resistance = (Supply Voltage) - (LED Forward voltage) / Forward current
As they are in series, the forward voltage is 5 * 1..6V = 8.0V, so:
Resistance = (12 - 8) / 0.12 = 33.333333333333336 ohms
That value I rounded to 33 ohms, as that is the resistor I had spare.
Another useful thing to work out is how much power the resistor would dissipate as heat:
P = I2R, so P = 0.12*0.12*33 = 0.0144 * 33 = 0.4752W
So a 1/2 watt resistor would be good for 5 LEDs, but it would get noticably hot after prolonged use.
After wiring it all up, we got it working. I'm not sure if they are bright enough, but I can always increase the current later. For now this is how they look through my digital camera (sorry about the blurriness):
And the circuit itself:
This is all well and good, but I want to use 10 LEDs, not 5. What I decided to do is put two sets of 5 LEDs in parallel, like this:
The way this works, we have twice the current draw, so the resistor dissipates 950mW of power, which is almost twice the maximum of the 1/2watt resistor. Indeed if we run this circuit for longer than 20 seconds the resistor gets so hot that it starts melting the breadboard. Thankfully the software is designed to never be on for longer than 2 seconds. I will replace it with a 1 Watt resistor , but I don't have one at the moment. This is an example of a situation where a software bug could in fact cause physical damage. Let's hope that doesn't happen as it would be quite a fire hazard.
The next thing I needed to do install them. For this I ended up doing something I had not done since I was about 7 years old, I decided to use cardboard as a base for the LED's. It seemed the best idea. The cardboard was easy to work with (just push the LEDs through), sturdy enough to support them, cheap and plentiful for me (I had it sitting around) and light. First thing I did was get some cardboard, I used some old cardboard from a RS Electronics box:
If you click on the image to enlarge it, you will see little X's where I will push the LED's through. I pushed the LED's through, and soldered them in series, like so:
All connected up, now we just test it to see if everything is functioning as intended:
Success! The last thing left to do is to mount it above the kittens:
And that's it. The cardboard is so light I could attach it with tape, and the one time it fell, the kittens didn't even notice, they just kept sleeping underneath it.
Before:

After:

As you can see, it has been a hell of an improvement over the existing setup, I'll be working to tweak it as time goes by. Although, in hindsight, I should have spread out the LEDs more, not put them in two lines. Oh well.... it's still an improvement as I can actually see things now. I modified my webcam software so that between two points (given in 24h format) it works in "night" mode, firing the IR LED's for the time it takes a picture. As a result of this the LEDs are rarely on for more than 1 second every 30, and the resistor does not get very hot. During the day it does not fire the LEDs at all, as they don't do anything, and it would be nothing more than a waste of power.
I looked around at a lot of the webcam software out there, and nothing quite fit my needs. Most of them were too complicated, things like FTP transfer to a remote server, motion detection etc... In the end I decided it would be easier (and more flexible for me) if I just wrote my own software, which is what I did.
First I needed a way of getting one picture out of the camera at a time. Eventually I found out about mplayer's -frame option, and set it up to only output one frame (for the actual mplayer command I used, look at my Quickcam 3000 article under "Linux" in the "General Info" link above). Next task was to get it to output into a web-accessible format. Mplayer can output to either PNG, TIFF or JPG. TIFF was way too large, so out of the question, so we were left with two options. After quite a bit of testing I settled on JPG, because while it was not as good quality as PNG, it was more than 4x smaller. As we needed a picture every 30 seconds for about 10 weeks, space was of the utmost importance. As such we went with JPG.
The program I wrote takes a frame every 30 seconds, gives a name that corresponds to the timestamp it was taken at, then it is saved in a publically accessible folder. At the same time it updates a simple text file with the timestamp of the latest frame. When you access the page, the php script reads the timestamp from this file, finds the corresponding picture, and loads it. The web server I decided to use is lighttpd, with php-cgi support.
If you are interested to see the kittens yourself, you can find them here: http://ziva-vatra.dnsalias.com:89/.
Update: The webcam has been pulled down now, due to the fact that the kittens spend most of their time running around our living room, but the galleries are still available for viewing and download at the above link.
http://www.kpsec.freeuk.com/trancirc.htm
http://orionrobots.co.uk/tiki-index.php?page=PyParallel
http://pinouts.ru/ParallelPorts/ParallelECP_pinout.shtml
http://pyserial.wiki.sourceforge.net/pyParallel