Introduction: How to Connect OV7670 to Arduino Due

This instruction is a quick translation for an instruction in Russian available at

http://privateblog.info/arduino-due-i-kamera-ov7670-primer-ispolzovaniya/

Connection of OV7670 to Arduino Due is easier than to Arduino Uno: lower operation voltage - only 3V, higher internal speed, more memory and more contacts on the board.

Step 1: Schema to Connect OV7670 to Arduino Due

Let's start from connecting wires. Schema is available on the picture. You do not need any resistors. Operation voltage on Arduino Due is 3V. It is optimal for OV7670.

Step 2: Genering Clock Signal

After valid connection we need to get clock signal more than 8MHz. It is easy to get 10.5MHz.

int32_t mask_PWM_pin = digitalPinToBitMask(7);

REG_PMC_PCER1 = 1<<4; // activate clock for PWM controller

REG_PIOC_PDR |= mask_PWM_pin; // activate peripheral functions for pin (disables all PIO functionality)

REG_PIOC_ABSR |= mask_PWM_pin; // choose peripheral option

BREG_PWM_CLK = 0; // choose clock rate, 0 -> full MCLK as reference 84MHz

REG_PWM_CMR6 = 0<<9; // select clock and polarity for PWM channel (pin7) -> (CPOL = 0)

REG_PWM_CPRD6 = 8; // initialize PWM period -> T = value/84MHz (value: up to 16bit), value=8 -> 10.5MHz

REG_PWM_CDTY6 = 4; // initialize duty cycle, REG_PWM_CPRD6 / value = duty cycle, for 8/4 = 50%

REG_PWM_ENA = 1<<6; // enable PWM on PWM channel (pin 7 = PWML6)

Step 3: Configuring Register of OV7670

After generating clock signal we need to write proper values to registers of OV7670. You need to use 0x21 as address since TWI interface support 7bit addresses. It allows to write register, but reading will be with issues.

void write(uint8_t regID, byte regDat){

Wire.beginTransmission(address);

Wire.write(regID & 0x00FF);

Wire.write(regDat & 0x00FF);

if(Wire.endTransmission(true)){

Serial.print("error write reg ");

Serial.println(regID);

}

delay(20);

}

values for register you will find later in the source code.

Step 4: Transmitting an Image

After generating clock signal and writing register we need to transmit image. Arduino Due provides UART interface for that purpose.

...

Serial.begin(460800);

...

it is better to use custom function to speedup transmission.

static inline int uart_putchar(const uint8_t c) {

while(!(UART->UART_SR & UART_SR_TXRDY));

UART->UART_THR = c;

return 0;

}

We can try to prevent some artifacts by using buffer inside Arduino Due. In this case we write image to buffer and only after that transmit:

static void captureImg(uint16_t wg, uint16_t hg){

uint16_t y, x;

Serial.println("*RDY*");

while (!(REG_PIOB_PDSR & (1 << 21)));//wait for high while

((REG_PIOB_PDSR & (1 << 21)));//wait for low

y = hg;

while (y--){

x = wg;

while (x--){

while ((REG_PIOD_PDSR & (1 << 10)));//wait for low

myImage[y][x] = (REG_PIOC_PDSR & 0xFF000) >> 12;

while (!(REG_PIOD_PDSR & (1 << 10)));//wait for high

while ((REG_PIOD_PDSR & (1 << 10)));//wait for low

while (!(REG_PIOD_PDSR & (1 << 10)));//wait for high

}

}

for (y = 0; y < hg; y++) {

for (x = 0; x < wg; x++) {

uart_putchar(myImage[y][x]);

}

}

}

Step 5: Receiving

Now we need to receive the image. For this purpose the same java application as for example with Arduino Uno will be used.

Framegrabber

How to run Framegrabber

How to connect OV7670 and Arduino Uno

Step 6: Results

The result you can see on the picture.

There is problem with Arduino Due: I wasn't able to get speed more that 460800, but it should not have impact on quality of the picture since it buffered.