Driving an adafruit VC0706 TTL Serial JPEG Camera with a Netduino

HAL 9000


 Earlier this month, AdaFruit released a nice little TTL camera, perfect for security and remote monitoring applications. The camera supports three resolutions (640×480, 320×240 and 160×120), has a built-in motion detection circuit and can output an NTSC signal, all in a fairly compact form factor. The communication with the camera is done over a TTL UART @ up to 115200 bauds. In many respects, this device is very similar to the LinkSprite camera, which has been out there for some time now.

As I’m working on a security-related project involving the Netduino, it was the perfect opportunity to put this camera to the test, starting with writing a C# driver. While interfacing with the camera over the TTL UART of the Netduino is straight forward, the datasheet describing the protocol and commands required to control the camera functions is painfully sketchy and sometime inaccurate. In some instances, some camera functions such as OSD (text overlay) are not supported in the firmware even though the datasheet documents them or only behave properly if called in a particular sequence, which of course, is not documented…

Connecting the camera to the Netduino

Limor’s tutorial on how to interface the camera with the Arduino outlines the required steps rather well, so I won’t re-iterate them here. The only difference worth mentioning is that the voltage divider configuration shown in the adafruit tutorial is not necessary on the Netduino, since its GPIO pins are 5 volt tolerant. So, you can simply connect the TX pin of the camera to PIN 0 (RX) on the Netduino and the RX pin of the camera to PIN 1 (TX) on the Netduino. To make things a bit easier while testing the camera with a breadboard, I built a connector using a standard 0.1″ pitch right-angle header and a small section of prototyping board: unfortunately, the breakout board of the camera uses a different pitch. In addition, you’ll want to connect an SD card reader to your Netduino so that you can store snapshots. Please refer to my earlier post on how to connect an SD card reader to the Netduino if you aren’t familiar with the procedure. If you’re using a Netduino Plus, don’t worry about that part 🙂

Using the Netduino driver

The Netduino driver currently implements 4 major functions.

Initializing communication and the camera’s resolution

  • Initialize(string port, PortSpeed baudRate, ImageSize imageSize): This call must be the first call in the application. It takes care of initializing the UART and the resolution of the camera at the same time. The reason for keeping these two functions together is that changing resolution requires a reset of the camera, which also resets the camera’s baud rate to the factory default of 38400 bauds. In addition, if the baud rate is set to something other than the default and the program is interrupted while debugging, the next time the program runs, it will have to remember what the last baud rate was (unless the camera is hardware-reset). To avoid all this trouble, the initialization function automatically figures out the proper baud rate needed to communicate with the camera before applying new settings.

Controlling TV output

  • TvOutput(bool enable): Passing ‘true’ will tell the camera to output a composite video signal showing whatever the camera is looking at. Passing ‘false’ turns it off.

Taking pictures

  • TakePicture(string path): This function will tell the camera to take and store a snapshot, in JPEG format, to the location specified by the path argument. You need to have an SD card reader connected to the Netduino for this to work. You can control the quality of the image using the SetCompression(byte compression) function where the compression is a value between 0 and 100, with the default being 53.

Detecting motion

  • StartAutoMotionDetection(int imageSequenceNumber, string storagePath, MotionDetectedHandler motionDetectionHandler): This function will activate the motion detection circuit of the camera and will return immediately. Whenever motion is detected by the camera, the driver will callback the application through the motionDetectionHandler delegate. If the handler returns ‘true’, a snapshot will be automatically taken and stored to the location indicated by the storagePath parameter. The filename is sequentially incremented, starting with the number provided by the imageSequenceNumber argument. The motion detection can be stopped using a call to StopAutoMotionDetection(). Click on the image below to see a sample on how this can be used.

Testing the camera

To put the camera to the test, I wrote a sample taking a set of 100 pictures using each of the resolutions supported by the camera. The sample also tests motion detection and the camera’s composite output. During the test, the camera was set outside on a tripod, pointed at a neighbor’s house about 200 feet away around 8PM on August 11th. The goal of the test was to gauge the overall video quality of the camera in lower light conditions as well as evaluating the error-rate when taking snapshots.

The results

The composite video quality, shown here on a small CRT TV, is generally quite good and stable.

NTSC output

The snapshots, on the other hand, often show compression artifacts like this:

Artifacts

Out of 100 pictures taken at the higher resolution, only one did not have any artifacts. Please note that I did not tweak the color saturation of the camera before using it: colors can be greatly improved with some tuning with the tool coming with the camera. Limor covers this in her tutorial as well but I’ll post updated snapshots with tuned color saturation when I get the chance.

No artifact

In the large and medium resolutions, 1 picture out of 100 is generally corrupt and cannot be viewed. There could be several root causes for these artifacts and data corruptions:

  1. The connection I’m using between the camera and the Netduino is not shielded or twisted to minimize radio and electromagnetic interference. I haven’t had the chance to validate this yet.
  2. The serial buffer size vs. the baud rate is critical in minimizing errors: I was able to read a maximum of 120 bytes at a time @ 115200 baud without losing data with the current connection to the camera. Larger buffers only seem to increase the error rate to unacceptable levels which makes reading large images a slow process. Again, a shielded and twisted cable would likely help using larger buffers.

Conclusion

The VC0706 camera, with proper tuning, is a nice addition to any project where remote monitoring, motion detection and security are needed and it will pretty much work ‘out of the box’. It would be great to see future versions of this camera offering access to the SPI and High Speed UART interfaces: while it is possible to force the camera to use ‘out of spec’ UART speeds above 115200 bauds, it is unlikely to be very reliable.
As always, you can find the camera driver and the test code as part of the Netduino Helpers library.

Using an AdaFruit OLED display on a Boarduino without a level shifter

Limor's Playground

AdaFruit released a monochrome OLED screen last week and I wanted to test it with a netduino. So, I ported the Arduino driver written by Limor to C#, wrote a basic test app, soldered header pins to the OLED display, hooked it up to my netduino  and… nothing happened. It became clear that I needed to test the OLED display on an Arduino first to make sure that the screen was not defective in the first place.

I had on hand a Boarduino that I had previously upgraded with an Atmega328 and hacked to run on 3.3 volts instead of 5 volts, removing the need to use the level-shifter provided with the OLED display.

Here’s what ‘Frankenduino’ looks like:

The 'shoehorned' 3.3v voltage regulator 🙂

Brain transplant

Frankenduino and OLED display

That's a tiny display!

 

A few minutes later, I had my answer and the OLED display isn’t the problem here 😉

I’ll post an update soon when I have figured out my netduino driver issue…

Cheers,

-Fabien.