Hello, I am currently working on a project that requires camera input for object tracking. I am currently using Teensy 4.0 and the OV7670 camera. I am trying to get the timing down with the XCLK, PCLK, and HREF, but seem to be getting issues mainly from the XCLK. Right now, the only time that the XCLK seems to work is when I touch the wire. I'm assuming that either A: I messed up the wiring somehow, or B: My code is completely dysfunctional. Any advice is greatly appreciated! Also, please explain it to me like I am dumb, I really want to learn more about this, and I, very obviously, lack current skill right now. What I am least comfortable with is probably the PWM, and analogWrite() stuff, I don't exactly understand all that is happening. Thank you!
C++:
// Define OV7670 pin connections
#define VSYNC_PIN 2
#define HREF_PIN 4
#define PCLK_PIN 3
#define XCLK_PIN 5
#define D0_PIN 8
#define D1_PIN 9
#define D2_PIN 10
#define D3_PIN 11
#define D4_PIN 12
#define D5_PIN 13
#define D6_PIN 14
#define D7_PIN 15
int byteNum = 0;
uint8_t byteN = 0;
int highCap = 0;
int lowCap =0;
uint8_t highByte = 0;
uint8_t lowByte = 0;
int HREF_prev = 0;
int PCLK_prev = 0;
bool falling = false;
int currTime = 0;
bool byteLoaded = false;
void setup() {
// Initialize Serial Communication
Serial.begin(115200);
// Initialize OV7670 pins
pinMode(VSYNC_PIN, INPUT);
pinMode(HREF_PIN, INPUT);
pinMode(PCLK_PIN, INPUT);
pinMode(XCLK_PIN, OUTPUT);
pinMode(D0_PIN, INPUT);
pinMode(D1_PIN, INPUT);
pinMode(D2_PIN, INPUT);
pinMode(D3_PIN, INPUT);
pinMode(D4_PIN, INPUT);
pinMode(D5_PIN, INPUT);
pinMode(D6_PIN, INPUT);
pinMode(D7_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(PCLK_PIN), fallingPCLK, FALLING);
//attachInterrupt(digitalPinToInterrupt(PCLK_PIN), risingPCLK, RISING);
//provides the timing for the system clock, we desire a 24 MHz clockrate?
//PWM divides CPU by 4, so for 24 Mhz, we need the CPU at 528 MHz, which gives us a PWM base of 132 Mhz
analogWriteFrequency(XCLK_PIN, 24000000); //sets pulse freq to 24 MHz
//we will write an 128 long pulse with this frequency, this pulse acts as our "high".
analogWrite(XCLK_PIN, 128); //writes a PWM signal of 128 to XCLK_PIN, giving us a 50% duty cycle
delay(100);
attachInterrupt(digitalPinToInterrupt(XCLK_PIN), change, CHANGE);
}
void loop() {
static bool capture = false;
//interrupts();
if (digitalRead(VSYNC_PIN) == LOW) {
// Start of a frame
capture = true;
// Serial.println("Start of frame");
} else if (digitalRead(VSYNC_PIN) == HIGH && capture) {
// End of a frame
capture = false;
// Serial.println("End of frame");
}
//Serial.print(digitalRead(HREF_PIN));
//rising edge of HREF indicates line start, falling edge indicates line end
if (capture && digitalRead(HREF_PIN) == HIGH) { //this means we are on a line
//Serial.println("Begin Line");
if(byteNum == 0 && byteLoaded){ //set value for pixel bits 15-8
byteNum = 1; //set to next byte
highByte = byteN;
byteLoaded = false;
highCap = 1;
}
else if(byteNum == 1 && byteLoaded){ //set value for pixel bits 7-0
byteNum = 0;
lowByte = byteN;
byteLoaded = false;
lowCap = 1;
}
if(lowCap != 0 && highCap != 0){
lowCap = 0;
highCap = 0;
uint16_t pixel = 0;
pixel |= highByte << 8;
pixel |= lowByte;
lowByte = 0;
highByte = 0;
Serial.println(pixel, HEX);
}
}
}
uint8_t readByte() {
uint8_t newByte = 0;
newByte |= (digitalRead(D0_PIN) << 0);
newByte |= (digitalRead(D1_PIN) << 1);
newByte |= (digitalRead(D2_PIN) << 2);
newByte |= (digitalRead(D3_PIN) << 3);
newByte |= (digitalRead(D4_PIN) << 4);
newByte |= (digitalRead(D5_PIN) << 5);
newByte |= (digitalRead(D6_PIN) << 6);
newByte |= (digitalRead(D7_PIN) << 7);
return newByte;
}
void fallingPCLK(){ //falling pclk indicates the start of a new byte, our cycle time is rougly 25 ns
//the first 15 ns, are for the setup, and last 10 ish are for holding, so we need to stall 15 ns.
//the next rising edge will be when we can read a byte
//Serial.println("hio");
delay(0.000015); //15 ns
if(digitalRead(HREF_PIN) == HIGH){
byteN = readByte();
//Serial.println(byteN, HEX);
byteLoaded = true;
}
}
void change(){
Serial.println(digitalRead(XCLK_PIN));
}
Last edited: