Go Down

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

gtsam

That topic was very helpful to get me started with the OV7670 + fifo. I added working code, plus wiring / breadboard instrauctions to github  https://github.com/arndtjenssen/ov7670. I use an atmega1284 (lots of i/o pins) running at 3.3V with 16Mhz (works fine for me) which eliminats the trouble with voltage conversion between the camera and uC. Thanks to all the contributors!!!


Mr_arduino

I am very glad to hear that we helped you always glad to see knowledge being shared.

vichaz

Hi,
Mr_arduino, as you suggested I asked LCtech for pin outs.
They provided me the following archive http://ge.tt/2xBvxAs w5th the following answer:
------
It's very glad to receive your letter,much thanks for your interest in our products.
Attached the pin outs of OV7670 Camera Module ,please have a check.
 
If you have any questions,please feel free to contact us.
------

Actually, the information in this archive is not enough for me to understand how I have to continue with this module.
As I know I have to use at least some crystal for clock...

relic1974


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 exacly 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.


Hi, this is the closest thing I have found to a real library for this module, besides the over-priced arduCam shield/library, so kudos to you first of all.

I am using a Sainsmart 3.2" TFT that depends on the UFTF and UTouch libraries to work.  I use TinyFat to store to SD.  I am using a mega board, and I'm looking thru your code to see if I need to change any pin definitions, as the only pins available to me are A0 thru A7 and the i2C bus and a few other digital pins, some with PWM.  The shield uses the rest.  Plus I'm having a few errors getting main.c, ov7670.h and ov7570.c to compile.  I know no other way so I have all 3 source files tabbed out in the Arduino IDE.  I get an error about an undefined wrReg, which I see is a function and IS prototyped in ov7670.h.

Can you explain what changes to code I may need to make for the mega boards, and why I"m getting the compile error.  I also have NO idea how to use the frame grabber.

Also, a keyword.txt file would be most useful for the library.  And one more question .. I read that the library sets up the camera and grabs frames saving them to SD card (I'll have to use TinyFat somehow, not sure how) but are there functions in the library to output to a TFT screen?  If not, how do you suggest going about displaying on a screen, or would it be faster to send the data over bluetooth to the Processing IDE.

Sorry if these are noob questions but a lot of these methods are new to me, as so far I've only worked with single .ino files.

relic1974

OK, I have another question for MrArduino, and first of all I and I'm sure MANY others are most grateful that you took the time to write this library and are providing help.

An idea hit me and since you've had plenty of experience with these camera modules I wanted to ask if this approach would work.

I have a Sainsmart UTFT 3.2 inch + shield + touchscreen + SDCard.  The ONLY library that works with the sainsmart shield is the UTFT/UTouch library.  But while doing research I found the official arduino page with great example code and wiring examples.  The way I understand this module, all data is sent via SPI, MOSI/MISO.  Unlike other TFT displays, mine has a 40 pin header with 16 bit data bus (D0 - D15 plus all of the other usual CS and SPI lines.  It appears that if I connect my TFT without the sainsmart shield, following the default wiring shown here  http://arduino.cc/en/Guide/TFTtoBoards that it should work

Can I use your library to simply 'direct the traffic' and set registers, and connect the OV7670's DATA (D0-D7) outputs DIRECTLY to the sainsmart TFT's data input bus?  It would seem that if it was possible to do this I could basically stream the data directly from the camera to the TFT.  The arduino would just handle setting up the camera, controlling CS and sync signals and SPI.

If this would work, I am guessing that the framerate would be very fluid, and the images from the camera would virtually be displayed on the TFT as if it were streaming.  My module DOES have FIFO onboard.

And if all of this is possible in theory, what changes would I need to make to your code and/or library?  Here is a pin diagram of the TFT display that I have, and I'd REALLY prefer using this one.  image link below...

http://www.sainsmart.com/media/wysiwyg/Product/PinOut.jpg

I am hoping that this way I can avoid the sainsmart TFT shield, avoid the UTFT library (and eliminate rewriting a lot of tft code), avoid using something like the arduCam shield, and get great streaming video / results.

I'd also be more than happy to share in detail my results, I'm just new to these camera modules and interfacing to a not so standard TFT screen.  BTW apart from what a lot of people think about Sainsmart modules/shields, IMO this TFT is of great quality, has a responsive touch screen, and saves to SD just fine.   The picture is vivid as well.

drkblog

Well. I'm back with the OV7670 (now with FIFO). After some work I concluded I have the version 1 of the module. What means I have to reset the write pointer by hand at the start of the frame (as far as I know).

I managed to build a testing program which captures a frame and then dumps it to the serial interface. By dumping the captured frame more than once, I checked the memory reading process is working. Yet, the captured frame seems of of sync. The capture steps are:


  • Wait for VSYNC HIGH

  • Wait for VSYNC LOW

  • Reset Write pointer

  • Set Write Enable HIGH

  • Wait for VSYNC HIGH

  • Set Write Enable LOW



I tried by inverting VSYNC (and doing the proper changes in the code) as the version 2 of this module need such configuration, but I get the same result. I checked in the module HREF is connected to a NAND with the Write Enable input pin. So horizontal synchronization should be automatic. But I'm puzzled I get this kind of image:

6 FPS


3 FPS





relic1974

drk I have a question maybe you can answer.  I have a TFT/touchscreen 320x240 that has a 40 pin header and uses 16 bit data bus instead of SPI.  (at least I don't see any SPI pins labeled).  Is this screen going to work, or is it a waste of time .. and should I just buy a SPI based LCD ?

Also I have found so many different examples that my head is spinning.  Are you using a library to set your fuses?  Or are you manually writing to registers in your code?  I think if I could just get the camera configured then I would have some luck getting data out to a LCD.  My cam also has FIFO.  Using an external 16mhz xtal to clock it.

as for your problem, maybe using the two available interrupts for catching the vsync and href signals would help??  I've created many arduino projects, but getting this camera to work has been the biggest challenge yet. 

drkblog

The point is according to the documentation I've found, I have nothing to do with HREF signal. I wait for VSYNC pulse (start of a frame) and set Write Enable high until VSYNC goes down. In the AL422 /WE is the output of a NAND between WE and HREF. That way /WE is low if and only if I set WE high and HREF is high (which is high during 640 PCLK, one horizontal line). Between two HREF pulses, /WE in the AL22 goes high again which prevents recording of invalid data between two lines. At least in theory.

About the TFT, I haven't used one of those yet. But I guess the problem with a 16bits parallel interface is you have to spend 16 I/O ports just for interfacing with the display. So you will need an ArduinoMEGA or any other µC with plenty of ports. That's way SPI or I²C interfaces are preferred for µC --you save a lot of pins.

When I tested the OV7670 (without FIFO) I clocked it with 16MHz clock from Arduino at first. Later I used the code in this post and changed to a Timer library and clocked it at 4MHz (I guess, I don't remember precisely but you can see my comments in the previous pages) which made easier to read from the non-FIFO module.

Why do you clock your FIFO module externally?

relic1974

drkblog,

I think you're problem may be the 4mhz clock you are driving the camera with.  Obviously I am no expert, as I've only been able to run OV7670 init sketches to ensure that the module is functioning.  I really need to pick up a SPI display!

I've been to every forum I could fine, and even according to at least one datasheet I have seen, the MINIMUM suggested clock speed is 10mhz .. although 8mhz seems to work fine too.  I think the max you're supposed to clock it is like 20mhz.

I'm using an external ocsillator simply to increase the framerate.  It could be that @ 4mhz you're missing some horizontal / row data and also possibly missing some vsync triggers.  I'd say try your same setup and code at 8mhz and see what happens.

As for my module / project, like i said I've only had success in initializing the module.  So that I'm clear, would you kindly post any links to the libraries and/or code that you're using?  While I don't have a compatible display yet, I could at least get some framework code working and verify that I'm getting data from the cam's data bus, sync signals, etc...

drkblog

You are confused about these modules. All the FIFO modules I've seen so far don't support external clocking. Instead they are internally clocked and connected to the FIFO. From outside the module you can only access the FIFO memory. There you can read the data sequentially at any given speed. As long as you stopped the Write process (From OV7670 to the AL422B).

From what you say I guess you have a non-FIFO version, which you have to clock externally. I have successfully used such a module and you can see the images I've got, if you go back to page 4 of this same post. There I explained I was using a 16MHz clock, but as MR_Arduino said, you can feed the module with an 8MHz clock (software made, so you don have to change the fuses). And it works too, even then datasheets says the minimum clock is 10MHz. Can you link to the module you have bought? Or post a picture of it's back side (not the lens side)?

The problem with the non-FIFO version is you have to read at camera's speed and store the data in RAM. The FIFO version comes with a memory chip where you can store a full frame, then read it at the speed you want/you can.

relic1974

It looks like I am indeed confused, majorly!  the module does have a XCLK pin.  I don't have an image of the backside but I can describe what components are there and give a link to where i bought it.  It does not appear to have FIFO onboard.  I'm also going to go ahead and buy a SPI display module.

product link http://www.ebay.com/itm/261213033140?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1439.l2649

On the back of the camera, blank space except for a few caps.  Do you have a part number for a FIFO chip?  I have some arduino prototype shields I can use to solder it all up.  And I really appreciate your help / responses.  You are the first one to reply to the many forums I have posted these questions in.

drkblog

Yup! That's the non-FIFO version. You have to feed it with a clock in XCLK which can be as low as 8MHz. And you have to read data at PCLK speed. So you have to setup a slow frame rate and PCLK in order to read data from Arduino. You won't be able to do it otherwise. You will have to find out if you can do (whatever you want to do) without the FIFO version. In my case, as I have to store to an SD card, storing a whole frame to RAM is mandatory. My options are using the FIFO version or adding enough RAM externally. Of course, the FIFO module seems the accurate solution.

But I'm stuck now. I think I'm using a wrong signal sequence during the write process.

relic1974

Thanks for your reply.  I can pick up a FIFO chip cheap and TTL convert to 3V.  Not sure that I understand the PCLK signal and timing.  What I really have a hard time understanding is the large number of registers / fuses that have to be configured.  I guess I need to examine your code from page 4 again.  Anyway, just bought a SPI display so maybe I will get somewhere soon.

drkblog

The non-FIFO version works with the registers that Mr_Arduino provided, using 16MHz or 8MHz clock. You have to wait for PCLK raising edge and the read one byte from data lines. Then the second byte with the next PCLK raising edge. That portion of code should be really fast, and you have to disable interrupts in the µC for that to work (disable interrupts only when reading the image from the sensor). And you have to configure the cam to slow PCLK enough. If you have 16MHz clock you have to divide it for a bigger number than having an 8MHz clock. If you don't do that you will never be able to read the image with an 16MHz Arduino. Unless (I'm not sure) you configure interrupts for handling PCLK. But even if you do that, you could have a speed problem if PCLK is too fast.

drkblog

#104
Oct 03, 2013, 03:39 am Last Edit: Oct 03, 2013, 05:06 am by drkblog Reason: 1
UPDATE: OV7670 + FIFO is in the end a big disappointment, at least for me.

It is true you can capture a frame in the module's FIFO memory. But you can't read it at any speed you want. AL422B memory datasheet states 1µS as the maximum read cycle time. Which means you can't read less than 1,000,000 bytes per second from the FIFO. Right now I'm testing whether it is possible to read a block, pause and later resume. I'll let you know...

UPDATE II: The OV7670 + FIFO module (three versions checked) have a huge design error. They don't provide access to the /RE pin of the FIFO. Using that pin you can pause reading and then continue, without stopping the RCLK. The other way (pausing RCLK) you get out of sync eventually.

UPDATE III: I can successfully read a block of data from the FIFO optimizing the code in Arduino Mega2560. I get a 1.3MHz clock which is ok for the AL422B. Of course, I'm limited by RAM to a small block of bytes. So reading the next block is hard. The only way is resetting the read pointer and discarding the previous block. Which makes the process slow, and yet I'm missing some byte in between blocks. I need to write the frame to an SD card, so my block size must be 512 bytes, which makes a total of 600 blocks which in turn makes a total of 179,700 skips.

At this point I have three options:

  • Adding 1MB static RAM to Arduino (not easy as far as I know)

  • Cutting the /RE pin from AL422B chip and solder it to a cable (I'm going to burn it)

  • Using a Raspberry Pi instead of Arduino (I really want to use an Arduino, but...)




Go Up