Go Down

Topic: ov7670 with both arduino uno and now mega (Read 100700 times) previous topic - next topic

Mr_arduino

Apr 10, 2013, 05:50 am Last Edit: Aug 21, 2014, 04:53 pm by Mr_arduino Reason: 1
Have you been told by someone that you an external ram of some sort such as a fifo or spi ram. I admit to thinking that was needed and telling people they need one or the other (fifo being the better option) but if you just want to send data from the camera to your PC using the arduino you don't need external ram.
Check out this https://github.com/ComputerNerd/ov7670-no-ram-arduino-uno
It requires only the ov7670 without fifo and a way to get 5v to 3.3v no other parts such as spi ram or al422.
Edit: As of 2014-07-05 I have decided to try and improve this initial post. I would like to hear your feedback. I want to try and avoid redundant questions and I think a better writeup in the initial post would be beneficial. Tell me what you think about this post.
When creating this post on the 2013-04-09 I would have never imagined that there would be so much interest in the ov7670.
I am happy that I have enabled so many people to explore the world of image processing introducing people to a valuable and fun concept.
What is the ov7670?
Although I think most people who click on this thread know what the ov7670 is, I think it is still good to have an explanation for the people curious about what all the commotion is.
The ov7670 is an image sensor manufactured by Omnivision.
This image sensor is quite old by image sensor standards. According to Omnivision they started mass production of the sensor in February of 2006.
The image sensor has a resolution of 640x480 and is an Soc meaning it has built in image processing capabilities.
Why the ov7670?
I am quite surprised that out of all the sensors available this one has the most success.
I like to play with image sensors of all types not just the ov7670 however the ov7670 seems to spark the most interest in people.
I bought the module because at the time it was (and still is) the lowest cost camera module that you can buy.
The quality you can get from it would be be described as just okay. There are nicer modules you can buy for not much more money if you are looking for quality.
What can I do with the ov7670?
The reality is you are limited not only by the sensor but by the processor you are using.
This thread focuses primarily on arduino boards and interfacing the ov7670 to microcontrollers featured on an arduino board. The arduinos that I have used are both based on 8bit AVRs running at 16mhz so that is quite the limitation. I do however welcome discussion of any microcontroller. Do not expect something ridiculous like 30fps 640x480 on the arduino uno.

The original reason that I wanted to use the ov7670 was time lapse purposes.
I could live with the slow speed as all I need was an image every few seconds. However using a faster microcontroller can mean reading pixels faster but remember unoptimized code on a fast microcontroller can be slower than well optimized code on a slower device.

So with all that said: What can I actually do with this sensor? The answer is pretty much anything that does not involve subjecting the sensor to unreasonable conditions or expecting something unreasonable from it like 1000fps full resolution. What attracts me to the idea of a camera module vs just buying a webcam is the fact that I have more control over it. You are able to program it to do various tasks that suite your needs and lots of the automatic stuff on the ov7670 can be overridden if needed.
How can I get started?
Read the documentation and check out code that I have written. Also check the code to figure out some aspects of wiring. I have already explained many aspects of wiring. Just read the thread.
Where can I get documentation?
http://www.electronicaestudio.com/docs/sht001.pdf
https://github.com/dalmirdasilva/ArduinoCamera/blob/master/CameraAL422B/datasheet/OV7670%20Implementation%20Guide%20%28V1.0%29.pdf
https://github.com/luckasfb/Development_Documents/blob/master/MTK-Mediatek-Alps-Documents/OV7670%20software%20application%20note.pdf
I however would like to expand this list. If you have ANYTHING from Omnivsion that would help me understand undocumented stuff in regards to the ov7670 I will take it. If you cannot or do not want it to be posted on the internet I will respect that wish fully. I will take anything regarding the ov7670 even a newer version of what I have already. In fact I would take unrelated documentation that comes from Omnivsion. It is nice to have. You never know seemly unrelated documentation might prove to be relevant in non direct ways.
Where do you keep up to date code
Here https://github.com/ComputerNerd/ov7670-simple/ and here https://github.com/ComputerNerd/arduino-camera-tft also if you don't have any other parts besides the ov7670 check out https://github.com/ComputerNerd/ov7670-no-ram-arduino-uno it also contains how to enable pwm to get 8mhz.
I also made a data convert that allows you to convert raw data from the camera into a png file
https://github.com/ComputerNerd/RawCamera-data-converter
For windows users who don't want to bother setting up MinGW here is a windows binary.
https://github.com/ComputerNerd/RawCamera-data-converter/blob/master/convert.exe.7z
I also posted some pastebin links that is old code but it covers some stuff that the code above does not
How I can I help the author?
Responding to you all guys does not happen magically.  There are some things you can do to help ensure that I will continue to help you.
1. Give back: Know something that I don't know regarding the ov7670? Post it.
2. Avoid asking repeat questions.
3. Write stuff. Maybe you can explain something better than I can. If that is the case please do such. I am always open to suggestions on how I can improving my writing.
The initial post below the line break is the second revision of my initial post. I had to move the first revision down a post to work around a character limit.

Edit: I now recommend the fifo version over the non-fifo version. However if you have the regular version without the fifo you can still get an image using external spi ram.
If you have the fifo version lots of this is still relevant all except the external ram part and reading pixels.
The reason for using the fifo version is because of faster readout and you can capture a 640x480 images without breaking it up into pieces however to do such you must use raw bayer data.
Also I have since figured out how to generate an 8mhz clock using PWM
Using PWM to generate XCLK has several advantages including:
You don't need a special programmer to set the fuse bits.
You can change the output clock speed the fastest it goes is F_CPU/2 which results in 8mhz in the case of the arduino. However it is best to set it as max speed and use the divider that the ov7670 has.
Also a good way to keep filesize down thus improving transfer speed is to use raw bayer data.
Raw bayer appears to be about the same or better quality as yuv422 but takes half the speed thus doubling transfer speed.
I would recommend you use it instead of yuv422 I have posted new versions that use raw bayer data.
Here is an FAQ of some questions that may come up:
Q: Some arduino outputs a 5v clock but the OV7670 will only accept 3.3v what should I do
A: use a buffer of some sort it just needs to be fast enough to pass the 8mhz signal.
Q: Will the ov7670 accept twi/sccb/i2c (same thing different names) commands without XCLK?
A: No
Q: Will I need to buffer any other pins besides the XCLK?
A: No but be sure you have the i2c/twi/sccb lines pulled up to 3.3v instead of 5v or you risk damage to the ov7670
Also don't set any of the pins that go to the ov7670 as output.
Q: where can I get current registers and useful functions for the ov7670?
A: On my github page https://github.com/ComputerNerd/arduino-camera-tft
More specifically here is some stat-up registers here https://github.com/ComputerNerd/arduino-camera-tft/blob/master/ov7670_regs.h
And here are some useful functions here https://github.com/ComputerNerd/arduino-camera-tft/blob/master/twicam.c also don't forget the header file https://github.com/ComputerNerd/arduino-camera-tft/blob/master/twicam.h
And you will notice that I have vga qvga rgb565 yuv422 defined somewhere else that is here https://github.com/ComputerNerd/arduino-camera-tft/blob/master/config.h
Q: the code you posted runs on the arduino mega but I have an arduino uno what  can I do?
A; The functions that setup the camera will also work on the arduino uno and I have posted some code for the arduino uno see the pastebin links below or my github page ov7670-simple (link below)
Q: The code you posted (above) is complex give me something more simple
A: For a while I had this code available I just thought I would make it more obvious that it exists. https://github.com/ComputerNerd/ov7670-simple
Q: The FAQ does not answer my question what should I do
A: try reading through this topic your question might be answered if not post a reply I'd rather that you not send a pm because someone else may have the same question that you do later on.

nonzung

Hello, I would like to see your connection in detail. I want the camera to be used in image processing by arduino.

Thanks for answer and sorry for my English. Nice job.

Mr_arduino

#2
Apr 12, 2013, 02:30 am Last Edit: Jul 06, 2014, 05:41 am by Mr_arduino Reason: 1
Edit I had to move down the first revision of my inital post to here to work ardound a character limition below that I explained how I conntect the ov7670 to the arduino uno.
Here is the my old original post below kept for historical reasons:

I have recently been working with the ov7670 unfortunately I made the mistake of cheeping out and buying the cheaper one without the fifo. At first I though it would be a challenge to get this to work but it turns out not to be that hard at all. The problems: the arudino does not have enough ram and is slow additionally it runs on 5v when both the ov7670 and the sd card need 3.3v. The solutions. Break the image into smaller pieces and transfer the smaller pieces into spi ram in this case I have the 23LC1024 128kb of ram that means if I want a vga image 640*480*2 bytes per pixel. I must divide it into 5 equal parts. So I transfer part of the image and save that part into the sd card and do this for a total of 5 times each time skipping different regions and saving others. The sensor can output both rgb565 or yuv422 I found that yuv422 is better quality so I made a converter for that and you can get the source code here https://github.com/ComputerNerd/RawCamera-data-converter. Here is code for the capture program. http://pastebin.com/1nnRc5qL I used sdfatlib to write and based my code off of his fastlogger code. Note that by defining useLed using #define useLed will assume you have an led on pin 0 and a button on pin 1 to stop the capture hold down the button and wait for the led to blink very fast make sure that the button sinks the pin to ground. If you do not define useLed then it uses serial to start stop image send one letter to the arduino and it will  save 1 image you can send more for more images. Also Note that I found some registers online somewhere and I could not find documentation on those registers. The only ov7670 datasheet that I could find online does not explain all the registers it gives the name but the description is blank. If someone could explain with a reply or PM what these:
Code: [Select]

    wrReg(AWBC7,0x88);
    wrReg(AWBC8,0x88);
    wrReg(AWBC9,0x44);
    wrReg(AWBC10,0x67);
    wrReg(AWBC11,0x49);
    wrReg(AWBC12,0x0e);
wrReg(REG_GFIX,0x00);
//wrReg(GGAIN,0x40);
    wrReg(AWBCTR3,0x0a);
    wrReg(AWBCTR2,0x55);
    wrReg(AWBCTR1,0x11);
    wrReg(AWBCTR0,0x9f);
wrReg(0xb0,0x84);//not sure what this does
registers do that would be awesome.
To solve the 5v issue I use a buffer. To solve the fact that the arduino is slow I set the divider to 9 also I am getting the clock with the CLKOUT pin you will have to change your fuse settings for that. Also for twi communication the ov7670 is picky about what pullup resistor values you use I found 4.7k and 10k to work. I tried 1k and 2.2k and those do NOT work. You will need twi to write to the registers the image out is parallel. Here are some images taken with the ov7670.


Here is the arduino uno itself. Image is very large click here to view http://imageshack.com/a/img849/4632/zuvj.jpg

Below here lies my response (the original aspect of the post).

The connections are simple. Start by plugging in SIO_C to A5 and SIO_D to A4 since this is i2c/twi you must have a 4k7 resistor 10k also works. Make sure you have the resistor to pull up 3.3v not 5v. Also edit twi.c  in the arduino ide folder/libraries/Wire/utility search for these lines and comment them out or remove them
Code: [Select]
// activate internal pullups for twi.
 digitalWrite(SDA, 1);
 digitalWrite(SCL, 1);
This is to remove the internel pullup resistor by not removing these 2 lines you could cause damage to the sensor. Then plug d7 to digital pin 7 d6 to 6 d5 to 5 d4 to 4 d3 to A3 d2 to A2 d1 to A1 and d0 to A0 now plug in VSYNC to digital pin 3 and PCLK to pin 2. Now change the fuse bits to be exactly the same except enable the CLKOUT pin. This will output a clock run this through a buffer or level shifter to 3.3v if you do not get the 5v signal down to 3.3v it could damage the sensor. The sd card and spi ram is just standard spi wiring nothing special.


Mr_arduino

I wish you the best of luck if anything does not work right just reply and I will help you.

michinyon

Could you post a photo of your device sometime ?   I got one of these  and the connections were so tiny that
I could not see then with a magnifying glass  and certainly not actually connect anything to them.

Saren

Hi,
I'm working on a project at university about computer vision and Arduino.
I'm trying to capture an image using Arduino Uno and OV7670 camera without FIFO. Other components like SD card, LCD, additional RAM, shields, etc. are unfortunately not available at this time (I've read some tutorials about this, but they were using special shields or some stuff I don't have or camera with FIFO...).
Is it possible to directly communicate with camera from Arduino and get some images? It doesn't have to be fast, the point is to get some results.

Since I'm just a beginner with Arduino, I'm a little bit confused about how to connect my camera to it, when I don't use RAM that was mentioned above. I really don't want to damage it...
Could you please describe it or provide some connection schema for a case like mine? Could you please also give me some advice how to change the code for the capture program?

Any help is appreciated.

Mr_arduino

#7
Apr 14, 2013, 04:03 am Last Edit: Apr 14, 2013, 04:05 am by Mr_arduino Reason: 1
michinyon I bought an ov7670 camera module that means some of the pins are routed to a 2.54mm pitch header I think you have bought just the sensor. I am busy right now I will take a picture soon.
Saren it is possible I will have to get back with you on this one though. I am busy right now and don't have any code written right now for using no ram. I do however have a program that is compiled with avr-gcc that sends the image to a frame grabber program that I wrote.
Here is the sender program it is in 3 files main.c ov7670.h ov7670.c
main.c:
http://pastebin.com/dF3pc23T
I will warn you that I made some changes to the code but forgot to change the comments like the captureImg function says it missed a byte but now it does not I posted it to paste bin before realising this.
ov7670.h
http://pastebin.com/CqYTwNqn
ov7670.c
http://pastebin.com/T1nN5Ni4
Here is the frame grabber source code
http://pastebin.com/dxMJhZTq
This one is only one file. If on Gnu/Linux you will need to install the development package of SDL or if gentoo just emerge sdl. If on windows get the development library from http://www.libsdl.org/download-1.2.php
Also I made an update to my program that captures an image to the sd card it nows saves raw bayer data.
http://pastebin.com/zV0ahzPv
The link is different than the previous code that I posted.
Here is a program to debayer/demosaic the data it is still in very beta needs work
It will also convert yuv422 to rgb (the old image to sd card program saved data in that format)
Code: [Select]

//to compile type gcc -Wall -Wextra -lm -lpng -o yuv main.c
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <png.h>
#include <zlib.h>
#include <sys/stat.h>
#define img_w 640
#define img_w_2 1280
#define img_h 480
#define CLIP(X) ( (X) > 255 ? 255 : (X) < 0 ? 0 : X)
#define C(Y) ( (Y) - 16  )
#define D(U) ( (U) - 128 )
#define E(V) ( (V) - 128 )
#define YUV2R(Y, U, V) CLIP(( 298 * C(Y)              + 409 * E(V) + 128) >> 8)
#define YUV2G(Y, U, V) CLIP(( 298 * C(Y) - 100 * D(U) - 208 * E(V) + 128) >> 8)
#define YUV2B(Y, U, V) CLIP(( 298 * C(Y) + 516 * D(U)              + 128) >> 8)
char buf[1024];
void showHelp()
{
puts("Yuv422 raw image data to png");
puts("-n x replace x with the image number you want to convert");
puts("-h shows this help file");
puts("-o x replace x with a real integer between 0 and 7 this sets the offset");
}
int savePNG(char * fileName,uint32_t width,uint32_t height,void * ptr)
{
//saves a 24bit png with rgb byte order
png_byte * dat=ptr;//convert to uint8_t
//png_byte **row_pointers = malloc(height*sizeof(png_byte));
//if (row_pointers==0)
// return 1;
FILE * fp=fopen(fileName,"wb");
if (fp==0)
return 1;
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)0,0,0);
if (!png_ptr)
return 1;
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_write_struct(&png_ptr,(png_infopp)NULL);
return 1;
}
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp);
return 1;
}
png_init_io(png_ptr, fp);
png_set_IHDR(png_ptr, info_ptr, width, height,8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);//must be called before other png_set_*() functions
//png_set_compression_level(png_ptr,Z_BEST_COMPRESSION);//since we are doing timelapses we may be dealing with many files it is good to keep disk space usage down
uint32_t y;
//for (y=0;y<height;y++)
// row_pointers[y]=&dat[(y*width*3)];//the rows are contiguous
png_set_user_limits(png_ptr, width, height);
png_write_info(png_ptr, info_ptr);
//puts("saving data 2");
//png_write_image(png_ptr, row_pointers);
for (y=0;y<height;y++)
png_write_row(png_ptr, &dat[(y*width*3)]);
//png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
png_write_end(png_ptr, info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
//free(row_pointers);
fclose(fp);//done with file
return 0;//will return 0 on success non-zero in error
}
void yuv2rgb(uint8_t * yuvDat,uint8_t * out)
{
uint64_t xy;
for (xy=0;xy<(img_w/2)*img_h;xy++)
{
*out++=YUV2R(yuvDat[0],yuvDat[1],yuvDat[3]);
*out++=YUV2G(yuvDat[0],yuvDat[1],yuvDat[3]);
*out++=YUV2B(yuvDat[0],yuvDat[1],yuvDat[3]);
*out++=YUV2R(yuvDat[2],yuvDat[1],yuvDat[3]);
*out++=YUV2G(yuvDat[2],yuvDat[1],yuvDat[3]);
*out++=YUV2B(yuvDat[2],yuvDat[1],yuvDat[3]);
yuvDat+=4;
}
}
void deBayerN(uint8_t * in,uint8_t * out)
{
uint32_t x,y;
for (y=0;y<img_h;y+=2)
{
for (x=0;x<img_w;x+=2)
{
//this will do a 2x2 pixel rectangle
/*R G
 G B*/
out[(x*3)]=in[x];//copy red
out[(x*3)+1]=in[x+1];//green
out[(x*3)+2]=in[x+1+img_w];//blue

out[(x*3)+3]=in[x];//red
out[(x*3)+4]=in[x+1];//green
out[(x*3)+5]=in[x+1+img_w];//blue

out[((x+img_w)*3)]=in[x];//red
out[((x+img_w)*3)+1]=in[x+img_w];//green
out[((x+img_w)*3)+2]=in[x+1+img_w];//blue

out[((x+img_w)*3)+3]=in[x];//red
out[((x+img_w)*3)+4]=in[x+img_w];//green
out[((x+img_w)*3)+5]=in[x+img_w+1];//blue
}
out+=img_w*6;
in+=img_w*2;
}
}
void deBayerL (uint8_t * in,uint8_t * out)
{//this is an implementation of http://www.ipol.im/pub/art/2011/g_mhcd/
uint32_t x,y;
for (y=0;y<img_h;y+=2)
{
for (x=0;x<img_w;x+=2)
{
//this will do a 2x2 pixel rectangle
/* B Gb
  Gr R
*/
/*R G THIS IS WRONG BUT STANDARD The rows are reversed on omnivision sensors keep this in mind later just get alg working for now
 G B*/
//if (x>=2 && x<=img_w-2 && y>=2 && y<=img_h-2)//see if we are able to grab pixels from neighboors
//{
//printf("X %d Y %d x-img_w %d\n",x,y,x-img_w);
out[x*3]=in[x];//red just needs to be copied
//out[(x*3)+1]=((in[x]*4)+(in[x-1]*2)+(in[x+1]*2)+(*(in+x-img_w)*2)+(in[x+img_w]*2)-(in[x-2])-(in[x+2])-(*(in+x-img_w_2))-in[x+img_w_2])/8;//green at red locations
//out[(x*3)+2]=((in[x]*6)+(*(in+x-1-img_w)*2)+(*(in+x+1-img_w)*2)+(*(in+x-1+img_w)*2)+(in[x+1+img_w]*2)-(in[x-2]/3*2)-(in[x+2]/3*2)-(*(in+x-img_w_2)/3*2)-(in[x+img_w_2]/3*2))/8;//Blue at red

//out[(x*3)+4]=
out[(x*3)+4]=in[x+1];//copy green

out[((img_w+x)*3)+1]=in[x+img_w];//copy green

out[((img_w+x)*3)+5]=in[x+img_w+1];//copy blue
/*}
else//we are on the edge defualt to edge safe algorthim
{
out[(x*3)]=in[x];//copy red
out[(x*3)+1]=in[x+1];//green
out[(x*3)+2]=in[x+1+img_w];//blue

out[(x*3)+3]=in[x];//red
out[(x*3)+4]=in[x+1];//green
out[(x*3)+5]=in[x+1+img_w];//blue

out[((x+img_w)*3)]=in[x];//red
out[((x+img_w)*3)+1]=in[x+img_w];//green
out[((x+img_w)*3)+2]=in[x+1+img_w];//blue

out[((x+img_w)*3)+3]=in[x];//red
out[((x+img_w)*3)+4]=in[x+img_w];//green
out[((x+img_w)*3)+5]=in[x+img_w+1];//blue
}*/
}
out+=img_w*6;
in+=img_w*2;
}
}
uint8_t readImg(uint32_t num,uint8_t * dat)
{
sprintf(buf,"F%d.YUV",num);
FILE * myfile = fopen(buf,"rb");
if (myfile==0)
{
printf("Cannot open file %s\n",buf);
return 1;
}
fread(dat,2,img_w*img_h,myfile);
fclose(myfile);
return 0;
}
uint8_t processImg(uint8_t * in,uint8_t * out,uint32_t num,uint8_t alg,uint16_t offset)
{
if (readImg(num,in))
return 1;
uint32_t w,h;
switch (alg)
{
case 2:
deBayerL(in+offset,out);//linear
break;
case 1:
deBayerN(in+offset,out);//nearest neighboor low quality try to avoid using
break;
case 0:
yuv2rgb(in+offset,out);
break;
default:
puts("You must pick an algorithm to save the image as");
return 1;
}
sprintf(buf,"frame %d.png",num);
if (savePNG(buf,img_w,img_h,out))
{
return 1;
puts("Error while saving PNG");
}
return 0;
}
int main(int argc,char ** argv)
{
uint8_t useNum=0;
uint32_t useImg;
uint16_t offset=0;
uint8_t debayer=1;
if (argc>1)
{
//handle arguments
int arg;
for (arg=0;arg<argc;arg++)
{
if (strcmp(argv[arg],"-n") == 0)
{
arg++;
useImg=atoi(argv[arg]);
useNum=1;
continue;
}
if (strcmp(argv[arg],"-o") == 0)
{
arg++;
offset=atoi(argv[arg]);
if (offset>img_w)
{
printf("you must specify a number between 0 and %d for argument -o\n",img_w);
showHelp();
return 1;
}
continue;
}
if (strcmp(argv[arg],"-h") == 0)
{
showHelp();
continue;
}
}
}
uint8_t * Dat;//in case some of the file was not saved we use calloc instead of malloc to garentte that the unsaved pixels are set to 0
if (debayer!=0)
Dat = calloc(img_w*img_h+img_w,1);
else
Dat = calloc(img_w*img_h+img_w,2);
uint8_t * outImg = malloc(img_w*img_h*3);//all bytes in the array will be overwritten no need for calloc
if (useNum)
{
processImg(Dat,outImg,useImg,debayer,offset);
}
else
{
uint32_t imgC;
for (;;imgC++)
{
printf("Saving image %d\n",imgC);
if (processImg(Dat,outImg,imgC,debayer,offset))
return 1;
}
}
free(Dat);
free(outImg);
return 0;
}

nonzung

I forget that. I bought the camera ov7670 fifo.
Sorry and thank you so much.

Mr_arduino


I forget that. I bought the camera ov7670 fifo.
Sorry and thank you so much.

Smart choice the one with the fifo is much better I wish I would have bought it but I bought the one without the fifo.

Saren

Mr_arduino: I didn't have much time lately, but now I'm going to try it. I have some questions about connection:
1. You mentioned that it's necessary to get the 5V signal down to 3.3V. Is it possible to do this without level shifter/buffer or do I have to get this stuff?
2. Are connections the same (as in one of your posts) even in my case (without RAM, etc)?

Thanks for your effort to help. I really appreciate it :)

Mr_arduino

The connections will be mostly the same but it could be abit different as I do not own the one with the fifo I am not sure but I think instead of PCLK you use RCLK and and RCLK is output you strobe that to get data. Check you this for more info about the fifo version http://wiki.beyondlogic.org/index.php/OV7670_Camera_Module_with_AL422_FIFO_Theory_of_Operation Also you could try a resistor divider but I have heard that they are too slow you may need a buffer/level-shiftier. Also this would not require the ram as you have the fifo.

Mr_arduino

A recent discovery that I made is you can get an F_CPU/2 (8mhz in the arduino's case) clock output with pwm this removes the need to edit fuse bits. Note that this is for the arduino mega 2560 I switched to from the uno to the mega recently. This will work with the arduino uno also just change the timer number.
Code: [Select]
DDRL|=8;
ASSR &= ~(_BV(EXCLK) | _BV(AS2));
//generate 8mhz clock
TCCR5A =67;
TCCR5B=17;

Also change DDRL to proper port and pin or be lazy and replace with pinMode();

emueyes

There's a good page on generating clock signals at http://hekilledmywire.wordpress.com/2011/05/28/introduction-to-timers-tutorial-part-6/#more-57

I too have the question about level shifting; what sort of buffers are needed, would a 74HC245 do?

Mr_arduino

I think the 74HC245 would work just fine also a unidirectional one would work too. Pretty much any buffer that is fast enough to handle a 16mhz signal and can accept 3.3v as a supply voltage which the 74HC245 can. You do not need to shift the d7-d0 as those are always output from the sensor and never input. Only the clock signal needs to go though the buffer as that is an input and the sd card if you are using it.  From twi just disable internal pullup resistors and have them to 3.3v instead of 5v. Also I think I may have forgot to mention that RESET needs to be tided to 3.3v and PWDN to ground or you could use more GPIO pins if you need to use the PWDN and RESET features although a reset can also be triggered by writing to a register so driving that pin with the arduino has little purpose.

Go Up