ap-tech / PI-Pico-OV7670-FIFO-Camera

Arduino code for connecting a OV7670 FIFO Camera to a PI Pico with no extra libraries other than the standard Arduino ones
MIT License
1 stars 0 forks source link

arduino due #1

Open xc597 opened 1 year ago

xc597 commented 1 year ago

Can this code be used for arduino due connection to ov7670 fifo

ap-tech commented 1 year ago

Theoretically if you change the port name from that of the Pi Pico to what ever the Due has I think you can make it work, There are ov7670 fifo codes specifically for the Due out there.

xc597 commented 1 year ago

i will try,thanks for your replay

xc597 commented 1 year ago

I want to know "wire.setSda()"; What does it mean? Can I delete it when I'm using arduino due, because I get an error when I compile

xc597 commented 1 year ago

And I was wondering where I should look at my images, sorry I'm new to this

xc597 commented 1 year ago

How should I run these pde files

xc597 commented 1 year ago
image

I don't know. Why is that

xc597 commented 1 year ago
image
xc597 commented 1 year ago

It looks like you took the picture out of the fifo like this. myImage[x][y] = gpio_get_all() > > 2; However, arduino due does not support such a way, so far I have not found a solution

ap-tech commented 1 year ago

I could not find this in the Processing code or the Pico code "wire.setSda()"; And as for the Processing code you have to change the port name to that of you PC's post name since mien is running on a Mac.

myPort = new Serial(this,"/dev/cu.usbmodem1421",9600);

ap-tech commented 1 year ago

I did a due code for the ov7670 camera (but with out the FIFO) send my your email (Because I don't know if I can send it here) And I'll send it to you maybe you can get some ideas from it.

xc597 commented 1 year ago

thanks!1785263952@qq.com

ap-tech commented 1 year ago

Ok I just sent it to you let me know how it goes and remember to change the port name on the processing code to your computer's port name.

xc597 commented 1 year ago

Thank you my friend, I'll try to find inspiration tomorrow

xc597 commented 1 year ago

I want to know how many frames per second you implemented for this fifo free code, I implemented five frames per second, which is too slow. I found that the method to get the image without fifo is myImage[y][x] = (REG_PIOC_PDSR&0xFF000) > > 12. I know this very well, but with fifo I don't understand how to get image data, I don't know how to get data from fifo. Your code I noticed that the way to get the data is myImage[x][y] = gpio_get_all() > > 2; However, this method is not applicable to arduino due, and when I look up relevant materials, it seems that there is no corresponding method in arduino due. I am confused about fifo, I want to use it to achieve at least one frame per second, but the image data is so difficult to obtain. Excuse my poor English. Looking forward to your reply, my friend.

ap-tech commented 1 year ago

What is the resolution you want out of it? In my GitHub code the resolution is 80x60, The lower the resolution the faster the frame rate, The code I sent you by email is 320 x 240 and that could take you 30 sec to get one frame and you have to be really still otherwise you skewer the image, See what the FIFO does is it handles all the fast clocking stuff for you, All that you have to do is clock it out at the microcontroller's own pace.

xc597 commented 1 year ago
image

I need a normal image, arduino due+ov7670 fifo

ap-tech commented 1 year ago

What resolution? Is the 80x60 resolution in my GitHub ok?

xc597 commented 1 year ago

yes

ap-tech commented 1 year ago

Can I see your code?

xc597 commented 1 year ago

/* APteck

Written By: Anthony Pirotta. Date: 20/05/2023. Revised: 01/06/2023. Name Of Code: OV7670_FIFO_Camera. Written For: RP2040 based boards or PI Picos using the Raspberry Pi Pico tool in the Arduino IDE. Purpose Of Code: Writing and reading camera data from a FIFO using a PI Pico or an RP2040 based board and sends the data to Processing running on Mac or PC. */

include

define REG_GAIN 0x00

define REG_BLUE 0x01

define REG_RED 0x02

define REG_COM1 0x04

define REG_VREF 0x03

define REG_COM4 0x0d

define REG_COM5 0x0e

define REG_COM6 0x0f

define REG_AECH 0x10

define REG_CLKRC 0x11

define REG_COM7 0x12

define COM7_RGB 0x04

define REG_COM8 0x13

define COM8_FASTAEC 0x80 // Enable fast AGC/AEC

define COM8_AECSTEP 0x40 // Unlimited AEC step size

define COM8_BFILT 0x20 // Band filter enable

define COM8_AGC 0x04 // Auto gain enable

define COM8_AWB 0x02 // White balance enable

define COM8_AEC 0x0

define REG_COM9 0x14

define REG_COM10 0x15

define REG_COM14 0x3E

define REG_SCALING_DCWCTR 0x72

define REG_SCALING_PCLK_DIV 0x73

define REG_COM11 0x3B

define COM11_NIGHT 0x80

define COM11_NMFR 0x60

define COM11_HZAUTO 0x10

define COM11_50HZ 0x08

define COM11_EXP 0x0

define REG_TSLB 0x3A

define REG_RGB444 0x8C

define REG_COM15 0x40

define COM15_RGB565 0x10

define COM15_R00FF 0xc0

define REG_HSTART 0x17

define REG_HSTOP 0x18

define REG_HREF 0x32

define REG_VSTART 0x19

define REG_VSTOP 0x1A

define REG_COM3 0x0C

define REG_MVFP 0x1E

define REG_COM13 0x3d

define COM13_UVSAT 0x40

define SCALING_DCWCTR 0x72

define SCALING_PCLK_DIV 0x73

define REG_BD50MAX 0xa5

define REG_BD60MAX 0xab

define REG_AEW 0x24

define REG_AEB 0x25

define REG_VPT 0x26

define REG_HAECC1 0x9f

define REG_HAECC2 0xa0

define REG_HAECC3 0xa6

define REG_HAECC4 0xa7

define REG_HAECC5 0xa8

define REG_HAECC6 0xa9

define REG_HAECC7 0xaa

define REG_COM12 0x3c

define REG_GFIX 0x69

define REG_COM16 0x41

define COM16_AWBGAIN 0x08

define REG_EDGE 0x3f

define REG_REG76 0x76

define ADCCTR0 0x20

define REG_SCALING_YSC 0x71

define REG_SCALING_XSC 0x70

define CAMERA (0x42 >> 1)

//Matrix values. uint8_t myImage[240][320]; int x,y = 0;

define VSYNC 52 //vertical sync

define RRST 40 //read reset

define WRST 41 //write reset

define RCK 42 //read clock

define WR 43 //write flag

define D0 51 //12

define D1 50 //13

define D2 49 //14

define D3 48 //15

define D4 47 //16

define D5 46 //17

define D6 45 //18

define D7 44 //19

unsigned long timeBegin = 0; unsigned long duration = 0;

void I2CwriteByte(uint8_t Address, uint8_t Register, uint8_t Data){ // Set register address Wire.beginTransmission(Address); Wire.write(Register); Wire.write(Data); if (Wire.endTransmission(true)) { Serial.print(F("ERROR REG :")); Serial.println(Register); } delay(20); }

/* void frameControl(int hStart, int hStop, int vStart, int vStop) { I2CwriteByte(CAMERA, REG_HSTART, hStart >> 3); I2CwriteByte(CAMERA, REG_HSTOP, hStop >> 3); I2CwriteByte(CAMERA, REG_HREF, ((hStop & 0b111) << 3) | (hStart & 0b111));

I2CwriteByte(CAMERA, REG_VSTART, vStart >> 2);
I2CwriteByte(CAMERA, REG_VSTOP, vStop >> 2);
I2CwriteByte(CAMERA, REG_VREF, ((vStop & 0b11) << 2) | (vStart & 0b11));

}

*/

void saturation(int s) //-2 to 2 { //color matrix values I2CwriteByte(CAMERA, 0x4f, 0x80 + 0x20 s); I2CwriteByte(CAMERA, 0x50, 0x80 + 0x20 s); I2CwriteByte(CAMERA, 0x51, 0x00); I2CwriteByte(CAMERA, 0x52, 0x22 + (0x11 s) / 2); I2CwriteByte(CAMERA, 0x53, 0x5e + (0x2f s) / 2); I2CwriteByte(CAMERA, 0x54, 0x80 + 0x20 * s); I2CwriteByte(CAMERA, 0x58, 0x9e); //matrix signs }

void setup() {

inline void readReset() attribute((always_inline)); inline void writeEnable() attribute((always_inline)); inline void writeDisable() attribute((always_inline)); inline void writeReset() attribute((always_inline));

Serial.begin(115200);

pinMode(D0,INPUT_PULLUP);    //8 Bit pixil input from camera.
pinMode(D1,INPUT_PULLUP);    // 
pinMode(D2,INPUT_PULLUP);    //            
pinMode(D3,INPUT_PULLUP);    //              
pinMode(D4,INPUT_PULLUP);    //             
pinMode(D5,INPUT_PULLUP);    //  
pinMode(D6,INPUT_PULLUP);    //  
pinMode(D7,INPUT_PULLUP);    //   

pinMode(D0, INPUT); 
pinMode(D1, INPUT); 
pinMode(D2, INPUT);
pinMode(D3, INPUT);
pinMode(D4, INPUT);
pinMode(D5, INPUT); 
pinMode(D6, INPUT);
pinMode(D7, INPUT);

//pinMode(VSYNC,INPUT_PULLUP);   //Frame strobe input or VSYNC
pinMode(VSYNC, INPUT);

//FIFO and Camera control inputs.
pinMode(RRST, OUTPUT);       
pinMode(WRST, OUTPUT);       
pinMode(RCK, OUTPUT);        
pinMode(WR, OUTPUT);        

//LED pin (For debugging)
pinMode(LED_BUILTIN, OUTPUT);

Wire.begin();

//What you need to initiate I2C communication with the OV7670.

I2CwriteByte(CAMERA,REG_COM7,0b10000000); //all registers default

I2CwriteByte(CAMERA,REG_CLKRC,0b10000000); //double clock

I2CwriteByte(CAMERA,REG_COM11, 0b1000 | 0b10); //enable auto 50/60Hz detect + exposure timing can be less...

//I2CwriteByte(CAMERA,REG_TSLB,0b100); //sequence UYVY

I2CwriteByte(CAMERA,REG_TSLB,0x14);

I2CwriteByte(CAMERA,0x67, 0x80); I2CwriteByte(CAMERA,0x68, 0x80);

//I2CwriteByte(CAMERA,REG_COM7, 0b100); //RGB

//I2CwriteByte(CAMERA,REG_COM15, 0b11000000 | 0b010000); //RGB565

///////////////////////////////////////////////////////////////////////

I2CwriteByte(CAMERA,REG_COM10,0x02); //VSYNC negative

I2CwriteByte(CAMERA,REG_MVFP, 0x2b); //mirror flip

//Test Image. //I2CwriteByte(CAMERA,SCALING_YSC,0x35 | 0x80);

//Image Scaler for 320x240 QVGA. //I2CwriteByte(CAMERA,REG_COM14,0x19); //I2CwriteByte(CAMERA,SCALING_DCWCTR,0x11); //I2CwriteByte(CAMERA,SCALING_PCLK_DIV,0xf1);

//Image Scaler for 160x120 QQVGA.

//I2CwriteByte(CAMERA,REG_COM3, 0x04); //I2CwriteByte(CAMERA,REG_COM14, 0x1a); //I2CwriteByte(CAMERA,REG_SCALING_XSC, 0x3a); //I2CwriteByte(CAMERA,REG_SCALING_YSC, 0x35); //I2CwriteByte(CAMERA,REG_COM14,0x1a); //I2CwriteByte(CAMERA,SCALING_DCWCTR,0x22); //I2CwriteByte(CAMERA,SCALING_PCLK_DIV,0xf2);

//Image Scaler for 80x60 QQQVGA.

I2CwriteByte(CAMERA,REG_COM3, 0x04); I2CwriteByte(CAMERA,REG_COM14, 0x1b); I2CwriteByte(CAMERA,REG_SCALING_XSC, 0x3a); I2CwriteByte(CAMERA,REG_SCALING_YSC, 0x80); I2CwriteByte(CAMERA,REG_COM14,0x1b); I2CwriteByte(CAMERA,SCALING_DCWCTR,0x33); I2CwriteByte(CAMERA,SCALING_PCLK_DIV,0xf3);

//frameControl(196, 52, 8, 488); // new lead

I2CwriteByte(CAMERA,REG_HSTART, 0x18); I2CwriteByte(CAMERA,REG_HSTOP, 0x06); I2CwriteByte(CAMERA,REG_HREF, 0x24); I2CwriteByte(CAMERA,REG_VSTART, 0x02); I2CwriteByte(CAMERA,REG_VSTOP, 0x7a); I2CwriteByte(CAMERA,REG_VREF, 0x00);

I2CwriteByte(CAMERA,0xb0, 0x84); saturation(10); I2CwriteByte(CAMERA,0x13, 0xe7); I2CwriteByte(CAMERA,0x6f, 0x9f);

//Experimental values for day time //I2CwriteByte(CAMERA,0x11, 0x80); //I2CwriteByte(CAMERA,0x6b, 0x0a); //I2CwriteByte(CAMERA,0x2a, 0x00); //I2CwriteByte(CAMERA,0x2b, 0x00); //I2CwriteByte(CAMERA,0x92, 0x00); //I2CwriteByte(CAMERA,0x93, 0x00); //I2CwriteByte(CAMERA,0x3b, 0x0a);

//Values for day time I2CwriteByte(CAMERA,0x11, 0x00); I2CwriteByte(CAMERA,0x6b, 0x4a); I2CwriteByte(CAMERA,0x2a, 0x00); I2CwriteByte(CAMERA,0x2b, 0x00); I2CwriteByte(CAMERA,0x92, 0x2b); I2CwriteByte(CAMERA,0x93, 0x00); I2CwriteByte(CAMERA,0x3b, 0x0a);

}

void readReset() { digitalWrite(RRST, 0); delayMicroseconds(1); digitalWrite(RCK, 0); delayMicroseconds(1); digitalWrite(RCK, 1); delayMicroseconds(1); digitalWrite(RRST, 1);
}

void writeEnable() { digitalWrite(WR, 0); }

void writeDisable() { digitalWrite(WR, 1); }

void writeReset() { digitalWrite(WRST, 0); delayMicroseconds(1); digitalWrite(WRST, 1); }

void loop() {

timeBegin = micros();

digitalWrite(LED_BUILTIN, HIGH);

while(digitalRead(VSYNC)== LOW); while(digitalRead(VSYNC)== HIGH); writeReset(); writeEnable(); while(digitalRead(VSYNC)== LOW); writeDisable(); Frame();

}

void Frame(){

unsigned long timeEnd = micros();

duration = timeEnd - timeBegin;

digitalWrite(LED_BUILTIN, LOW);

readReset();
for (y = 0; y <60; y++) {   
  for (x = 0; x < 80; x++) { 
    digitalWrite(RCK, LOW);
    digitalWrite(RCK, HIGH);
    //myImage[i][j] = ((gpio_get_all() >>2)  & (0b11111000));
    uint8_t pixelData = 0;
   pixelData =  ((digitalRead(51) << 7) |
                (digitalRead(50) << 6) |
                (digitalRead(49) << 5) |
                (digitalRead(48) << 4) |
                (digitalRead(47) << 3) |
                (digitalRead(46) << 2) |
                (digitalRead(45) << 1) |
                (digitalRead(44) << 0));

  // Store the pixel value in the myImage array at the appropriate position
    myImage[x][y] = pixelData;
    digitalWrite(RCK, LOW);
    digitalWrite(RCK, HIGH);

   } 
 }

Horizon(); To_PC(); //To Processing

//Timer_USB(); //For for testing frame rate //One_Byte_Of(); //For debugging single pixel }

void Horizon(){ for(x = 0; x < 80; x ++){ myImage[x][30] = 255;

}

}

void To_PC(){

for(y = 0; y < 60; y ++){
for(x = 0; x < 80; x ++){
Serial.print(myImage[x][y]);
Serial.print(",");

}                                                                   

}
Serial.println(" ");

}

void Timer_USB(){

Serial.println(duration);

}

void One_Byte_Of(){

Serial.println(myImage[40][30], BIN);

}

xc597 commented 1 year ago

The image displayed is the same as the QR code, is the clock signal wrong

ap-tech commented 1 year ago

Try replacing this

pixelData = ((digitalRead(51) << 7) | (digitalRead(50) << 6) | (digitalRead(49) << 5) | (digitalRead(48) << 4) | (digitalRead(47) << 3) | (digitalRead(46) << 2) | (digitalRead(45) << 1) | (digitalRead(44) << 0));

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

ap-tech commented 1 year ago

And can I see a pic of how everything is connected?

xc597 commented 1 year ago

9bcda2225dcf19a7b9caea6174d1291

xc597 commented 1 year ago

bdcf95e0b16d8c89df30763ecfd8b3c

xc597 commented 1 year ago

myImage[y][x] = (REG_PIOC_PDSR&0xFF000) > > 12. Neither can I; As far as I know, FIFO doesn't seem to work that way

xc597 commented 1 year ago
image

I also found that the pixel value at the beginning also wrote some garbled Chinese

ap-tech commented 1 year ago

The first thing I see is that you don't have 4.7K pull-up resistors for I2C.

xc597 commented 1 year ago

fine

xc597 commented 1 year ago

After I grounded the OE pin, there was a lot of snow pattern. But you don't seem to see the OE setting in your code. I don't know if this means I'm one step closer to success? At present, my configuration of OV7670 module does not use HERF,RST and STR.

xc597 commented 1 year ago
image
ap-tech commented 1 year ago

Did you put those 4.7K pull-up resistors on I2C?

ap-tech commented 1 year ago

And if you comment this part of the code out .... Horizon(); = //Horizon(); you can remove that white line in the meddle of the image.

ap-tech commented 1 year ago

And I just checked yes the OE pin is just grounded.

ap-tech commented 1 year ago

And RST to 3v+

xc597 commented 1 year ago

it is necessary?

---Original--- From: "Anthony @.> Date: Thu, Aug 3, 2023 17:34 PM To: @.>; Cc: "Small @.**@.>; Subject: Re: [ap-tech/PI-Pico-OV7670-FIFO-Camera] arduino due (Issue #1)

Did you put those 4.7K pull-up resistors on I2C?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

xc597 commented 1 year ago

OK,thanks,I will replay tomorrow 

---Original--- From: "Anthony @.> Date: Thu, Aug 3, 2023 17:56 PM To: @.>; Cc: "Small @.**@.>; Subject: Re: [ap-tech/PI-Pico-OV7670-FIFO-Camera] arduino due (Issue #1)

And RST to 3v+

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

xc597 commented 1 year ago

It's still all snow pattern

xc597 commented 1 year ago

arduino has a built-in pull-up resistor, and I set it to pull-up mode, but nothing changed

xc597 commented 1 year ago

After I connected the RST to 5V (because I don't have any more 3.3V), the image looked like this

image
xc597 commented 1 year ago

This is my first time in this situation and I don't know what to do. Is it possible that VSYN is incorrectly configured and does not store the correct image data? Or is the RCK wrong? Or was some of the data transmitted to PROCESS lost?

ap-tech commented 1 year ago

Do you have an oscilloscope to see if you are getting an I2C signal?