Hello, I am trying to take a picture with my ov7670 camera module. in the first step, I am trying to print out the pixel values via the Serial Terminal. If I then convert the pixel values to an actual picture, the output looks like this:
#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*"); // Start of frame message
delay(1000);
cli(); // Disable interrupts
while (PIN3_DIGITAL_READ() == LOW); // Wait for VSYNC
while (PIN3_DIGITAL_READ() == HIGH); // Wait until VSYNC goes low
String pixelDataString = ""; // String to hold pixel data
unsigned int pixelIndex = 0;
while (frameHeight--) {
for (unsigned int tempWidth = 0; tempWidth < frameWidth; tempWidth++) {
while (PIN2_DIGITAL_READ() == LOW); // Wait for PCLK high
// Read two bytes for RGB565
byte highByte = 0b00000000;
byte lowByte = 0b00000000;
// Read the 8 data pins
highByte |= ((PIN7_DIGITAL_READ() == HIGH) << 7);
highByte |= ((PIN6_DIGITAL_READ() == HIGH) << 6);
highByte |= ((PIN5_DIGITAL_READ() == HIGH) << 5);
highByte |= ((PIN4_DIGITAL_READ() == HIGH) << 4);
lowByte |= ((PINA3_DIGITAL_READ() == HIGH) << 3);
lowByte |= ((PINA2_DIGITAL_READ() == HIGH) << 2);
lowByte |= ((PINA1_DIGITAL_READ() == HIGH) << 1);
lowByte |= (PINA0_DIGITAL_READ() == HIGH);
// Convert RGB565 to RGB888
byte r = (highByte & 0xF8); // Red 5 bits
byte g = ((highByte & 0x07) << 5) | ((lowByte & 0xE0) >> 3); // Green 6 bits
byte b = (lowByte & 0x1F) << 3; // Blue 5 bits
// Build the string for this pixel
pixelDataString = "(" + String(r) + "," + String(g) + "," + String(b) + ")";
Serial.println(pixelDataString);
while (PIN2_DIGITAL_READ() == HIGH); // Wait for PCLK low
}
}
sei(); // Enable interrupts
delay(1000);
}
void setup() {
initializePWMTimer();
Wire.begin();
Serial.begin(115200); // Set baud rate for serial communication
captureFrame(320, 240); // capture a frame at QVGA resolution (320 x 240)
Serial.println("Done!");
}
My Pin configuration looks like this:
// SDA/SIOD ---> pin A4
// SCL/SIOC ---> pin A5
// MCLK/XCLK --> pin 11
// 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
Can anyone help me to find the problem here?
