This entry is the next part of a series in which I share my experience building a solar-powered camera node for a ZigBee mesh network. These posts are not intended to be a tutorial on ZigBee; there are lots of places to find that information, one of the most digestible being Building Wireless Sensor Networks by Robert Faludi.
Now that I had the radios talking to each other, I wanted to try out the camera. I chose the Weatherproof TTL Serial JPEG Camera from Adafruit.com, based on the VC0706 security camera digital processor from Vimicro. The core part of the camera is a 1/4-inch CMOS sensor. A microcontroller can talk to the camera through a serial port; sending a command over the serial port to take a photo and retrieve it will return a JPEG image up to 640 x 480 pixels. The serial port baud rate can go up to 115200 baud. You can send it commands to change focus, and also to take a snapshot when it detects movement.
Another nice thing about this camera is the weatherproof enclosure, and the array of infrared LEDs and a built-in light sensor; if the light sensor detects there is not enough visible light, it switches on the infrared LEDs to illuminate the scene, making it possible to take night shots. At USD$55, I reckon it’s good value.
The camera module uses 3.3V logic on its pins; the Arduino uses 5V, so I needed to have a voltage divider on the input to the camera so that voltage levels don’t blow it away.
This is the circuit:
The TX and RX pins refer to the transmit and receive pins, relative to their module. Pins 2 and 3 on the Arduino will be used for serial receiving and transmitting respectively. RX and TX on the camera are for receiving to and transmitting from the camera.
For now, I wired this up on a small breadboard.
Adafruit have done a lot of work to make this camera as easy to use as possible. They have published an Arduino library and examples for talking to VC0706-based serial JPEG cameras with a higher-level API. It’s quite simple to get the camera to take a snapshot and read it out from the serial port. Then I only needed to send it to the serial port on the XBee module to get the image to the Coordinator and the receiving node.
Since I was now sending a couple of different types of messages, binary images and text debug and information messages, I needed to design a simple message protocol. I decided to use JSON format.
A debug and information message looks like this:
To decode these message types, I changed the Ruby server to handle each type. If it receives an ‘inf’ message type, it just prints out the message contents. If it receives an ‘img’ message type, it decodes the Base64 string into an array of bytes. When it has received all the image in the byte array, it writes the image to a file and waits to receive the next one.
On the Arduino side, I needed to set up the serial port as before, and to initiate the camera. As indicated in the diagram above, the camera module is connected to digital ports 2 and 3 on the Arduino. Basing the code on the Adafruit snapshot example, it looked like this:
The best part is how well the infrared LEDs automatically illuminated the same scene when I turned off the lights.
I’m hoping this will work really well out in the field. More on that later.
With the XBees running at 115200 baud, it seemed to take an average of 20 seconds to send a 45K-byte image. Keen observers, or even casual ones, will note that by choosing a JSON format for the messages, I have effectively doubled the number of bytes required to send an image to the server. I will fix that problem in the next installment.