Arduino Forum

Using Arduino => Sensors => Topic started by: matanbright on Mar 17, 2018, 07:02 pm

Title: [SOLVED] Problem with camera module OV7670
Post by: matanbright on Mar 17, 2018, 07:02 pm
Hello,

I have Arduino MEGA 2560 and camera module OV7670.

The camera module doesn't work!

I have tried the following tutorials:
http://www.instructables.com/id/OV7670-Without-FIFO-Very-Simple-Framecapture-With-/ (http://www.instructables.com/id/OV7670-Without-FIFO-Very-Simple-Framecapture-With-/)
http://www.instructables.com/id/OV7670-Arduino-Camera-Sensor-Module-Framecapture-T/ (http://www.instructables.com/id/OV7670-Arduino-Camera-Sensor-Module-Framecapture-T/)
https://forum.arduino.cc/index.php?topic=159557.0 (https://forum.arduino.cc/index.php?topic=159557.0)
https://create.arduino.cc/projecthub/tech-duino/visual-capturing-with-ov7670-on-arduino-069ebb (https://create.arduino.cc/projecthub/tech-duino/visual-capturing-with-ov7670-on-arduino-069ebb)
These tutorials are for the Arduino UNO and I have changed the DDRx, PORTx and PINx values so it will match the pins on the Arduino MEGA, but it is not working!

I think that the camera module is fake, because it doesn't look like in the pictures from the internet:
(https://i.imgur.com/6S5FcwF.png)

Please help me! Thank you.
Title: Re: Problem with camera module OV7670
Post by: falexandru on Mar 20, 2018, 08:50 pm
I have one similar to the internet one.

I did not un-seal it by now (scheduled for a later stage of the project). But I brought it from a commercial reputable and reliable source in my country. So, from the appearance, the one in the image on the right is the same to the one that I have,

It does not mean that the left one is a fake, according to my knowledge.

Could be a basic/simplified version.

What do you mean by "does not work"? The code does not compile? The camera does not send anthing to the board?

I have no idea about the camera as such, but many times I wired incorrectly or the jumpers do not contact.
Title: Re: Problem with camera module OV7670
Post by: matanbright on Mar 21, 2018, 08:55 pm
Ok, finally it is working, so it is not a fake module  :) .
It was not working because I forgot to change some timer registers values that work on the Arduino UNO but not on the Arduino MEGA. Now the timer generates 8MHz PWM signal for the Master Clock of the OV7670 and I am able to capture frames.


But I still have a problem!
I can't modify the camera registers.
The camera is connected to the Arduino SCL and SDA pins, and the communications with the camera registers is done via I2C protocol.

As far as I know, the camera communicates via SCCB protocol, that can be implemented via the I2C protocol.
For writing value to a camera register:
1) The Arduino starts a I2C transmission to the camera.
2) The Arduino sends a byte representing the ID of the register that we want to modify its value.
3) The Arduino sends a byte representing the value to write to the register.
4) The Arduino ends the I2C transmission.
Here is my code for writing value to a register:
Code: [Select]
void writeCameraRegister(byte registerId, byte registerValue) {
  Wire.beginTransmission(0x42);
  Wire.write(registerId);
  Wire.write(registerValue);
  Wire.endTransmission();
}

For reading value from a camera register:
1) The Arduino starts a I2C transmission to the camera.
2) The Arduino sends a byte representing the ID of the register that we want to read its value.
3) The Arduino ends the I2C transmission.
4) The Camera sends to the Arduino the value of the register.
Here is my code for reading value from a register:
Code: [Select]
byte readCameraRegister(byte registerId) {
  Wire.beginTransmission(0x42);
  Wire.write(registerId);
  Wire.endTransmission();
  Wire.requestFrom(0x43, 1);
  return Wire.read();
}


According to the OV7670 datasheet, the slave addresses of the camera are: 0x42 for writing and 0x43 for reading. But when I try to read a value from a register, the camera doesn't respond to the request.
I send to the camera the ID of the register I want to read its value, but the camera doesn't send me back the value.

I tried to run a code that tries all the possible addresses for I2C devices and prints if an address starts a connection successfully, but none of the address started a connection, so it means that there is a problem with the camera's I2C connection with the Arduino.
The code is from here: https://playground.arduino.cc/Main/I2cScanner (https://playground.arduino.cc/Main/I2cScanner)

Please help me! Thank you.
Title: Re: Problem with camera module OV7670
Post by: matanbright on Mar 28, 2018, 05:13 pm
Ok, finally after all my tries it works perfect!  :)
Now I can modify the camera registers and I can take pictures and videos from the camera with my Arduino MEGA without any problems!

In the beginning it was not worked for me because I have tried a code that was for the Arduino UNO, so I forgot to change some of the registers names and values in order that they will be compatible with the Arduino MEGA (I mean to the DDRx, PORTx and PINx registers) and in addition, the Arduino MEGA has different pins associated with each PWM timer so I forgot to change the pin to be compatible with the timer used in the code (I mean to the OCRxA registers associated pins).

Then, I had problem with communicating with the camera registers. I could not communicate with the registers because I have used the write address (0x42) and the read address (0x43) of the camera in the "Wire.beginTransmitting" and "Wire.requestFrom" functions. These addresses contain the read/write bit for the I2C:
0x42 --> 1000010
0x43 --> 1000011
But the I2C functions need the address without the read/write bit because they handle the read/write adresses automatically.
So if we shift the bits of the read/write addresses to the right once (1000010 >> 1) we will get the address without the read/write bit: 0x21 (1000010 >> 1 = 0100001).
So when I write the address 0x21 in the I2C functions it works!
Code: [Select]
Wire.beginTransmission(0x21);
Wire.requestFrom(0x21, 1);

Please note that the camera needs a PWM signal at the master clock pin (MCLK or XCLK) even for the communication via the I2C with the Arduino. Without the master clock signal, the camera will not work at all! Because of that, when I tried the code that tries all the possible addresses for I2C devices, even when it tried the address 0x21, the communication didn't work!


So the problem has been solved!  :)
Title: Re: Problem with camera module OV7670
Post by: zoomx on Mar 28, 2018, 11:13 pm
Maybe can you share your sketch?
Title: Re: Problem with camera module OV7670
Post by: matanbright on Mar 29, 2018, 10:29 pm
Here is my sketch and the connections.
The sketch is for capturing grayscale images (because it is easier).
For receiving images you will need to install the software from one of the tutorials from the first post.

(https://i.imgur.com/KyPlsRB.png)

Code: [Select]
// Pins configurations:
// SDA/SIOD ---> pin A4 (for Arduino UNO) | pin 20/SDA (for Arduino MEGA)
// SCL/SIOC ---> pin A5 (for Arduino UNO) | pin 21/SCL (for Arduino MEGA)
// MCLK/XCLK --> pin 11 (for Arduino UNO) | pin 10 (for Arduino MEGA)
// PCLK -------> pin 2
// VS/VSYNC ---> pin 3
// HS/HREF ----> pin 8
// D0 ---------> pin A0
// D1 ---------> pin A1
// D2 ---------> pin A2
// D3 ---------> pin A3
// D4 ---------> pin 4
// D5 ---------> pin 5
// D6 ---------> pin 6
// D7 ---------> pin 7

#include <Wire.h>

#define CAMERA_ADDRESS 0x21

// Definitions of functions for manipulating the Arduino boards pins according to each Arduino board registers, so the code will work for both Arduino UNO and Arduino MEGA:
// The only change is the connections of the SDA/SIOD, SCL/SIOC and MCLK/XCLK pins to each board (see the pins configurations above).
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) // If you are using Arduino MEGA the IDE will automatically define the "__AVR_ATmega1280__" or "__AVR_ATmega2560__" constants.
#define TIMER2_PWM_A_PIN_MODE_OUTPUT() ({ DDRB |= 0b00010000; })
#define PIN2_DIGITAL_READ() ({ (PINE & 0b00010000) == 0 ? LOW : HIGH; })
#define PIN3_DIGITAL_READ() ({ (PINE & 0b00100000) == 0 ? LOW : HIGH; })
#define PIN4_DIGITAL_READ() ({ (PING & 0b00100000) == 0 ? LOW : HIGH; })
#define PIN5_DIGITAL_READ() ({ (PINE & 0b00001000) == 0 ? LOW : HIGH; })
#define PIN6_DIGITAL_READ() ({ (PINH & 0b00001000) == 0 ? LOW : HIGH; })
#define PIN7_DIGITAL_READ() ({ (PINH & 0b00010000) == 0 ? LOW : HIGH; })
#define PIN8_DIGITAL_READ() ({ (PINH & 0b00100000) == 0 ? LOW : HIGH; })
#define PINA0_DIGITAL_READ() ({ (PINF & 0b00000001) == 0 ? LOW : HIGH; })
#define PINA1_DIGITAL_READ() ({ (PINF & 0b00000010) == 0 ? LOW : HIGH; })
#define PINA2_DIGITAL_READ() ({ (PINF & 0b00000100) == 0 ? LOW : HIGH; })
#define PINA3_DIGITAL_READ() ({ (PINF & 0b00001000) == 0 ? LOW : HIGH; })
#elif defined(__AVR_ATmega328P__) // If you are using Arduino UNO the IDE will automatically define the "__AVR_ATmega328P__" constant.
#define TIMER2_PWM_A_PIN_MODE_OUTPUT() ({ DDRB |= 0b00001000; })
#define PIN2_DIGITAL_READ() ({ (PIND & 0b00000100) == 0 ? LOW : HIGH; })
#define PIN3_DIGITAL_READ() ({ (PIND & 0b00001000) == 0 ? LOW : HIGH; })
#define PIN4_DIGITAL_READ() ({ (PIND & 0b00010000) == 0 ? LOW : HIGH; })
#define PIN5_DIGITAL_READ() ({ (PIND & 0b00100000) == 0 ? LOW : HIGH; })
#define PIN6_DIGITAL_READ() ({ (PIND & 0b01000000) == 0 ? LOW : HIGH; })
#define PIN7_DIGITAL_READ() ({ (PIND & 0b10000000) == 0 ? LOW : HIGH; })
#define PIN8_DIGITAL_READ() ({ (PINB & 0b00000001) == 0 ? LOW : HIGH; })
#define PINA0_DIGITAL_READ() ({ (PINC & 0b00000001) == 0 ? LOW : HIGH; })
#define PINA1_DIGITAL_READ() ({ (PINC & 0b00000010) == 0 ? LOW : HIGH; })
#define PINA2_DIGITAL_READ() ({ (PINC & 0b00000100) == 0 ? LOW : HIGH; })
#define PINA3_DIGITAL_READ() ({ (PINC & 0b00001000) == 0 ? LOW : HIGH; })
#endif


void initializePWMTimer() {
  cli();
  TIMER2_PWM_A_PIN_MODE_OUTPUT(); // Set the A PWM pin of TIMER2 to output
  ASSR &= ~(_BV(EXCLK) | _BV(AS2));
  TCCR2A = (1 << COM2A0) | (1 << WGM21) | (1 << WGM20);
  TCCR2B = (1 << WGM22) | (1 << CS20);
  OCR2A = 0;
  sei();
}

byte readCameraRegister(byte registerId) {
  Wire.beginTransmission(CAMERA_ADDRESS);
  Wire.write(registerId);
  Wire.endTransmission();
  Wire.requestFrom(CAMERA_ADDRESS, 1);
  while (Wire.available() <= 0);
  byte registerValue = Wire.read();
  delay(1);
  return registerValue;
}

void writeCameraRegister(byte registerId, byte registerValue) {
  Wire.beginTransmission(CAMERA_ADDRESS);
  Wire.write(registerId);
  Wire.write(registerValue);
  Wire.endTransmission();
  delay(1);
}

void captureFrame(unsigned int frameWidth, unsigned int frameHeight) {
  Serial.print("*RDY*"); // send to the frame capture software a "start of frame" message for beginning capturing

  delay(1000);

  cli(); // disable all interrupts during frame capture (because it needs to be as fast as possible)
  while (PIN3_DIGITAL_READ() == LOW); // wait until VS/VSYNC pin is high
  while (PIN3_DIGITAL_READ() == HIGH); // wait until VS/VSYNC pin is low
  unsigned int tempWidth = 0;
  while (frameHeight--) {
    tempWidth = frameWidth;
    while (tempWidth--) {
      while (PIN2_DIGITAL_READ() == LOW); // wait until PCLK pin is high
      while (PIN2_DIGITAL_READ() == HIGH); // wait until PCLK pin is low
      byte byteToWrite = 0b00000000;
      byteToWrite |= ((PIN7_DIGITAL_READ() == HIGH) << 7);
      byteToWrite |= ((PIN6_DIGITAL_READ() == HIGH) << 6);
      byteToWrite |= ((PIN5_DIGITAL_READ() == HIGH) << 5);
      byteToWrite |= ((PIN4_DIGITAL_READ() == HIGH) << 4);
      byteToWrite |= ((PINA3_DIGITAL_READ() == HIGH) << 3);
      byteToWrite |= ((PINA2_DIGITAL_READ() == HIGH) << 2);
      byteToWrite |= ((PINA1_DIGITAL_READ() == HIGH) << 1);
      byteToWrite |= ((PINA0_DIGITAL_READ() == HIGH));
      UDR0 = byteToWrite; // send data via serial connection with UART register (we need to use the serial register directly for fast transfer)
      while (PIN2_DIGITAL_READ() == LOW); // wait until PCLK pin is high
      while (PIN2_DIGITAL_READ() == HIGH); // wait until PCLK pin is low
      // ignore each second byte (for a grayscale image we only need each first byte, which represents luminescence)
    }
  }
  sei(); // enable all interrupts
  
  delay(1000);
}


void setup() {
  initializePWMTimer();
  Wire.begin();
  Serial.begin(1000000); // the frame capture software communicates with the Arduino at a baud rate of 1MHz
}

void loop() {
  captureFrame(320, 240); // capture a frame at QVGA resolution (320 x 240)
}
Title: Re: Problem with camera module OV7670
Post by: matanbright on Mar 29, 2018, 10:36 pm
If you can't get a good image from the camera, you can try to set its registers to common values.
Put this method in the sketch and call it at the end of the "setup" function.

Code: [Select]
void initializeCamera() {
  // these are common registers values for initializing the camera to QVGA (320 x 240) mode at the maximum clock prescaler:
  writeCameraRegister(0x12, 0x80); // reset all camera registers to default value
  delay(1000); // wait for reset proccess to be done (because it is quite slow)
  writeCameraRegister(0x3A, 0x04);
  writeCameraRegister(0x12, 0x00);
  writeCameraRegister(0x17, 0x13);
  writeCameraRegister(0x18, 0x01);
  writeCameraRegister(0x32, 0xB6);
  writeCameraRegister(0x19, 0x02);
  writeCameraRegister(0x1A, 0x7A);
  writeCameraRegister(0x03, 0x0A);
  writeCameraRegister(0x0C, 0x00);
  writeCameraRegister(0x3E, 0x00);
  writeCameraRegister(0x70, 0x3A);
  writeCameraRegister(0x71, 0x35);
  writeCameraRegister(0x72, 0x11);
  writeCameraRegister(0x73, 0xF0);
  writeCameraRegister(0xA2, 0x01);
  writeCameraRegister(0x15, 0x00);
  writeCameraRegister(0x7A, 0x20);
  writeCameraRegister(0x7B, 0x10);
  writeCameraRegister(0x7C, 0x1E);
  writeCameraRegister(0x7D, 0x35);
  writeCameraRegister(0x7E, 0x5A);
  writeCameraRegister(0x7F, 0x69);
  writeCameraRegister(0x80, 0x76);
  writeCameraRegister(0x81, 0x80);
  writeCameraRegister(0x82, 0x88);
  writeCameraRegister(0x83, 0x8F);
  writeCameraRegister(0x84, 0x96);
  writeCameraRegister(0x85, 0xA3);
  writeCameraRegister(0x86, 0xAF);
  writeCameraRegister(0x87, 0xC4);
  writeCameraRegister(0x88, 0xD7);
  writeCameraRegister(0x89, 0xE8);
  writeCameraRegister(0x13, 0xC0);
  writeCameraRegister(0x00, 0x00);
  writeCameraRegister(0x10, 0x00);
  writeCameraRegister(0x0D, 0x40);
  writeCameraRegister(0x14, 0x18);
  writeCameraRegister(0xA5, 0x05);
  writeCameraRegister(0xAB, 0x07);
  writeCameraRegister(0x24, 0x95);
  writeCameraRegister(0x25, 0x33);
  writeCameraRegister(0x26, 0xE3);
  writeCameraRegister(0x9F, 0x78);
  writeCameraRegister(0xA0, 0x68);
  writeCameraRegister(0xA1, 0x03);
  writeCameraRegister(0xA6, 0xD8);
  writeCameraRegister(0xA7, 0xD8);
  writeCameraRegister(0xA8, 0xF0);
  writeCameraRegister(0xA9, 0x90);
  writeCameraRegister(0xAA, 0x94);
  writeCameraRegister(0x13, 0xC5);
  writeCameraRegister(0x30, 0x00);
  writeCameraRegister(0x31, 0x00);
  writeCameraRegister(0x0E, 0x61);
  writeCameraRegister(0x0F, 0x4B);
  writeCameraRegister(0x16, 0x02);
  writeCameraRegister(0x1E, 0x07);
  writeCameraRegister(0x21, 0x02);
  writeCameraRegister(0x22, 0x91);
  writeCameraRegister(0x29, 0x07);
  writeCameraRegister(0x33, 0x0B);
  writeCameraRegister(0x35, 0x0B);
  writeCameraRegister(0x37, 0x1D);
  writeCameraRegister(0x38, 0x71);
  writeCameraRegister(0x39, 0x2A);
  writeCameraRegister(0x3C, 0x78);
  writeCameraRegister(0x4D, 0x40);
  writeCameraRegister(0x4E, 0x20);
  writeCameraRegister(0x69, 0x00);
  writeCameraRegister(0x74, 0x10);
  writeCameraRegister(0x8D, 0x4F);
  writeCameraRegister(0x8E, 0x00);
  writeCameraRegister(0x8F, 0x00);
  writeCameraRegister(0x90, 0x00);
  writeCameraRegister(0x91, 0x00);
  writeCameraRegister(0x96, 0x00);
  writeCameraRegister(0x9A, 0x00);
  writeCameraRegister(0xB0, 0x84);
  writeCameraRegister(0xB1, 0x0C);
  writeCameraRegister(0xB2, 0x0E);
  writeCameraRegister(0xB3, 0x82);
  writeCameraRegister(0xB8, 0x0A);
  writeCameraRegister(0x43, 0x0A);
  writeCameraRegister(0x44, 0xF0);
  writeCameraRegister(0x45, 0x34);
  writeCameraRegister(0x46, 0x58);
  writeCameraRegister(0x47, 0x28);
  writeCameraRegister(0x48, 0x3A);
  writeCameraRegister(0x59, 0x88);
  writeCameraRegister(0x5A, 0x88);
  writeCameraRegister(0x5B, 0x44);
  writeCameraRegister(0x5C, 0x67);
  writeCameraRegister(0x5D, 0x49);
  writeCameraRegister(0x5E, 0x0E);
  writeCameraRegister(0x6C, 0x0A);
  writeCameraRegister(0x6D, 0x55);
  writeCameraRegister(0x6E, 0x11);
  writeCameraRegister(0x6F, 0x9E);
  writeCameraRegister(0x6A, 0x40);
  writeCameraRegister(0x01, 0x40);
  writeCameraRegister(0x02, 0x60);
  writeCameraRegister(0x13, 0xC7);
  writeCameraRegister(0x4F, 0x80);
  writeCameraRegister(0x50, 0x80);
  writeCameraRegister(0x51, 0x00);
  writeCameraRegister(0x52, 0x22);
  writeCameraRegister(0x53, 0x5E);
  writeCameraRegister(0x54, 0x80);
  writeCameraRegister(0x58, 0x9E);
  writeCameraRegister(0x41, 0x08);
  writeCameraRegister(0x3F, 0x00);
  writeCameraRegister(0x75, 0x05);
  writeCameraRegister(0x76, 0xE1);
  writeCameraRegister(0x4C, 0x00);
  writeCameraRegister(0x77, 0x01);
  writeCameraRegister(0x3D, 0x48);
  writeCameraRegister(0x4B, 0x09);
  writeCameraRegister(0xC9, 0x60);
  writeCameraRegister(0x56, 0x40);
  writeCameraRegister(0x34, 0x11);
  writeCameraRegister(0x3B, 0x12);
  writeCameraRegister(0xA4, 0x82);
  writeCameraRegister(0x96, 0x00);
  writeCameraRegister(0x97, 0x30);
  writeCameraRegister(0x98, 0x20);
  writeCameraRegister(0x99, 0x30);
  writeCameraRegister(0x9A, 0x84);
  writeCameraRegister(0x9B, 0x29);
  writeCameraRegister(0x9C, 0x03);
  writeCameraRegister(0x9D, 0x4C);
  writeCameraRegister(0x9E, 0x3F);
  writeCameraRegister(0x78, 0x04);
  writeCameraRegister(0x79, 0x01);
  writeCameraRegister(0xC8, 0xF0);
  writeCameraRegister(0x79, 0x0F);
  writeCameraRegister(0xC8, 0x00);
  writeCameraRegister(0x79, 0x10);
  writeCameraRegister(0xC8, 0x7E);
  writeCameraRegister(0x79, 0x0A);
  writeCameraRegister(0xC8, 0x80);
  writeCameraRegister(0x79, 0x0B);
  writeCameraRegister(0xC8, 0x01);
  writeCameraRegister(0x79, 0x0C);
  writeCameraRegister(0xC8, 0x0F);
  writeCameraRegister(0x79, 0x0D);
  writeCameraRegister(0xC8, 0x20);
  writeCameraRegister(0x79, 0x09);
  writeCameraRegister(0xC8, 0x80);
  writeCameraRegister(0x79, 0x02);
  writeCameraRegister(0xC8, 0xC0);
  writeCameraRegister(0x79, 0x03);
  writeCameraRegister(0xC8, 0x40);
  writeCameraRegister(0x79, 0x05);
  writeCameraRegister(0xC8, 0x30);
  writeCameraRegister(0x79, 0x26);
  writeCameraRegister(0xFF, 0xFF);
  writeCameraRegister(0x15, 0x20);
  writeCameraRegister(0x0C, 0x04);
  writeCameraRegister(0x3E, 0x19);
  writeCameraRegister(0x72, 0x11);
  writeCameraRegister(0x73, 0xF1);
  writeCameraRegister(0x17, 0x16);
  writeCameraRegister(0x18, 0x04);
  writeCameraRegister(0x32, 0xA4);
  writeCameraRegister(0x19, 0x02);
  writeCameraRegister(0x1A, 0x7A);
  writeCameraRegister(0x03, 0x0A);
  writeCameraRegister(0xFF, 0xFF);
  writeCameraRegister(0x12, 0x00);
  writeCameraRegister(0x8C, 0x00);
  writeCameraRegister(0x04, 0x00);
  writeCameraRegister(0x40, 0xC0);
  writeCameraRegister(0x14, 0x6A);
  writeCameraRegister(0x4F, 0x80);
  writeCameraRegister(0x50, 0x80);
  writeCameraRegister(0x51, 0x00);
  writeCameraRegister(0x52, 0x22);
  writeCameraRegister(0x53, 0x5E);
  writeCameraRegister(0x54, 0x80);
  writeCameraRegister(0x3D, 0x40);
  writeCameraRegister(0xFF, 0xFF);
  writeCameraRegister(0x11, 0x1F);
  writeCameraRegister(0x0C, 0x08);
  writeCameraRegister(0x3E, 0x19);
  writeCameraRegister(0x73, 0xF1);
  writeCameraRegister(0x12, 0x10);
  delay(1000); // wait for registers to be set (because it is quite slow)
}
Title: Re: Problem with camera module OV7670
Post by: ieee488 on Mar 29, 2018, 10:54 pm
What can you do with this camera module?


Seems very interesting!


Title: Re: Problem with camera module OV7670
Post by: matanbright on Mar 31, 2018, 11:28 am
You can take pictures and videos in various resolutions and fps (frames per second).
You can change the camera's settings (resolution, format, clock speed, brightness, contrast and more...) via the I2C connection.
Title: Re: Problem with camera module OV7670
Post by: ieee488 on Mar 31, 2018, 11:43 pm
Thank you.

What you using this camera for ?


I am trying to decide whether I should buy one.
Title: Re: Problem with camera module OV7670
Post by: zoomx on Apr 01, 2018, 09:33 am
Thanks matanbright!
Can you modify the topic title adding [Solved]?
This way many other users can find this topic.
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: matanbright on Apr 02, 2018, 11:13 am
Thanks matanbright!
Can you modify the topic title adding [Solved]?
This way many other users can find this topic.
Yes, I did. Thank you!
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: matanbright on Apr 02, 2018, 11:39 am
Thank you.

What you using this camera for ?


I am trying to decide whether I should buy one.
I am using it for taking small pictures and streaming small videos.

Please note that the Arduino is not intended for capturing frames because it doesn't have enough proccessing power for capturing all the pixels of the frames because it is quite slow and the frame capture proccess needs to be fast.
So with the Arduino you can capture images at low resolution and videos at low FPS (frames per second) rate, so the Arduino will be able to proccess it faster. So don't expect it to take pictures at high resolution and video at high FPS rate.

Please note that the camera has a version with a thing called FIFO. It is a hardware stack that keeps the frames data from the camera in FIFO order (first in first out), so the Arduino will be able to take them out from the stack at its own time.
I have the version without the FIFO, so I don't have experience with it.

I will recommend the camera if you want to try it and learn about it, and if you want to take small images and videos.
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: ieee488 on Apr 02, 2018, 08:44 pm
Thank you.

Seems very interesting device to try and learn.    :)




.
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: falexandru on Apr 15, 2018, 06:30 am
Is there any way to bookmark threads?
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: juma_yetu on Apr 15, 2018, 06:44 am
Kudos to metanbright for taking the trouble to document this in the spirit of helping others.

Title: Re: [SOLVED] Problem with camera module OV7670
Post by: falexandru on Apr 15, 2018, 06:52 am
Agree. Great work, @metanbright!
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: EmDG on Apr 29, 2018, 08:47 pm
Hello, Thanks for this guide. I've been able to get the camera to work. However, i get scrambled images. I've added the "initializeCamera()" code but it doesn't fix the problem. How do i resolve this? Thanks.
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: Omany on May 03, 2018, 06:34 pm
If you can't get a good image from the camera, you can try to set its registers to common values.
Put this method in the sketch and call it at the end of the "setup" function.

Code: [Select]
void initializeCamera() {
  // these are common registers values for initializing the camera to QVGA (320 x 240) mode at the maximum clock prescaler:
  writeCameraRegister(0x12, 0x80); // reset all camera registers to default value
  delay(1000); // wait for reset proccess to be done (because it is quite slow)
  writeCameraRegister(0x3A, 0x04);
  writeCameraRegister(0x12, 0x00);
  writeCameraRegister(0x17, 0x13);
  writeCameraRegister(0x18, 0x01);
  writeCameraRegister(0x32, 0xB6);
  writeCameraRegister(0x19, 0x02);
  writeCameraRegister(0x1A, 0x7A);
  writeCameraRegister(0x03, 0x0A);
  writeCameraRegister(0x0C, 0x00);
  writeCameraRegister(0x3E, 0x00);
  writeCameraRegister(0x70, 0x3A);
  writeCameraRegister(0x71, 0x35);
  writeCameraRegister(0x72, 0x11);
  writeCameraRegister(0x73, 0xF0);
  writeCameraRegister(0xA2, 0x01);
  writeCameraRegister(0x15, 0x00);
  writeCameraRegister(0x7A, 0x20);
  writeCameraRegister(0x7B, 0x10);
  writeCameraRegister(0x7C, 0x1E);
  writeCameraRegister(0x7D, 0x35);
  writeCameraRegister(0x7E, 0x5A);
  writeCameraRegister(0x7F, 0x69);
  writeCameraRegister(0x80, 0x76);
  writeCameraRegister(0x81, 0x80);
  writeCameraRegister(0x82, 0x88);
  writeCameraRegister(0x83, 0x8F);
  writeCameraRegister(0x84, 0x96);
  writeCameraRegister(0x85, 0xA3);
  writeCameraRegister(0x86, 0xAF);
  writeCameraRegister(0x87, 0xC4);
  writeCameraRegister(0x88, 0xD7);
  writeCameraRegister(0x89, 0xE8);
  writeCameraRegister(0x13, 0xC0);
  writeCameraRegister(0x00, 0x00);
  writeCameraRegister(0x10, 0x00);
  writeCameraRegister(0x0D, 0x40);
  writeCameraRegister(0x14, 0x18);
  writeCameraRegister(0xA5, 0x05);
  writeCameraRegister(0xAB, 0x07);
  writeCameraRegister(0x24, 0x95);
  writeCameraRegister(0x25, 0x33);
  writeCameraRegister(0x26, 0xE3);
  writeCameraRegister(0x9F, 0x78);
  writeCameraRegister(0xA0, 0x68);
  writeCameraRegister(0xA1, 0x03);
  writeCameraRegister(0xA6, 0xD8);
  writeCameraRegister(0xA7, 0xD8);
  writeCameraRegister(0xA8, 0xF0);
  writeCameraRegister(0xA9, 0x90);
  writeCameraRegister(0xAA, 0x94);
  writeCameraRegister(0x13, 0xC5);
  writeCameraRegister(0x30, 0x00);
  writeCameraRegister(0x31, 0x00);
  writeCameraRegister(0x0E, 0x61);
  writeCameraRegister(0x0F, 0x4B);
  writeCameraRegister(0x16, 0x02);
  writeCameraRegister(0x1E, 0x07);
  writeCameraRegister(0x21, 0x02);
  writeCameraRegister(0x22, 0x91);
  writeCameraRegister(0x29, 0x07);
  writeCameraRegister(0x33, 0x0B);
  writeCameraRegister(0x35, 0x0B);
  writeCameraRegister(0x37, 0x1D);
  writeCameraRegister(0x38, 0x71);
  writeCameraRegister(0x39, 0x2A);
  writeCameraRegister(0x3C, 0x78);
  writeCameraRegister(0x4D, 0x40);
  writeCameraRegister(0x4E, 0x20);
  writeCameraRegister(0x69, 0x00);
  writeCameraRegister(0x74, 0x10);
  writeCameraRegister(0x8D, 0x4F);
  writeCameraRegister(0x8E, 0x00);
  writeCameraRegister(0x8F, 0x00);
  writeCameraRegister(0x90, 0x00);
  writeCameraRegister(0x91, 0x00);
  writeCameraRegister(0x96, 0x00);
  writeCameraRegister(0x9A, 0x00);
  writeCameraRegister(0xB0, 0x84);
  writeCameraRegister(0xB1, 0x0C);
  writeCameraRegister(0xB2, 0x0E);
  writeCameraRegister(0xB3, 0x82);
  writeCameraRegister(0xB8, 0x0A);
  writeCameraRegister(0x43, 0x0A);
  writeCameraRegister(0x44, 0xF0);
  writeCameraRegister(0x45, 0x34);
  writeCameraRegister(0x46, 0x58);
  writeCameraRegister(0x47, 0x28);
  writeCameraRegister(0x48, 0x3A);
  writeCameraRegister(0x59, 0x88);
  writeCameraRegister(0x5A, 0x88);
  writeCameraRegister(0x5B, 0x44);
  writeCameraRegister(0x5C, 0x67);
  writeCameraRegister(0x5D, 0x49);
  writeCameraRegister(0x5E, 0x0E);
  writeCameraRegister(0x6C, 0x0A);
  writeCameraRegister(0x6D, 0x55);
  writeCameraRegister(0x6E, 0x11);
  writeCameraRegister(0x6F, 0x9E);
  writeCameraRegister(0x6A, 0x40);
  writeCameraRegister(0x01, 0x40);
  writeCameraRegister(0x02, 0x60);
  writeCameraRegister(0x13, 0xC7);
  writeCameraRegister(0x4F, 0x80);
  writeCameraRegister(0x50, 0x80);
  writeCameraRegister(0x51, 0x00);
  writeCameraRegister(0x52, 0x22);
  writeCameraRegister(0x53, 0x5E);
  writeCameraRegister(0x54, 0x80);
  writeCameraRegister(0x58, 0x9E);
  writeCameraRegister(0x41, 0x08);
  writeCameraRegister(0x3F, 0x00);
  writeCameraRegister(0x75, 0x05);
  writeCameraRegister(0x76, 0xE1);
  writeCameraRegister(0x4C, 0x00);
  writeCameraRegister(0x77, 0x01);
  writeCameraRegister(0x3D, 0x48);
  writeCameraRegister(0x4B, 0x09);
  writeCameraRegister(0xC9, 0x60);
  writeCameraRegister(0x56, 0x40);
  writeCameraRegister(0x34, 0x11);
  writeCameraRegister(0x3B, 0x12);
  writeCameraRegister(0xA4, 0x82);
  writeCameraRegister(0x96, 0x00);
  writeCameraRegister(0x97, 0x30);
  writeCameraRegister(0x98, 0x20);
  writeCameraRegister(0x99, 0x30);
  writeCameraRegister(0x9A, 0x84);
  writeCameraRegister(0x9B, 0x29);
  writeCameraRegister(0x9C, 0x03);
  writeCameraRegister(0x9D, 0x4C);
  writeCameraRegister(0x9E, 0x3F);
  writeCameraRegister(0x78, 0x04);
  writeCameraRegister(0x79, 0x01);
  writeCameraRegister(0xC8, 0xF0);
  writeCameraRegister(0x79, 0x0F);
  writeCameraRegister(0xC8, 0x00);
  writeCameraRegister(0x79, 0x10);
  writeCameraRegister(0xC8, 0x7E);
  writeCameraRegister(0x79, 0x0A);
  writeCameraRegister(0xC8, 0x80);
  writeCameraRegister(0x79, 0x0B);
  writeCameraRegister(0xC8, 0x01);
  writeCameraRegister(0x79, 0x0C);
  writeCameraRegister(0xC8, 0x0F);
  writeCameraRegister(0x79, 0x0D);
  writeCameraRegister(0xC8, 0x20);
  writeCameraRegister(0x79, 0x09);
  writeCameraRegister(0xC8, 0x80);
  writeCameraRegister(0x79, 0x02);
  writeCameraRegister(0xC8, 0xC0);
  writeCameraRegister(0x79, 0x03);
  writeCameraRegister(0xC8, 0x40);
  writeCameraRegister(0x79, 0x05);
  writeCameraRegister(0xC8, 0x30);
  writeCameraRegister(0x79, 0x26);
  writeCameraRegister(0xFF, 0xFF);
  writeCameraRegister(0x15, 0x20);
  writeCameraRegister(0x0C, 0x04);
  writeCameraRegister(0x3E, 0x19);
  writeCameraRegister(0x72, 0x11);
  writeCameraRegister(0x73, 0xF1);
  writeCameraRegister(0x17, 0x16);
  writeCameraRegister(0x18, 0x04);
  writeCameraRegister(0x32, 0xA4);
  writeCameraRegister(0x19, 0x02);
  writeCameraRegister(0x1A, 0x7A);
  writeCameraRegister(0x03, 0x0A);
  writeCameraRegister(0xFF, 0xFF);
  writeCameraRegister(0x12, 0x00);
  writeCameraRegister(0x8C, 0x00);
  writeCameraRegister(0x04, 0x00);
  writeCameraRegister(0x40, 0xC0);
  writeCameraRegister(0x14, 0x6A);
  writeCameraRegister(0x4F, 0x80);
  writeCameraRegister(0x50, 0x80);
  writeCameraRegister(0x51, 0x00);
  writeCameraRegister(0x52, 0x22);
  writeCameraRegister(0x53, 0x5E);
  writeCameraRegister(0x54, 0x80);
  writeCameraRegister(0x3D, 0x40);
  writeCameraRegister(0xFF, 0xFF);
  writeCameraRegister(0x11, 0x1F);
  writeCameraRegister(0x0C, 0x08);
  writeCameraRegister(0x3E, 0x19);
  writeCameraRegister(0x73, 0xF1);
  writeCameraRegister(0x12, 0x10);
  delay(1000); // wait for registers to be set (because it is quite slow)
}


i try this but get this can u tell me how to fixed
(https://cdn.discordapp.com/attachments/313293292663996418/441638319080734730/2.bmp)
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: WI_DED on May 13, 2018, 11:41 am
Hi, please can you help me ?
i followed what you already done but nothing's happened and i can't know where i will found the pic if it is functional
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: jlsilicon on Oct 04, 2018, 07:50 pm
Omany,

I had related problems myself.

If you look at your image closely, it looks like that there is some image definition mixed in there.
It could be that you have misaligned your Image by Size or Bytes.
The Final Image Format probably does not match your Camera Bytes per Pixel / Line.

Title: Re: [SOLVED] Problem with camera module OV7670
Post by: bikram05 on Nov 27, 2018, 03:13 pm
hello @matanbright.great job. but i have a confusion  in the part of seeing the image " For receiving images you will need to install the software from one of the tutorials from the first post"...please help me with this stuff..:)
thank you
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: zoomx on Nov 27, 2018, 03:37 pm
The image is transmitted over serial so you have to use a program in a PC to see it.
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: RizN81 on Feb 26, 2019, 05:08 pm
Hi matanbright,
I just brought OV7670 without FIFO and Arduino Mega and as per your documentation i tried it but unfortunately i am not getting exact images :smiley-confuse: . Check at GDrive (https://drive.google.com/open?id=1wDHbsYPfYTC2zLoZCzPqFqdGVAY-ct56).
 I have done same connection for Mega and also using your sketch but its not working. I am doing this for my college project.
Will you please help me???
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: CIMLAB on Aug 27, 2019, 08:29 pm
Hi matanbright,

Thank you for the code you uploaded. I am just trying to get it to work, but I had the following questions:

1- The arduino outputs the 8MHz clock with a peak to peak voltage of 5V, I believe this isn't good for the sensor,are the two 4.7k resistors you included in between the arduino and the external clock supposed to reduce this to 3.3V?

2- When I run your code, even though I've put a 1MHz baud rate on my terminal, I am receiving weird values such as backwards questions marks. Have you had this problem before? If so, do you have any suggested solutions?

Thanks,
Kasra
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: abrar408 on Nov 04, 2019, 09:01 pm
i am trying to get the image data pixel by pixel from ov7670 to serial monitor and to store it into arduino memory which i can access later. i am using arduino mega and the camera is configured to 160x120 resolution. Any suggestions or code from which i can get help from?
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: ilylily07 on Dec 15, 2019, 10:41 am
hye i also buy the same camera module as yours.im using your code and circuit connection but in cmd it stated that the image is not found.please help me.
 
// Pins configurations:
// SDA/SIOD ---> pin A4 (for Arduino UNO) | pin 20/SDA (for Arduino MEGA)
// SCL/SIOC ---> pin A5 (for Arduino UNO) | pin 21/SCL (for Arduino MEGA)
// MCLK/XCLK --> pin 11 (for Arduino UNO) | pin 10 (for Arduino MEGA)
// PCLK -------> pin 2
// VS/VSYNC ---> pin 3
// HS/HREF ----> pin 8
// D0 ---------> pin A0
// D1 ---------> pin A1
// D2 ---------> pin A2
// D3 ---------> pin A3
// D4 ---------> pin 4
// D5 ---------> pin 5
// D6 ---------> pin 6
// D7 ---------> pin 7

#include <Wire.h>

#define CAMERA_ADDRESS 0x21

// Definitions of functions for manipulating the Arduino boards pins according to each Arduino board registers, so the code will work for both Arduino UNO and Arduino MEGA:
// The only change is the connections of the SDA/SIOD, SCL/SIOC and MCLK/XCLK pins to each board (see the pins configurations above).
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) // If you are using Arduino MEGA the IDE will automatically define the "__AVR_ATmega1280__" or "__AVR_ATmega2560__" constants.
#define TIMER2_PWM_A_PIN_MODE_OUTPUT() ({ DDRB |= 0b00010000; })
#define PIN2_DIGITAL_READ() ({ (PINE & 0b00010000) == 0 ? LOW : HIGH; })
#define PIN3_DIGITAL_READ() ({ (PINE & 0b00100000) == 0 ? LOW : HIGH; })
#define PIN4_DIGITAL_READ() ({ (PING & 0b00100000) == 0 ? LOW : HIGH; })
#define PIN5_DIGITAL_READ() ({ (PINE & 0b00001000) == 0 ? LOW : HIGH; })
#define PIN6_DIGITAL_READ() ({ (PINH & 0b00001000) == 0 ? LOW : HIGH; })
#define PIN7_DIGITAL_READ() ({ (PINH & 0b00010000) == 0 ? LOW : HIGH; })
#define PIN8_DIGITAL_READ() ({ (PINH & 0b00100000) == 0 ? LOW : HIGH; })
#define PINA0_DIGITAL_READ() ({ (PINF & 0b00000001) == 0 ? LOW : HIGH; })
#define PINA1_DIGITAL_READ() ({ (PINF & 0b00000010) == 0 ? LOW : HIGH; })
#define PINA2_DIGITAL_READ() ({ (PINF & 0b00000100) == 0 ? LOW : HIGH; })
#define PINA3_DIGITAL_READ() ({ (PINF & 0b00001000) == 0 ? LOW : HIGH; })
#elif defined(__AVR_ATmega328P__) // If you are using Arduino UNO the IDE will automatically define the "__AVR_ATmega328P__" constant.
#define TIMER2_PWM_A_PIN_MODE_OUTPUT() ({ DDRB |= 0b00001000; })
#define PIN2_DIGITAL_READ() ({ (PIND & 0b00000100) == 0 ? LOW : HIGH; })
#define PIN3_DIGITAL_READ() ({ (PIND & 0b00001000) == 0 ? LOW : HIGH; })
#define PIN4_DIGITAL_READ() ({ (PIND & 0b00010000) == 0 ? LOW : HIGH; })
#define PIN5_DIGITAL_READ() ({ (PIND & 0b00100000) == 0 ? LOW : HIGH; })
#define PIN6_DIGITAL_READ() ({ (PIND & 0b01000000) == 0 ? LOW : HIGH; })
#define PIN7_DIGITAL_READ() ({ (PIND & 0b10000000) == 0 ? LOW : HIGH; })
#define PIN8_DIGITAL_READ() ({ (PINB & 0b00000001) == 0 ? LOW : HIGH; })
#define PINA0_DIGITAL_READ() ({ (PINC & 0b00000001) == 0 ? LOW : HIGH; })
#define PINA1_DIGITAL_READ() ({ (PINC & 0b00000010) == 0 ? LOW : HIGH; })
#define PINA2_DIGITAL_READ() ({ (PINC & 0b00000100) == 0 ? LOW : HIGH; })
#define PINA3_DIGITAL_READ() ({ (PINC & 0b00001000) == 0 ? LOW : HIGH; })
#endif


void initializePWMTimer() {
  cli();
  TIMER2_PWM_A_PIN_MODE_OUTPUT(); // Set the A PWM pin of TIMER2 to output
  ASSR &= ~(_BV(EXCLK) | _BV(AS2));
  TCCR2A = (1 << COM2A0) | (1 << WGM21) | (1 << WGM20);
  TCCR2B = (1 << WGM22) | (1 << CS20);
  OCR2A = 0;
  sei();
}

byte readCameraRegister(byte registerId) {
  Wire.beginTransmission(CAMERA_ADDRESS);
  Wire.write(registerId);
  Wire.endTransmission();
  Wire.requestFrom(CAMERA_ADDRESS, 1);
  while (Wire.available() <= 0);
  byte registerValue = Wire.read();
  delay(1);
  return registerValue;
}

void writeCameraRegister(byte registerId, byte registerValue) {
  Wire.beginTransmission(CAMERA_ADDRESS);
  Wire.write(registerId);
  Wire.write(registerValue);
  Wire.endTransmission();
  delay(1);
}

void captureFrame(unsigned int frameWidth, unsigned int frameHeight) {
  Serial.print("*RDY*"); // send to the frame capture software a "start of frame" message for beginning capturing

  delay(1000);

  cli(); // disable all interrupts during frame capture (because it needs to be as fast as possible)
  while (PIN3_DIGITAL_READ() == LOW); // wait until VS/VSYNC pin is high
  while (PIN3_DIGITAL_READ() == HIGH); // wait until VS/VSYNC pin is low
  unsigned int tempWidth = 0;
  while (frameHeight--) {
    tempWidth = frameWidth;
    while (tempWidth--) {
      while (PIN2_DIGITAL_READ() == LOW); // wait until PCLK pin is high
      while (PIN2_DIGITAL_READ() == HIGH); // wait until PCLK pin is low
      byte byteToWrite = 0b00000000;
      byteToWrite |= ((PIN7_DIGITAL_READ() == HIGH) << 7);
      byteToWrite |= ((PIN6_DIGITAL_READ() == HIGH) << 6);
      byteToWrite |= ((PIN5_DIGITAL_READ() == HIGH) << 5);
      byteToWrite |= ((PIN4_DIGITAL_READ() == HIGH) << 4);
      byteToWrite |= ((PINA3_DIGITAL_READ() == HIGH) << 3);
      byteToWrite |= ((PINA2_DIGITAL_READ() == HIGH) << 2);
      byteToWrite |= ((PINA1_DIGITAL_READ() == HIGH) << 1);
      byteToWrite |= ((PINA0_DIGITAL_READ() == HIGH));
      UDR0 = byteToWrite; // send data via serial connection with UART register (we need to use the serial register directly for fast transfer)
      while (PIN2_DIGITAL_READ() == LOW); // wait until PCLK pin is high
      while (PIN2_DIGITAL_READ() == HIGH); // wait until PCLK pin is low
      // ignore each second byte (for a grayscale image we only need each first byte, which represents luminescence)
    }
  }
  sei(); // enable all interrupts
 
  delay(1000);
}


void setup() {
  initializePWMTimer();
  Wire.begin();
  Serial.begin(1000000); // the frame capture software communicates with the Arduino at a baud rate of 1MHz
}

void loop() {
  captureFrame(320, 240); // capture a frame at QVGA resolution (320 x 240)
}
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: ilylily07 on Dec 15, 2019, 10:56 am
hello @matanbright.great job. but i have a confusion  in the part of seeing the image " For receiving images you will need to install the software from one of the tutorials from the first post"...please help me with this stuff..:)
thank you

you will need to install java jdk and follow the steps
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: srishtiasrn on Feb 08, 2020, 11:19 am
hello..  i am also using ov7670 camera and the codes are working i mean it is successfully uploaded. As far as i have i have read about the working of the camera and arduino, i get to konw that due less memory of arduino uno only one single row pixels are stored at a time in the flash memory of arduino uno and  as we know that the camera outputs two bytes data for each pixel. so is it possible to read those bytes for a complete row in serial monitor? if possible, how can we do that? Also after uploading is over, if i open the serial monitor i get the following thing *RDY*???(a lots of question mrak) why is it so? and does it mean? can anybody please tell me soon??
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: vky021 on Mar 02, 2020, 03:10 pm
i try this but get this can u tell me how to fixed
(https://cdn.discordapp.com/attachments/313293292663996418/441638319080734730/2.bmp)

i am also have same this problem
Title: Re: [SOLVED] Problem with camera module OV7670
Post by: ballscrewbob on Mar 02, 2020, 03:20 pm
@vky021

Could you take a few moments to Learn How To Use The Forum (https://forum.arduino.cc/index.php?topic=148850.0).
Other general help and troubleshooting advice can be found here. (https://forum.arduino.cc/index.php?topic=52113.0)
It will help you get the best out of the forum in the future.