Finally I got clean images at low speed ( wrReg(0x11, 63); ) so I decided to move the project to the DUE.
for the oscilloscope I think I'll go for the RIGOL DS1102E which seems to be a good oscilloscope to start with, also because suits also this case and I should be good at least until frequency at 33Mhz.
I'm going to open a thread soon asking for a couple of advices
Auto exposure it's ok for me but I feel to advise other users that the first few frames taken could be over-exposed! (thought might be the issue of the user vvavepacket)
If you did output 5v and didn't burn, shouldn't I also. I think might be the light or dust on the sensor when I take out the lens to see how the sensor looks like.
I doubt it's screwed. I'll check when I'll finish the port on the DUE, speaking of which:
I wired DUE like so for now
SCL -> SIOC (10Kohm to 3v3)
SDA -> SIOD (10Kohm to 3v3)
PIN7 -> XCLK
3v3 -> 3v3
GND -> GND
and nothing more, just to see if this little devil answer.
to generate the clock on the DUE I found many techniques which involves PWM.
I liked this because it can achieve the highest possible PWM on the DUE which is a clean 84Mhz waveform,
but I didn't know if setting
uint32_t pwmPin = 7;
uint32_t maxDutyCount = 2;
uint32_t clkAFreq = 20000000ul;
uint32_t pwmFreq = 20000000ul;
was enough to get a 20 Mhz clock on pin 7 for the camera module.
So I tryied this other code which I found here ~10MHz clock generation with the Due - Arduino Due - Arduino Forum which I'm (quite) sure generate a 10.5Mhz clock;
the OV7670 say that wrReg is ok but when I try to read the registers it answer that the value is 0 (with three different methods).
I also tried the pwm01 library which is an "official" alpha library to generate a pwm on the DUE but it seems ok until 100000hz, then "Serial.print" screw up and begins to throw out random stuff.
BEWARE! only pin 6, 7, 8, 9 can be used for PWM on the DUE!
#include <Arduino.h>
#include <Wire.h>
#define camAddr_WR 0x42
#define camAddr_RD 0x43
#define REGISTERS 0x91 // Define # of Registesr on OV7076
byte wrReg(unsigned char regID, unsigned char regDat){
Wire.beginTransmission(camAddr_WR >> 1);
Wire.write(regID);
Wire.write(regDat);
if (Wire.endTransmission()){
return 0;
while (1);
}
delay(1);
return 1;
}
void readRegisterBank()
{
uint8_t count = 0x12;
int address = 0x12;
Wire.beginTransmission(camAddr_WR);
Wire.write(address);
Wire.endTransmission();
Wire.requestFrom(camAddr_RD, 1);
while (!Wire.available())
{
}
int c = Wire.read();
Serial.println(c);
//while (count<REGISTERS)
//{
byte highByte = 0;
Serial.print("\r\n Register num: ");
Serial.print(count, HEX);
Serial.print(" val: ");
Wire.beginTransmission(camAddr_WR); //Start communication with cmps03
Wire.write(count); //Send the register we wish to read
Wire.endTransmission();
Wire.requestFrom(camAddr_RD, 1); //Request high byte
while (Wire.available() < 1); //While there is a byte to receive
highByte = Wire.read(); //Read the byte as an integer
Serial.print(highByte, HEX);
delay(25);
//count++;
//}
Serial.print("\r\n Register num: ");
Serial.print(count, HEX);
Serial.print(" val: ");
Wire.beginTransmission(camAddr_WR);
Wire.write(count);
Wire.endTransmission();
Wire.requestFrom(camAddr_RD, 2);
byte LSB = Wire.read();
byte MSB = Wire.read();
uint16_t touched = ((MSB << 8) | LSB); //16bits that make up the touch states
Serial.print(touched);
Wire.beginTransmission((uint8_t)camAddr_WR);
Wire.write(count);
Wire.endTransmission(false);
Wire.requestFrom((uint8_t)camAddr_RD, (uint8_t)1, (uint8_t)true);
if (Wire.available() >= 1)
{
int result = Wire.read();
Serial.println(result, HEX);
}
}
void setup() {
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 B
REG_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)
Serial.begin(115200);
Wire.begin();
Serial.print("wrReg: "); Serial.println((wrReg(0x12, 0x80)));
delay(1000);
readRegisterBank();
}
void loop()
{
}
I know that the camera has already been ported on the DUE by user aturcitu but I didn't like he used
#define RCLK_SET PIOC->PIO_SODR=1<<15
#define RCLK_CLR PIOC->PIO_CODR=1<<15
because in the previous article I linked states that with this technique (slightly different) you can reach 16.8 Mhz. It looks like an hack to me. I want to use wire library (disabling internal pullups) and the SAM PWM to generate the clock to unleash the full potential of the OV7670 and then try to move to the ov5642 with an 8M sram module (hoping DUE keep up)
when I get the camera working with DUE I'm willing to make a C# program to toggle the settings of the module runtime so you don't need to recompile each time and allow you to see the register settings change in real-time.
Mr_Arduino thank you for your time and your patience which allow other user to grow their knowledge!