3

I have an Arduino UNO and OV7670 camera sensor without FIFO. I wanted to build a device, that would take frame once in a while, and would send it through bluetooth (HC-05) or wi-fi (esp-01). I didn't know though, that the microcontroller inside Uno has so little RAM memory, that the frame doesn't fit inside. Moreover, even Arduino Mega has too little memory...

My question is- is there anything I could do to take a VGA-resolution photo (circa 1MB) and send it through any serial medium?

I suppose it'd be some kind of a buffer or memory- I'm asking for references to concrete chips or solutions (like- would it be possible to encode or compress an image on-the-fly)?

8
  • 2
    The first thing you could do is but the camera with the buffer :) The ESP-01 has much more RAM than the Arduino, I don't think its got enough still though. You can buy the FIFO chip that the other version of the camera uses, you could try and retro fit your camera. Commented Apr 18, 2017 at 10:37
  • Oh. Looks like ESP-01 could have enough memory for grayscale or lower resolution frame. It's surprising to find that I could do without Arduino... By 'retrofitting' you mean adding the FIFO manually to the camera circuit? It sounds like a pretty difficult process...
    – Jack L.
    Commented Apr 18, 2017 at 13:28
  • I have a camera with FIFO, one without and a couple of FIFO memory chips. I wasn't sure if I could either attach the FIFO to the camera (I agree sounds horrid) or use the FIFO from the ESP. But then I got distracted and its at the bottom of a heap of electronics somewhere. So I can't tell you which way to go, just offer suggestions. To be honest though, buying a camera with FIFO might be a lot less hassle. Commented Apr 18, 2017 at 15:07
  • Compress on the already belabored Uno/Mega? Nope. If you're okay with grayscale, you don't need 1 MB buffer space. With the YCbCr422 colour space, you can extract only the Y component and need only 640*480 = 307kB buffer for a VGA grayscale image. Commented Apr 26, 2017 at 0:18
  • if it's not a silly question, does the entire image need to be sent in a single transaction? i believe with i2c you could issue the command to capture, and then read back chunks at a time (that fit within your RAM) send those chunks, then repeat until no image data left to retrieve?
    – James Kent
    Commented Apr 27, 2017 at 14:31

2 Answers 2

3
+50

If you're okay with grayscale, you don't need 1 MB buffer space. With the YUV422 colour space, you can extract only the Y component and need only 640*480 = 307kB buffer for a VGA grayscale image.

However, according to this, you can set the hardware serial baud rate to 1M-baud and transmit the image bytes as you receive them without buffering. main() shows how to set up the serial port and you can also see how they received each VGA pixel byte in Bayer-RGB and transmitted immediately; notice that all interrupts are disabled first, given the high-speed nature of the transfer. But instead of Bayer, I'd recommend you use YUV422 instead, meaning the camera sends 2 bytes per pixel. Because you're only interested in the Y byte, you can place that in the UART buffer and use the time spent in receiving (and discarding) the second U/V byte to give the UART peripheral some additional breathing room to send the Y byte, before you send the next one.

Regarding the high baud rate, the crystal frequency of the Arduino doesn't matter so much because you'll only be transmitting to your PC, which should be able to handle the speed even given the rate error. Note that in main(), double speed async is enabled, and UBRR is set to 500 kBaud to obtain 1-Mbaud. Also notice that an 8MHz PWM signal was used to clock the camera (XCLK signal) with no PLLs activated in the camera register settings. This is another tutorial related to the same code; may clear up a few things.

If you really want to use a chip solution, you can look up parallel SRAM like the HM628128; it's only 128kB though, you'll need to find a bigger one to hold an entire frame of 307kB. Parallel SRAM are great because you can attain really high write speeds because of the simple interface. You'll need some sort of counter connected to the SRAM address lines clocked by the PCLK line (divided by 2, since you only want every other byte) so that every pulse increments the address. This same clock will feed the nW signal to actually clock the data into the SRAM (after satisfying address setup times somehow). The camera data lines will be connected directly to the SRAM and you activate the SRAM's chip select signal based on your monitoring of the camera's VSYNC signal (to know when a new frame's about to start). When the frame's done, you read from the RAM and forward the bytes to your destination.

All this assumes you aren't trying for video, merely taking frames "once in a while". Though the first solution will work for video, albeit poor video.

1

You need to add a FIFO buffer to the camera, or work out a scheme for streaming data from the camera over the network, because you don't have anywhere enough memory to store the image.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.