Monthly Archives: July 2015

Connecting Projects to Cameras

I am preparing some IoT content for a class and wanted to delve into cameras. My interest was first piqued when I found 1-5mp breadboard ready sensors on AliExpress and Ebay starting in the $3 range. This unfortunately, was the end of the good news. From this point on, the story got much more convoluted.

The options when choosing a cheap (<$30) breadboardable camera:

Serial

These are slow, poor fidelity, not very configurable devices based on the VC0706. They are great because they only need a serial port, have mature libraries and buffer the data internally. Unfortunately the max serial speed is 115200 baud. The slow transfer speed is however somewhat mitigated by the fact that the picture is compressed in jpeg format. Just to be clear, this device could be controlled by an xtal-less ATTiny85 with enough pins left over for SPI!

A cheap bare sensor (what initially hooked me)

A basic connection to the bare ov7670

The majority of the <$10 breadboardable cameras available seem to derive from sensors made from OmniVision. The majority run on 3.3v and above 1MP, integrate a jpeg encoder. These are incredibly configurable and support video. Unlike many common Arduino devices, the connections are not simple. In addition to a ~10Mhz clock (or greater) which you have to provide, and an 8-10bit pixel bus there are also several interrupt lines coming out of the device which mostly serve as out-of-band annotations for pixel data. But wait, there’s more. For setup you must also supply an I²C connection and (if you care), pins for reset, sleep mode, etc.

The problem with using these devices is three-fold.

First, timing matters. Once the camera xtal starts pulsing, the fire hose is on and you are barraged with a torrent of latency sensitive data to absorb. Servicing complicated interrupts from other devices during this time is probably off the table.

Second, the resources required/result ratio is underwhelming. Arduinos in particular typically don’t have the resources to meaningfully deal with the captured data. Even on a faster Due, (assuming the code existed) jpeg en/decoding for a basic slideshow, scaling, or filtering would be punishing. If processing the picture is off the table, you are limited to storing or forwarding the data somewhere else. Storage in this case implies investment in a framebuffer, SPI flash/SRAM, or SD card/socket. These take time, money, pins, code and breadboard space. Suddenly, the tiny $3 camera (which can only be used for pictures) is not such a win.

Third, depending on which device you choose, you will dedicate around 14 pins to the project. If you are on a Mega, this is not an issue. On an Uno however, not much will be left over for connecting to other devices, LEDs, or buttons. In my case, I don’t even have that many GPIO available.

At issue is that all of these devices are built do video in some form. To use device to the fullest they need a fast parallel bus, lots of storage, and computes. For example, take the 1MP element (ov7670). A crappy 15fps 320×240 8bit color video, would generate 1,152,000 bytes/sec. With direct port reads an Uno can do one read for each tick in its 16Mhz clock. The data is far to large to buffer in available RAM and there is no way to get rid of the data fast enough through I²C. This leaves the options of either attaching a fast SPI device (SD card), or transferring the data out in parallel to an equally quick device (SRAM, fifo, etc.). Even if the above worked, the reward would be uninspiring.

Assuming you are ok with just taking pictures, the bus, and computes problems still exist. The above mentioned Due would be unable to hold a whole 640×480 raw picture in it’s available RAM (maybe a small jpeg from a >1MP sensor would fit). That said, external storage of a still is possible even for a lowly Uno.

An ov7670 with fifo

Looking similar to the bare cameras, they cost ~3x more and come with a AL422 fifo on back.

Some versions of the more costly OmniVision 1MP boards come bundled with a (AL422) fifo. The fifo drains data from the pixel spigot and allows you to sip raw (the ov7670 has no jpeg encoder) picture data at your leisure. In addition to being more expensive, it requires a similar number of pins, and the fifo in question is too tiny for several picture formats.

ArduCam Mini

The last alternative is an interesting one called the ArduCAM Mini. This device uses a CPLD (Altera Max II) to serve as a data go-between. The CPLD, receives the flood of data from the pixel bus, stores one or more stills in a fifo (AL422) and provides an SPI interface for access the fifo store. The end result is a device with only I²C for control and SPI for data transfer. At $25 it is probably the best compromise for taking quality stills. Unlike the above, the data in the fifo can be in a compressed jpeg format instead of raw.

My Choice

In the final analysis, I went with a serial device found on AliExpress for <$17. I found I wanted the other devices for non-technical reasons. I wanted picture quality and video capability though neither are required, and in most configurations not reasonably possible. The poorest OmniVision is a much more configurable and capable device and they are so cheap! That said, after attaching the supporting infrastructure, you can still only use a subset of the device’s functionality. Arducam is cool but again a lot of resources are spent dumbing down the interface so my poor μC could handle it. Between the sensor, its DSP, and the CPLD, I got the sense that I was desperately trying to bolt a Ferrari engine in my Hyundai just for idle curiosity. It would be cool for pedagogic reasons, but the end utility would be severely limited.

My μC will be uploading the pictures to a website which implies a couple constraints. The pictures should be jpeg, and WIFI interrupts could cause latency issues so the picture data should be buffered. Also, my μC of choice lacks enough pins for the bare sensors making my only real choices Arducam Mini or Serial. Even though the Arducam has better fidelity, and is much more controllable, I realized I don’t NEED it. The serial camera is ugly, but dead simple (which has value in the context of my class) and cheaper. The AliExpress page seemed to be a bit confused about its required voltage saying it could work at 3.3v (which I need) and then minimum 4.8v in other places. So I might have to buy an ArduCam Mini anyway.

What I would like to see

If the result must be compromised, at least make it cheap and easy. This is a shorter way to say, if all I can do is snap ok pictures, give me a device with a buffer, jpeg encoder, and a single I²C, fast UART (=>345600 baud) or single SPI connection. Each of the previous options are hacky or lacking in their own way without fully reducing the cons of these devices.

Were it not for the space required, I briefly played with the idea of riveting a 2MP sensor to a dedicated Atmega328 with a 1Mb SPI SRAM, and using a slave I²C connection to other devices. The result would probably be <$15, have an electrically simpler interface than the ArduCam Mini, and potentially save precious RAM on the main μC, while being unpleasantly large and Frankensteinian.

Alternatives

If you have the kit already and/or price is not an issue there are tonnes of other options available. Ranging from addon shields to the OpenMV with its own attached μC. The latter cost $65, are much more complex, but can run micropython and even do complex blob/face detection!

 


Apropos nothing, though the research was disheartening if fun and interesting, it gave me insight into my Raspberry Pi which uses an OmniVision 5MP device. Picture taking on the RPi requires GPU memory which can be seen by raspistill optionally filling up a window with the flood of raw pixel data. Since the camera’s data bus likely runs much faster than lower MP versions, I would imagine latency, timing, and storage issues exist for the RPi too. Dumping a 5MP picture to memory first, followed by encoding/manipulation makes more sense now.