• Post author:
• Post category:Android

Hey there. Not so long ago I bought this OV7670 camera module as it was the cheapest(obviously) module available. I have had this camera module for a while now and a few days back I decided to use it.  Just took out my Uno, googled for “OV7670 Arduino Uno sdcard” . I did get a lot of results but not a simple guide to just take a picture and save it on an SD card. It took a lot of googling and delving into the datasheets and stuff to get this damn thing to work which I DO NOT intend to do again.

So, this is going to be a simple to-the-point guide on how to capture an image with the OV7670 camera module and save it onto an SD card on an Arduino Uno, to save me (or anyone else out there) some time and effort the next time I decide to use it again. I just wanna mention here that the work of user “ComputerNerd” has been a great help so do check that out here. Anyway, Let’s get started.

In this project we are going to capture a QVGA(320×240) image with OV7670 non-FIFO Camera on an Arduino Uno and save it onto an SD card. This has been achieved using the Arduino SD and Wire library.

## Introduction

Camera Module: The OV7670 camera module can be understood as consisting of two parts:
1. SCCB (I2C) Interface
2. Image data Interface

SCCB Interface: This is basically an I2C interface with which one can access all the control registers of the camera which control various aspects of camera operation like white balance, exposure, resolution etc. One needs to write appropriate values to these registers for the camera to work in the desired fashion. We are going to use the Arduino Wire library for this purpose.

Image Data Interface: This is the D0-D7 pinout where the image data is obtained one byte at a time.

SD Card Module: This is a basic SD card adapter module operating at 3.3V. However, an onboard voltage regulator allows us to connect it to Arduino 5V supply. The module communicates with Arduino via its SPI interface. We are going to use the Arduino SD library for this purpose.

Arduino Uno: The very small number of pins on the Uno board makes it a difficult task to use the camera module with SD module. Since most of the pins on Arduino are multiplexed to provide other functions, this doesn’t leave us with much choice over the way we can connect the modules. Another limitation is the small amount of memory(32Kb) on the Atmega328 chip driving Arduino.

## Steps Involved

In order to make this thing work, we have to:

1. Connect the modules according to the schematics.
2. Generate 8mhz XCLK at digital pin 9.
3. Initialize SCCB interface.
4. Reset OV7670 register values.
5. Write Registers for QVGA settings.
6. Write registers for YUV422 settings.
7. Initialize SD module and make sure it is working.
8. Capture one frame raw data to SD card.
9. Write the raw data into a BMP file to obtain the final image.

## XCLK

The camera module requires a system clock input at the pin XCLK. This clock is essential for the SCCB interface to work and for any other camera operation. According to the datasheet, the system clock (XCLK) frequency must be between 10 and 48 MHz although it works fine with 8 MHz clock.Note that this clock is different from the SCCB input clock. We are generating an 8Mhz PWM signal at digital pin 9 of the Arduino board using Arduino timer 1. For this purpose we’ll have to set some bits in TCCR1A, TCCR1B and OCR1A.

TCCR1A – Timer/Counter1 Control Register A.
TCCR1B – Timer/Counter1 Control Register B.
OCR1A – Output Compare Register 1 A.
WGM – Waveform Generation Mode.
COM – Compare Output Mode.

void XCLK_SETUP(void){
pinMode(9, OUTPUT); //Set pin 9 to output

//Initialize timer 1

//WGM13, WGM12, WGM11 & WGM10 bits SET- Fast PWM mode
//COM1A0 SET- Toggle OC1A on compare match
TCCR1A = (1 << COM1A0) | (1 << WGM11) | (1 << WGM10);
//SET CS10 bit for clock select with no prescaling
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS10);
//Output Compare Register 1A(OCR1A) = 0
//This will lead to a match on every clock cycle
//Toggle OC1A output pin on every match instance
//Therefore, the generated waveform will have half
//the frequency of the driving clock i.e. 8Mhz
//OC1A pin- PB1 (alternate functn) pin i.e. Arduino pin 9
OCR1A = 0;

}

## I2C(SCCB) Interface

Each I2C bus consists of two signals: SCL(SIOC) and SDA(SIOD). SCL is the clock signal, and SDA is the data signal. The clock signal is always generated by the master. Some slave devices may force the clock low at times to delay the master sending more data (or to require more time to prepare data before the master attempts to clock it out). Each signal line has a pull-up resistor on it, to restore the signal to high when no device is asserting it low. Since the devices on the bus don’t actually drive the signals high, I2C allows for some flexibility in connecting devices with different I/O voltages.

In general, in a system where one device is at a higher voltage than another, it may be possible to connect the two devices via I2C without any level shifting circuitry in between them. The trick is to connect the pull-up resistors to the lower of the two voltages. This only works in some cases, where the lower of the two system voltages exceeds the high-level input voltage of the higher voltage system–for example, 5V Arduino and a 3.3V OV7670.

## Writing to OV7670 from Arduino

Data is written to the OV7670 Registers in a 3-phase write transmission cycle. The 3-phase write transmission cycle is a full write cycle such that the master can write one byte of data to a specific slave. The 7-bit ID address identifies the specific slave that the master intends to access. The sub-address identifies the register location. The write data contains 8-bit data that the master intends to overwrite the content of this specific address. The 9th bit of the three phases will be Don’t-Care bits.

void WriteOV7670(byte regID, byte regVal){
// Slave 7-bit address is 0x21.
// R/W bit set automatically by Wire functions
// dont write 0x42 or 0x43 for slave address
Wire.beginTransmission(0x21);
// Reset all register values
Wire.write(regID);
Wire.write(regVal);
Wire.endTransmission();
delay(1);
}

The read cycle consists of 2-phase write transmission cycle followed by 2-phase read transmission cycle. The purpose of issuing a 2-phase write transmission cycle is to identify the sub-address of some specific slave from which the master intends to read data for the following 2-phase read transmission cycle. The 9th bit of the two write transmission phases will be Don’t-Care bits.

void ReadOV7670(byte regID){
// Reading from a register is done in two steps
// Step 1: Write register address to the slave
// from which data is to be read.
Wire.endTransmission();

// Step 2: Read 1 byte from Slave
Wire.requestFrom(0x21, 1);
Serial.println(Wire.available());
Serial.print(regID,HEX);
Serial.print(":");
}

## OV7670 Initialization

void Init_OV7670(){
//Reset All Register Values
WriteOV7670(0x12,0x80);
delay(100);
WriteOV7670(0x3A, 0x04); //TSLB

WriteOV7670(0x13, 0xC0); //COM8
WriteOV7670(0x00, 0x00); //GAIN
WriteOV7670(0x10, 0x00); //AECH
WriteOV7670(0x0D, 0x40); //COM4
WriteOV7670(0x14, 0x18); //COM9
WriteOV7670(0x24, 0x95); //AEW
WriteOV7670(0x25, 0x33); //AEB
WriteOV7670(0x13, 0xC5); //COM8
WriteOV7670(0x6A, 0x40); //GGAIN
WriteOV7670(0x01, 0x40); //BLUE
WriteOV7670(0x02, 0x60); //RED
WriteOV7670(0x13, 0xC7); //COM8
WriteOV7670(0x41, 0x08); //COM16
WriteOV7670(0x15, 0x20); //COM10 - PCLK does not toggle on HBLANK
}

## QVGA Initialization

void Init_QVGA(){
WriteOV7670(0x0C, 0x04);//COM3 - Enable Scaling
WriteOV7670(0x3E, 0x19);//COM14
WriteOV7670(0x72, 0x11);//
WriteOV7670(0x73, 0xF1);//
WriteOV7670(0x17, 0x16);//HSTART
WriteOV7670(0x18, 0x04);//HSTOP
WriteOV7670(0x32, 0xA4);//HREF
WriteOV7670(0x19, 0x02);//VSTART
WriteOV7670(0x1A, 0x7A);//VSTOP
WriteOV7670(0x03, 0x0A);//VREF
}

## YUV Initialization

void Init_YUV422(){
WriteOV7670(0x12, 0x00);//COM7
WriteOV7670(0x8C, 0x00);//RGB444
WriteOV7670(0x04, 0x00);//COM1
WriteOV7670(0x40, 0xC0);//COM15
WriteOV7670(0x14, 0x1A);//COM9
WriteOV7670(0x3D, 0x40);//COM13
}

## Receiving Image Bytes

The OV7670 sends the data in a parallel synchronous format. After a clock signal has been applied to the XCLK pin, the OV7670 will start driving its VSYNC, HREF and D0-D7 pins. The falling edge of VSYNC signals the start of a frame, and its rising edge signals the end of a frame. The image format used in this project is QVGA (320 x 240). That means each QVGA frame has 240 rows and each row has 320 pixels. Each row data must be captured during the high state of HREF i.e. D0-D7 must be sampled only when HREF is high. The rising edge of HREF signals the start of a row, and the falling edge of HREF signals the end of the row.

D0-D7 must be sampled at the rising edge of the PCLK signal. All these bytes sampled when HREF was high, correspond to the pixels in one row.

Note that one byte is not a pixel, and in the format chosen i.e. YUV422, two bytes correspond to a pixel where the first byte has luminescence information. The 240 lines, equivalent to a frame, are captured during the low state of VSYNC. During HREF high state, we must capture 320 pixels, equivalent to a line. Now, how fast the data is being sent depends on the frequency of PCLK. By default, the PCLK will have the same frequency of XCLK, however prescalers and PPLs can be configured using the SCCB, to produce a PCLK of different frequency. This is particularly important because writing data to SD card is timeconsuming and not a very fast process. This puts up timing restrictions on how fast data can be sampled. In this project, PCLK has been slowed down by using maximum allowed prescaler bits.

WriteOV7670(0x11, 0x1F); //Range 00-1F

Before running the main code, check if the SD adapter initialization is successful or not. When I ran the main code directly I didn’t get any output on SD card. So I uploaded this test code first to check if the Adapter initialized successfully and after that my code worked. If you run into such problem, just try this once.

#include <SD.h>

int CS_Pin = 10;

void setup() {
// SD setup
Serial.begin(9600);
pinMode(CS_Pin, OUTPUT);
if (SD.begin(CS_Pin)) {
Serial.println("Card Initialization Successful!");
}else{
Serial.println("Card Initialization Failed!");
}

File dataFile = SD.open("test.bmp", FILE_WRITE);

for(int i=0;i<240;i++){
for(int j=0;j<320;j++){
dataFile.write(0x77);
}
}

dataFile.close();
}

void loop(){
}

## Saving Data On SD Card

BYTE 1 captures the luminescence of the image and therefore it is being sampled to obtain a greyscale image. BYTE 2 is being discarded due to memory limitations of the Arduino Uno board. Also, the SD write function is faster than print function so remember to use that. Here a buffer has been used as writing an array at once using write function is more time efficient than writing values one at a time.

void QVGA_Image(String title){
int h,w;

File dataFile = SD.open(title, FILE_WRITE);
while (!(PIND & 8));//wait for high
while ((PIND & 8));//wait for low

h = 240;
while (h--){
w = 320;
byte dataBuffer[320];
while (w--){
while ((PIND & 4)); //wait for low
dataBuffer[319-w] = (PINC & 15) | (PIND & 240);
while (!(PIND & 4)); //wait for high
while ((PIND & 4)); //wait for low
while (!(PIND & 4)); //wait for high
}
dataFile.write(dataBuffer,320);
}
dataFile.close();
delay(100);
}

## Writing A Bitmap Image File

A python script writes the raw image data obtained to a BMP image file. Here’s the python code (thank my friend Hemant for this) that writes the raw pixel data from the SD card to a Bitmap image file.

import csv
import sys
import binascii
csv.field_size_limit(500 * 1024 * 1024)

columnvector = []
with open('data.csv', 'rb') as csvfile:
columnvector.append(row)
'40','01','00','00','F0','00','00','00','01','00','18','00','00','00','00','00','00','84','03','00','C5','00',
'00','00','C5','00','00','00','00','00','00','00','00','00','00','00']

hexArray=[]
for i in range(0,76800):
data = columnvector[0][i]
hexArray.extend([data,data,data])

with open('test.bmp', 'wb') as f:
f.write(binascii.unhexlify(''.join(hexArray)))

The first 54 bytes in a BMP file is the header data that sets the file parameters. All following bytes are pixel data. Each pixel has 3 dedicated bytes for the Blue, Green and Red channels. Therefore to obtain a greyscale image, all 3 bytes are written with the same value. Row size for a BMP image is given by the formula:

$RowSize = Floor(\frac{BitsPerPixel \times ImageWidth + 31)}{32})\times 4$

Each row consists of 1 row of image pixel data plus some padding bytes. In this case where image width is 320 pixels and height is 240 pixels, row size:

$RowSize = Floor(\frac{24 \times 320 + 31)}{32})\times 4 = 960 bytes = 320 \times 3$

Therefore, no padding bytes needed here. The size of a BMP file can be calculated as:

$FileSize = HeaderBytes + ImageHeight \times RowSize$

## Results

Here are some of the images i obtained. Remember to capture a couple of image to get one fine output. The first one or two images are going to be whitewashed as the camera tries to adjust its exposure, gain etc. The source code is available here.

## Limitations in using Arduino Uno with OV7670

1. Few no. of I/O pins and a small amount of memory(32Kb ) on the Arduino Uno board.
2. 8mhz of maximum generated clock speed by the Arduino Uno board which is less than the specified operating range of the OV7670 camera.
3. Slow writing speed to the SD card.

If you are looking to interface your Arduino with a Bluetooth module, check out this project where I control an Arduino powered Rover with my Android phone via Bluetooth.

## References

### This Post Has 87 Comments

1. Hai.. when I init the sd card it was success.. but when I open the file, it was corrupted.

1. Try opening the file in a hex editor and check if the byte data that the Arduino is expected to write is actually there.

1. Tq for the fast reply..
Using code SDcard_Test. I have run the code and open the file write inside sd car using hex editor. It was success
However, when I run OV7670_SD code. Just capture single frame. The file was error after the program have been executed.
One more, how to use the phyton program to convert the file from SD card to image?

1. I don’t quite understand the first part of your problem. The image data that Arduino is going to write to the SD card is raw image data i.e. just plain byte data-one byte for one pixel. If you try to open it as an image file then it won’t work. It is not in proper format to be read as an image. That’s why you need to write a bmp file with proper headers and use the raw image data to fill in for the pixel data in the bmp file. Now, here is the part where I cheated a little bit. I just opened up the file containing raw image data that Arduino wrote and opened it in a hex editor. I copy pasted the data into a text file and fed this text file to the Python code that I used. But you can read the data from the file directly. You just gonna have to tweak the code a little bit. I hope this helps. One more thing, make sure that you have written the correct register values by reading them.
Cheers

1. Kinley

Hi, have you solved your problem.

2. “I don’t quite understand the first part of your problem. The image data that Arduino is going to write to the SD card is raw image data i.e. just plain byte data-one byte for one pixel. If you try to open it as an image file then it won’t work. It is not in proper format to be read as an image. That’s why you need to write a bmp file with proper headers and use the raw image data to fill in for the pixel data in the bmp file. Now, here is the part where I cheated a little bit. I just opened up the file containing raw image data that Arduino wrote and opened it in a hex editor. I copy pasted the data into a text file and fed this text file to the Python code that I used. But you can read the data from the file directly. You just gonna have to tweak the code a little bit. I hope this helps. One more thing, make sure that you have written the correct register values by reading them.”
Cheers
Sorry for my english.
1) “The image data that Arduino is going to write to the SD card is raw image data i.e. just plain byte data-one byte for one pixel.”……. This one I understand. The data should be in byte form. and if I want to open it, I must use a Hex Editor software. The data should be 320×240 of bytes.
However why we save the file in *.bmp?
2) My problem is when I want to copy the finished file from SD card to my laptop so that I can open it with hex editor. The file itself is corrupted. “An unexpected error is keeping you from moving the file. Error 0x80070570 : The File or directory is corrupted and unreadable”. I still google the meaning and solution of 0x80070570
3) Although the data was corrupted. the size is 75kb.. (320×240) / 1024 = 75kb.

2. Hai.. The problem occurs sometime. Im good with it.. currently focuses on changing to VGA resolution and save it as RAW image..

1. Kinley

3. JKT

Hi, how is the camera triggered? Im working with same cameramodule to build a motion sensor triggered security camera, but I cant get the code together. Could you help? ?

4. ali berk

Can you tell me more about translating raw image data with python?
because I did not know how to use python so I could not convert raw image data.

5. Hi Hardik,
Very interesting article. Just a question: when you set the OV7670 to QVGA format, does the camera send you a flow of frames, or can you “capture” only one frame? meaning: do I have to get the data as fast as possible to avoid “movement” of the image, or can I ask the camera to “freeze” the picture in order to give me enought time to transfert it?

1. Hi Pierre.
This camera module sends continuous data and one can’t just ask for “one frame”. Therefore, one needs to look for the start and end pulse of a frame. It sends image data one line at a time, so all the buffering has to be done by the arduino. If you are using arduino uno then this problem gets particularly difficult because uno board doesn’t have enough memory to buffer even one frame of data. So one needs to write the frame data to an SD card as soon as it is available one line at a time. Writing to an SD card is a very slow process and therefore there are chances that one might miss a line or two. Even when you have captured one frame the camera will just keep on sending out the data. So what I would suggest is you capture 8-10 frames and pick the best one, if you are trying to capture a still object. If the object is moving, I don’t think this module will be very useful. If you are using this module for learning purpose, this is a great piece of hardware for that. But if you are working on a project and need to get things done, this module is a lot of pain and the results are not worth the time and effort. But again, if the motto is to learn, this is the best choice because one needs to do all the work in this one. Hopefully this answer was of some help.

Good luck

2. In short, yes you need to get the data as soon as possible to avoid movement.

6. Good TUTORIAL!!!
Great!!
Can I use a button to take picture jpeg
Can you help me with this?
thanks!!

7. Peter Johnson

Just wanted to say thanks for the guide, it was very helpful. Also, I wanted to confirm that this does work, and I did manage to do this myself. Some comments I would add for clarity though:

1) I only managed to get the camera to take an image when I plugged the XCLK pin in directly into the arduino (without the voltage divider), and didn’t connect HREF – so this is something to try if it doesnt work. You can also try switching around the SIOC and SIOD pins, it’s easy to get those mixed up. See: (http://www.instructables.com/id/OV7670-Without-FIFO-Very-Simple-Framecapture-With-/#comment-list) for more help on connecting it all up.

2) If you want to get this to all work remotely (i.e. not plugged into a pc), you can run it from a 9V battery. However, I only got this to work by making the arduino first run the “Initialize SD Adapter” code, before the rest of the code. You can then just click the reset button on the arduino board itself to get it to take images.

3) the image format that comes out is a little difficult to work with. You need to first open the file with a hex editor – i used HxD (it’s free), then copy and paste the data from there. Because colour data was discarded by the code, the image data appears as 76800 pairs of letters/numbers (one pair for each pixel). However, hexidecimal works in 6’s, so you have to take each pair of data and triple it (i.e. FF needs to become FFFFFF). Then, you need to add the image header to make the bitmap. The python code provided tries to do this – it wants you to manually open the image data with HxD, then copy and paste it into the provided csv file. It then tries to take each pair, triple it, then add the header for the bitmap image.

I found this to be quite problematic because there were issues copy and pasting all the data in such that there were no blank spaces etc. which would cause the array in the python code to go out of range. To fix this, I instead put the data into a text file (instead of the csv) and made the python code work with a text file instead. My python code is nearly identical except the start looks like this now:

“”
import csv
import sys
import binascii
csv.field_size_limit(500 * 1024 * 1024)

columnvector = []
text_file = open(“data.txt”,”r”)
columnvector.append(lines)
print(len(columnvector))
“”

All code after this is the same. So first you open the image data with HxD, then copy and paste it into a notepad text file called data.txt, then run the python code.

Good luck to anyone trying this – it took me about 3 evenings to get it all working. Probably, this project is something that shouldn’t be attempted with an arduino, but it was fun to try.

1. Jorge Maranto

8. Hossein Aghaie

Hi,
Is there any way to get a 2D array of pixels (x and y) from the bitmap or jpeg file on the sd which every byte shows the grayscale level of that pixel from 0 to 255? Is arduino capable of making a 320×240 array? If no Is it possible to read every 20×20 square of pixels from the image and turn it into one pixel that has the average grayscale level of the all pixels in it. and then make a 16×12 array from these pixels. in other word resize the image. after I get the array I want to do some processing on it. but I’m weak at programming and I can’t get to this point. If you help me with that it would be a great help!
Another question, How can I just get the grayscale level of a particular pixel?

1. Peter Johnson

The data comes out as hexadecimal. You can convert it to 8bit (0-255), look online. FF = 255, 00 = 0.

9. Hossein Aghaie

Imagine a dot matrix made of many IR sensors which give you only 0 (for white) and 1 (for black). I want to get something like this at the end.

10. johnny

thank you for the explanation. i was able to take pictures but wasn’t able to convert the raw data into bitmap. you skipped the part of how to take the raw image(for example “0.bmp”) and convert it into csv file like the one you give in the example(data.csv). i tried to do it manually in many ways without success…
whenever i run the code on my converted csv file it says column is out of range, so obviously you did something specific in the way you pasted the raw data into the csv.

i was able to see the data with hex editor , change columns number etc…. but was not able to convert it to csv in which your python program might understand.
your post is of great help to the community and i hope you could help me resolve the issue.
thanks..

1. Peter Johnson

The out of range error means there is more data than there is pixels. For me it was some spaces in the data. I got it working by copying all the data to a text file then running the python code on the text file (see my post).

11. michel

hello thanks for your great tuto. I encoutered a trouble with reading the .bmp files . The 8 files does appear on my sd card, but windows ( neither the Gimp, or photofiltre ) can not open them. Have you an idea to help me ?
thanks a lot,
Mich

1. The bmp file that is there on the SD card is not really a bmp file.it doesn’t have the headers of a bmp file so the program doesn’t know how to read it. It is just a file containing bytes corresponding to raw pixel values. You can use this data to create an image file. I’m creating a bmp file and the information on how to do this is there in the tutorial. I used a hex editor to view and copy all the data from the file. I could have done a better job and used Python to read the hex data but I was in a hurry, but you can do that. That would be a better way. Anyway, good luck

1. michel

thanks a lot ! Will try it !

hello Michel can you pls help me how to run phython program in which softare

12. the code is error

13. help please how to use python code to open bmp file…

14. mariko

Hello, thanks for this great tutorial. I have a problem with Serial, because it won’t output anything. Also the files don’t get written on the SD card. Could this be because I am using ethernet shield that has SD card module included?
Mariko

15. Diego

Hi I want to save the photos in RGB565 160×120 format.
It is possible ?? I tried a lot but has not success
Could you help me ??

16. Diego

I was trying to modified the code to save in sd card RGB565 160×120 but I coudn´t.
Could you help me with this ??

17. waqar

can you upload a single .ino file.

18. thank you for the explanation. but I wonder how to take a picture… Dose camera take pictures automatically? or Do I have to take a picture myself?…

1. Lalo

It takes the pictures automatically.

HEY PLS GIVE ME COMBINE PROGRAM OF THIS PLS…………….

anyone who has completed this project pls reply

22. Lalo

Hello, I have already tested your program and circuit, it works fine, at least when receiving data, but when I convert the headecimal data to an actual BMP file, I obtain this: https://www.dropbox.com/preview/test.bmp
And this problem has been present since I started using this module.
I bought other camera and the problem remains, also I have rebiult the circuit many times on different Arduinos.

1. Darshan

Can you pls give me detail about this work how is it happen pls my arduino code is uploaded but what can i do further? Pls tell me pls

1. Lalo

Let your program run on the Arduino. After that you disconnect your Arduino and remove the SD Card from its shield.
After that you put your SD Card in your PC, you must open the “.bmp” files by using a hex editor. You copy all the data into a .csv file and run the python code, that is included.

1. Darshan

Thanx very much

1. Darshan

2. Darshan

Hello pls help. Me ro remove error while it written in python it shiws like has you open it is in text mode

23. hello when I converting the csv file into image I get this error what can I do
Traceback (most recent call last):
_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
[Finished in 0.1s with exit code 1]
[path: C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Users\GAURAV\AppData\Local\Programs\Python\Python36-32\Scripts\;C:\Users\GAURAV\AppData\Local\Programs\Python\Python36-32\;C:\Users\GAURAV\AppData\Local\Microsoft\WindowsApps;;C:\Program Files\Microsoft VS Code\bin]

1. Ner

you can try removing the b in the code
with open(‘data.csv’, “rb”) as csvfile: >> with open(‘data.csv’, “r”) as csvfile:
but then after that i can run the data example file given but i get error when trying to change my own raw data to an image
Traceback (most recent call last):
File “C:\Users\asus\Desktop\OV7670_SDcard\RawDataToImage\csvToVec.py”, line 19, in
data = columnvector[0][i]
IndexError: list index out of range

1. Jeff

i got same problem as the following
data = columnvector[0][i]
IndexError: list index out of range
, did you solve it?

2. Peter Johnson

The out of range error means there is more data than there is pixels. This is likely due to some spaces in the data. I got it working by copying all the data to a text file then running the python code on the text file (see my post)

pls solve my problem anyone

1. Jeff

i got same problem here, did you solve it?

25. Ner

Could anyone advise me why when i convert my raw data to .csv
the file size is different from data example in github folder
data example is 230,399bytes while my .csv file is 230,418bytes
is that what is causing the list index out of range error?
am i suppose to omit some bytes when copying from the hex editor into excel to save as .csv?
If anyone can advise on how to proceed, i would be very grateful.

26. Ner

Yay finally managed to do it! Thanks for the tutorial ! Really appreciate the source code and guide!
Hmm but i dont quite understand why it works for me
but if anyone is facing similar issues as me
1) did u open in text mode error, maybe can consider editing the code abit
2) IndexError: list index out of range error; maybe after converting file using hex editor u can copy into notepad instead of an excel to save to .csv file. That solve my issue which i dont understand why.
(if can anyone had experimented on how to edit the code to work based on a trigger mechanism like a button or threshold value, could you please advise on how to proceed)

27. I am completely new to this field. Can you please help me out that where I am supposed to write this code, the entire code. Is it to be done on Arduino IDE ?

28. I am having some trouble getting the data from the original byte date in the bmp file converted into a hex csv file – can you tell me the program you used which let you convert the data as every hex editor I have tried doesn’t seem to perform correctly.

29. Vivek Srivastava

I’ve done every step successfully except conversion of hex into bmp. Please help. Is there any other way or can you provide video tutorial or image instructions for it.

1. I’ve the same trouble ! ?

30. Nimra

hello sir,

31. Marcin

Dear Hardik.
This is a great guide. Despite many problems, I was able to successfully start the camera and rip the image to the SD card. I introduced a modification, after opening the file, the BMP file header is recorded first, and then the image data. The BMP file is created immediately, which I can display.
However, I have a problem, because instead of a single 320×240 px image, I get an image which in the bottom shows three small images from the camera (one next to the other), and the entire upper part (about 2/3 of the height) is black. (image converted to jpg: https://images89.fotosik.pl/28/e7ddb4037a26f0camed.jpg)
I have read the datasheet and tried to change the values of HSTART, HSTOP, HREF, VSTART, VSTOP and VREF in different combinations, but without success.
What am I doing wrong. Where to find a mistake? I will be grateful for your help.
Best Regards.
Maricn

1. BIMBOU

Hello , can you send me your code pls

2. Jack

Hello,
I have almost the same problem. My images contains two half (120*320) image . ( https://imgur.com/a/sSxKET )
Have you got the solution since that?

3. MartinezB 98

32. Poretzo

Hi, Hardik, your code sample is fully functional, but I do not know what “PIND & 240” means. What pin does it mean?

33. mserkana

I’ve tried all the steps. I checked the circuit many times but I could not run. Is there anyone who can run? I think I can skip things or not. I’ve also tried it with the author’s code, but I’m observing no event

34. Mohamed Saber

Can I make this project on atmega32 microcontroller?

35. Don Juan

Hey is there any way to make it work for a video instead of just taking one picture?

36. amit jain

every thing is ok , i write herader codes in main program, as soon as file is opened , and codes were outside loop and setup, but image is coming like many small images coming in same image, help within 1 or 2 days if possible.

37. amit jain

every thing is ok , i wrote bmp header codes in main program, as soon as file is opened , and codes definition is outside loop and setup, but image is coming like many small images coming in same image, like 6 7 images in one image, help within 1 or 2 days if possible, thank you.
………………………………………………………………..
DDRD &= ~252;
}

{
0x42, 0x4D, 0x36, 0x84, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x84, 0x03, 0x00, 0xC5, 0x00, 0x00, 0x00, 0xC5, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void QVGA_Image(String title){

Hi can you explain more Please
I’m still getting this error.
“did you open the file in text mode?”

38. Thank you for this informative tutorial.
Just a question. As I read the code, I didn’t find any part of code in which “HREF” pin of OV7670 is checked. So what is the point of this pin?

39. Joshua Effendi

Anyone has the full arduino code? I only get white picture only.

40. Hey guys ive tried this tutorial and its not functioning for my device. my connections is ok and i just paste the programs in Arduino IDE what should i do ?

41. Ian Nicky

The camera just follow the time to take a picture, am i rights??? So, if we want to use motion sensor (PIR) as a trigger, can you add the code?? I want the PIR motion sensor adding to this system… thank you

42. joaquim

je comprends bien comment exécuter le script python pour à la fin avoir une image qui peut s’afficher sous un format jpeg par exemple. besoin d’aide svp…

43. joaquim

je comprends pas bien comment exécuter le script python pour passer de fichiers bmp vers les images au format jpeg par exemple. j’ai réalisé toute les étapes et tout s’est bien passé, sauf que j’arrive pas à convertir mes fichiers bmp. besoin d’aide svp…

44. Will Code

Hi, could you please provide us with the complete sketch ? I get serveral errors while running your snippets.
Regards

45. i’m working with the OV7670 module on an altera FPGA Board and i’m encountering some problems wich i cannot solve.
The YCbCr422 encoding is the default format used by the camera module right?
If so what are the exact data position/order that the camera is using on it’s D0-7 pin?
When you explain how the data is stored for the YCbCr format you make a block scheme.
What those blocks represents? Are they Bytes? If so one block would be the information present on D0-7 pins at a certain pclk edge?

46. GaM eR

47. Hi,
I can’t understand how the arduino knows that pictures need to save in “out” folder”?
Btw, I have the same problem: Looking for image.

48. Jorge456

Sorry for my English but, this is functional for Arduino Nano? Tell me, please.

49. In which part of the program is the method “ReadOV7670” invoked?

50. wth

You go to great lengths to explain these stuff to beginners then you go ahead and don’t even put the whole code together… brooo

51. Dian Kusuma

sir i change the conection pins D9 to D3(Xclx) , D2 to D8 (pclk), D3 to D2(Vsync). i have change the piout configurations for these pins but i found the code is stack in the setup in Init_YUV422();… do you have any suggestion? because i need the previous pins for the other device… thanks a lot

52. Xrayer

I don’t understand what code that i should copy onto the Arduino IDE, like in the “void setup” and the” void loop” standard functions. What should i put in the method parameters? ig the “WriteOV7670(byte, byte);”

53. Are you struggling to optimize your website content?
Wednesday at 12 PM (Pacific Time) I will teach you how to ensure you have SEO friendly content with high search volume keywords.
Learn tips, tricks, and tools that work in 2020 that the Google algorithm loves.
Signup here to get the webinar link https://www.eventbrite.com/e/113229598778

54. David

HI, do you have sketch or diagram for arduino mega instead uno?