Cheap Video with Teensy 3.1 and $5 OV7670 camera chip

Status
Not open for further replies.

craiglindley

Well-known member
I posted this in project guidance but wanted to make sure more people saw it so I re-posted it here. I hope I didn't break any forum rules by doing so.

I have just been successful interfacing a Teensy 3.1 to the $5 OV7670 Camera Chip ( without fifo) and the Adafruit 1.8" LCD display and wanted to share what I have learned. This hardware software combination captures QQVGA (160x120) images in RGB565 format at the rate of about 1.5 images/second. I'm sure the smart people on this forum could make it much faster and/or higher resolution. I've made the code available to anyone at: craigandheather.net/misc/TeensyCamera.zip

You are free to use my code anyway you want but if you do something cool with it, please let me know.

Cheers, for the Teensy's

Craig Lindley
calhjh@gmail.com

IMG_6100.png
 
Why did you choose XCLK to be 8MHz? Wouldn't a faster XCLK allow for a higher frame rate at the same resolution? I'd just like to know your reasoning in case I'm missing something.
 
Awesome achievement!

As for the clock speed, I imagine it could have to do with using a breadboard. High speed signals and lots of wires usually do not play nice with each other.
 
Looks great! Could you explain a bit about the camera? Does it buffer the frame so you can read it over spi after the pic was taken? Can you re-read the data or specific parts of the sensor (e.g. a square area in the middle?) or does the spi directly access the sensor data?
Ben
 
I'll try and answer both questions here:

First Constantin was exactly right. Moving high frequency signals from point to point gets more complex the higher the frequency. I didn't have a scope handy when I was doing this so I thought a conservative approach using 8 MHz would be best on my breadboard.

Second, no there isn't any buffering of the image at all. The Teensy is pulling the data in real time. Also, the data is not read over spi it is read in parallel from the video chip. i2c is used however to interact with the video chip for setting up it registers and what not.

Hope this helps,

Craig Lindley
 
Wow, great work! I will get this camera in some days and I will use your code!
Thank you very much! Maybe it is not optimized but it is simple to understand and easy to modify.

What I miss is a schema. Did you connected the camera without any resistor, or do you used the simple arduino schematics (with 3-4 resistors?).
 
Last edited:
Nicely done!

I assume this low-end camera doesn't have an IR filter, so it can be used with an infrared emitter to see in the dark?
 
Thanks to Craig I was able to using this camera (thank you again!!!).

I connected SIOC and SIOD to PIN SCL0 and SDA0 (pin 18 and 19 on Teensy 3.2) with a pull up resistor. Without a 4,7k it didn't worked by me.

I don't have a LCD and not a SD so I sent the data over the serial port (baud rate: 921600).

And here a simple .NET application screenshot (draws directly the serial data in the picture):
OV7670.jpg

Because the camera sends the data with a 8MHz/31 frequency (if I understood it right), it can only get still images, the camera is not able to get moving objects with this frame rate.

Edit:
This function is called 38400 times (160x120) for each frame:
// Read a byte of the pixel data
inline byte Camera::readPixel(void)
{
byte b = 0;

if (digitalReadFast(d7)) b |= 0x80;
if (digitalReadFast(d6)) b |= 0x40;
if (digitalReadFast(d5)) b |= 0x20;
if (digitalReadFast(d4)) b |= 0x10;
if (digitalReadFast(d3)) b |= 0x08;
if (digitalReadFast(d2)) b |= 0x04;
if (digitalReadFast(d1)) b |= 0x02;
if (digitalReadFast(d0)) b |= 0x01;
return b;
}

But if you defines this data PINS in this way:
const byte D7 = 5; // from 20;
const byte D6 = 21; // from 17;
const byte D5 = 20; // from 16;
const byte D4 = 6; // from 15;
const byte D3 = 8; // from 14;
const byte D2 = 7; // from 9;
const byte D1 = 14; // from 8;
const byte D0 = 2; // from 7;

You can get the data with 1 call:
// Read a byte of the pixel data
inline byte Camera::readPixel(void)
{
return (GPIOD_PDIR & 0xFF);
}
 
Last edited:
Adriano, would you mind sharing some more info. on how you displayed the photo from the serial data?

Writing a new image from the buffer sent over the serial:

Code:
                byte[] aby = new byte[3];
                int iBuffLen = Math.Min(4096, serialPort1.BytesToRead - (serialPort1.BytesToRead % 2));
                int iBuffPos = 0;
                serialPort1.Read(buffer, 0, iBuffLen);

                while (iBuffPos < iBuffLen)
                {
                    aby[0] = buffer[iBuffPos++];
                    aby[1] = buffer[iBuffPos++];

                    aby[2] = (byte)((aby[1] & 0x1F) * 8 + 7);
                    aby[1] = (byte)(((aby[1] >> 5) + ((aby[0] & 0x07) << 3)) * 4 + 3);
                    aby[0] = (byte)(((aby[0] & 0xF8) >> 3) * 8 + 7);

                    tempImage.SetPixel(iImagePixelIndex % 160, iImagePixelIndex / 160, Color.FromArgb(aby[0], aby[1], aby[2]));
                    iImagePixelIndex++;
                    if (iImagePixelIndex >= 160 * 120) iImagePixelIndex = 0;
                }

                pictureBox1.Image = tempImage;

If you want, I can send you the VS project - I didn't continued it, because it was to detect something on the cam and because the camera doesn't take photos but streams every single pixel, you can see the same (moving) object many times on the same frame.
 
I posted this in project guidance but wanted to make sure more people saw it so I re-posted it here. I hope I didn't break any forum rules by doing so.

I have just been successful interfacing a Teensy 3.1 to the $5 OV7670 Camera Chip ( without fifo) and the Adafruit 1.8" LCD display and wanted to share what I have learned. This hardware software combination captures QQVGA (160x120) images in RGB565 format at the rate of about 1.5 images/second. I'm sure the smart people on this forum could make it much faster and/or higher resolution. I've made the code available to anyone at: craigandheather.net/misc/TeensyCamera.zip

You are free to use my code anyway you want but if you do something cool with it, please let me know.

Cheers, for the Teensy's

Craig Lindley
calhjh@gmail.com

View attachment 5577

Hello my name is Carlos

I write to you because I need your help with a project with Tennsy 3.1, please, can you send me your programming codes and the circuit as you connected it? I would really appreciate it. I want to build a camera module in a Tennsy 3.6 and record the iamgenes in a micro sd card and your project would be very useful to continue with my project.

Thank you
email: km93@hotmail.es
 
Status
Not open for further replies.
Back
Top