I’ve been tempted to build a couple of camera projects recently, the first being a camera to capture the images to create an Analemma, which shows the path of the sun through the sky at a fixed time (usually at its highest point) each day over the course of a year, and the second being an all-sky camera.
For both of these ideas I decided it would be handy to have a camera connected up to a SheevaPlug as they’re relatively small and low power. I might have been tempted to go for a Raspberry Pi if I’d been able to get any, but I have the SheevaPlugs lying about unused so they seem like a sensible choice anyhow.
The first stage was to decide on a camera. I know of people using the Xbox Live camera for sky images and planetary imaging, so that looked like it would be worth a try and bought a couple from Ebay for the price of a couple of pints of beer. I also ordered a short focal length wide-angle lens that should fit into the same thread as all of these cameras seem to use (a fine M12 thread, as far as I recall).
As the new lens was coming from China and would take several weeks I got on with modding one of the cameras first, opening it up and pulling the LEDs off the PCB. They seem to have a significant effect on the image even though the sensor is supposed to be sealed from their glare. At the same time I removed the IR filter. Using SharpCap on Windows I managed to pick up a few stars so it looked like there were possibilities for using the camera as an all-sky cam overnight, perhaps picking up images of satellites or meteors and meteorites.
That’s when the trouble started. The Xbox Live camera uses the Linux UVC driver which appears to be fairly mature code-wise, but kept throwing errors with my test code. I’m new to the V4L2 API, so for a fair while I was convinced that my code was the problem, but dredging through the driver source I became convinced that there are a number of issues with this camera.
The first is that the camera auto-exposure mode really isn’t suitable for outdoor use so I need to add code to set that myself. This leads directly to the second problem.
Which is that when the camera is queried to find out if it supports manual exposure setting (it does) the response is that the minimum exposure is 1, the maximum is -1 and the default is 166. Clearly that’s nonsensical. The driver clamps out of range inputs to the minimum or maximum values too, so even if I tried to set the exposure to the default value, it ended up being set to -1.
The third problem is that although commands can be sent to the camera over USB and they apparently complete correctly, it looks like the camera itself takes some time to actually complete processing of that command internally. If commands are sent in quick succession (as happens if you want to set the image resolution and then the exposure length) then the later ones just keep timing out. There is a mechanism to allow one of the timeouts to be changed in the driver when it is loaded, but doubling that didn’t help at all and I’m not convinced it would anyhow.
I posted to the UVC developers list about this yesterday, but there’s been no response as yet. They possibly think I’m an idiot, rambling on about the odd behaviour of this camera anyhow. In the meantime however I’ve bodged my application to add a delay of a couple of seconds after every ioctl command sent to the driver (one second wasn’t enough, two seems fairly reliable). This is a messy fix, but I’m not confident with adding delays inside driver code. It still means there are problems when third party code is linked in to applications though, such as libv4l2. I’ve also added code for a new “quirk” in the driver which forces the maximum exposure time to be set to 255. I had a bundle of fun working on this as it meant upgrading the SheevaPlug I was working on with a new release of the OS, and in fact swapping from Ubuntu (which no longer supports ARM processors, apparently) to Debian. More about that in another post. These changes did however allow my code to run correctly most of the time. I still get a few timeouts in the libv4l2 code, but I’ll work on those later. I’ll also post my driver diffs once I get organised.
On the assumption that I can still pick up enough stars to make it interesting during the night, I still have some other issues to deal with. First is that I really need to be change the exposure lengths depending on how light or dark it is, so I need to think of some mechanism for that. The second is that the night time images appear to be fairly noisy, so some method of noise reduction would be useful. For the moment however I intend to procrastinate and worry about both of these issues later.