One of the cool devices I wanted to get work with .NET Micro Framework was a camera. Problem with most of the camera is, that it's using almost 20 pins when connecting to CPU. There are eight pins for Y-bus (gray-scale image) next eight for U-bus (color channel) and three pins for clock, frame-sync and h-sync. After that, camera is usually required to be connected over I2C, for configuration settings (brightness, contrast, rotation etc.)

Luckily there is the company called COMedia Ltd., producing still image cameras connected over serial interface. Cameras can be purchased from Electronics 123.

C328R camera module
C328R camera module

C328R Jpeg Compression VGA Camera Module

C328R is neat camera which can be purchased with different lenses. Those cameras are controlled by commands send over serial interface, so there are just four cables (Tx, Rx, +3.3V, Gnd). Communication logic is TTL so additional circuit is required when connecting to RS-232 port.

The best feature on this camera is ability to produce directly Jpeg images or 'raw' format images in different color depth and sizes. Camera resolution is VGA so pictures from 80x60 to 640x480 can be taken.

Connecting camera with Tahoe development board is simple. Tahoe serial port two is used. Ground black-wire is connected to pins labeled 0V, power red-wire must be connected to 3.3V pins. This is important, because connecting camera to 5V may cause damages to it. Yellow wire goes from Tx on camera to Rx on Tahoe. Green wire connects Rx on camera with Tx on Tahoe. Figures shows the connection.

C328R and Tahoe
Connecting power

C328R and Tahoe
Connecting serial interface

Camera driver

C328R is controlled by twelve commands, like Sync, Initial, Snapshot, GetPicture and so on. These commands are represented by two bytes and has four arguments. The complete command packet is always six bytes long. I definitely recommend to read C328R User Manual for better understanding of the camera functionality.

Driver for Micro Framework I wrote, exposes camera commands into the managed code class. It's necessary to understand that it's low-level driver for one specific hardware. For general purpose in real-life projects, it should be wrapped into more abstract camera class.

C328R camera module
C328R bottom view

Initializing camera driver

Constructor of the camera takes as the argument SerialPort.Configuration representing communication parameters and port to which camera is connected. First thing before talking to camera is to call Sync() method. Sync wakes up camera and let it detect communication speed, by sending sixty times the SYNC command (AA0Dh). If the process is successful and camera is responding method returns true.

Once the camera is up, Initial command (AA01h) can be send. This command configures picture quality and compression and it's represented by Initial(C328R.ColorType, C328R.PreviewResolution, C328R.JpegResolution) method. First two attributes has no effect, if only Jpeg pictures will be taken. Everything is visible from following listing. Lines 9 to 12 are completely optional and not required in initialization process.

// Create camera  
C328R camera = new C328R(new SerialPort.Configuration(
                            SerialPort.Serial.COM2, 
                            SerialPort.BaudRate.Baud115200, 
                            false));  

// Synchronize with camera 
camera.Sync();   

// Set baud rate - optional  
camera.SetBaudRate(C328R.BaudRate.Baud115200); 
// Set light frequency - optional 
camera.LigtFrequency(C328R.FrequencyType.F50Hz); 

// Initiate camera and picture details
camera.Initial(C328R.ColorType.Jpeg, 
                C328R.PreviewResolution.R160x120, 
                C328R.JpegResolution.R320x240);

Taking pictures

Now everything is ready to start taking pictures. Camera can operate in two modes: Snapshot and Preview/Jpeg. First mode takes picture and stores it in the buffer for later download, while second mode start immediately transfering picture data over serial connection. Following list shows how to take Jpeg pictures in first mode. It's important to have some delay before Snapshot and GetJpegPicture commands. Delay is adequate to the picture resolution and color depth.

// Picture data buffer
byte[] pictureData;

// Make Jpeg snapshot
camera.Snapshot(C328R.SnapshoteType.Compressed, 0);
// Make raw snapshot
//camera.Snapshot(C328R.SnapshoteType.UnCompressed, 0);

// Give C328R some time to process the picture
Thread.Sleep(1000);

// Get stored Jpeg snapshot from camera
// Give 0 processDelay - because we already gave 1000 ms.
camera.GetJpegPicture(C328R.PictureType.Snapshot, out pictureData, 0);

Immediate picture taking is done by calling GetJpegPicture or GetRawPicture without Snapshot command. In this case the process delay must be specified in Snapshot command. Color depth and resolution for raw picture is specified in previous Initial command. All C328R methods returns bool result defining whether the operation was successful or not. In case of camera error the exception is thrown. Exception contains number identifying the error code. More on error codes can be found in C328R User Manual.

// Picture data buffer
byte[] pictureData;

// Get instant Jpeg picture - give some process delay
camera.GetJpegPicture(C328R.PictureType.Jpeg, out pictureData, 800);

// Get instant Raw picture - give some process delay
// camera.GetRawPicture(C328R.PictureType.Preview, out pictureData, 800);

Displaying the picture

Using the captured picture in .NET Micro Framework is very simple through Bitmap object. Contsructor of the Bitmap has override allowing to get data directly from array of bytes.

Bitmap picture = new Bitmap(pictureData, Bitmap.BitmapImageType.Jpeg);

Such a bitmap can be used in Image control and immediately displayed. In case of the raw image is the situation a bit complicated. Data has to be decoded and displayed according to format. For example 12-bit color format means that each 12 bits represents red, green and blue component for one pixel (three bits for color). In case of 16-bit encoding five bits are used for red and blue, while green has 6 bits (human eye green color sensitivity).

// Picture data buffer
byte[] pictureData;

// Get instant Jpeg picture - give some process delay
camera.GetJpegPicture(C328R.PictureType.Jpeg, out pictureData, 800);

// If some data exists - show'em
if (pictureData.Length > 0)
{
    mainWindow.Background = new SolidColorBrush(Colors.Black);
    imageView.Bitmap = new Bitmap(pictureData, Bitmap.BitmapImageType.Jpeg);
    imageView.Invalidate();
}

Demo application contains C328R driver class and very simple application displaying captured image on display of Tahoe. As the trigger is used select button on Tahoe keyboard.

Conclusion

C328R is the fastest way to get camera functionality in embedded projects. It's not designed to taking video sequences, at least not better then six pictures per seconds. It's not even designed for high quality images, but still offers good way to take pictures in home automation, point of sales or some hobby gadgets.

Download demo here C328R_stuff.zip [32 Kb].

See sample pictures: Sample 1, Sample 2, Sample 3