Tested on Nucleo F411RE Based on OV7670 without FIFO, SCCB protocol rewritten. View on TFT ILI9341, possible capture picture on sd Around 3 frames per second Basic image treatment: zoom, rotation, etc Very basic pattern recognition, pattern being stored on SD, after camera capture, or from .bmp file (rgb 565, 120x160 max)
Dependencies: FastPWM SDFileSystem SPI_TFT_ILI9341 TFT_fonts imagetrlib mbed ov7670s
main.cpp
- Committer:
- sylvainkritter
- Date:
- 2016-02-16
- Revision:
- 1:7fbc24ad0958
- Parent:
- 0:39c9f3b49f5a
- Child:
- 2:7e06db0773c1
File content as of revision 1:7fbc24ad0958:
#include "mbed.h" #include "global.h" #include "FastPWM.h" #include "imagetr.h" #include "ov7670s.h" #include "ov7670sreg.h" #include "SPI_TFT_ILI9341.h" #include "SDFileSystem.h" #define SCTFT PA_5 // sclk TFT #define MISOTFT PA_6 //miso TFT #define MOSITFT PA_7 //Mosi tft #define PA9 PA_9 // dc TFT #define PB6 PB_6 // cs TFT #define PA11 PA_11 // reset TFT pc7 #define PCLK PC_10 //camera Pixel clock #define HREF PC_11 //camera Href #define VSYNC PC_12 // camera Vsync #define I2C_D PB_3 // Camera SCCB port data #define I2C_CLK PB_10 // Camera SCCB port clock #define RESET PB_12 // camera reset #define XCLK PA_10 // camera system clock #define mD0 PC_2//camera Data #define mD1 PC_3//camera Data #define mD2 PC_4//camera Data #define mD3 PC_5//camera Data #define mD4 PC_6//camera Data #define mD5 PC_7//camera Data #define mD6 PC_8 // camera Data #define mD7 PC_9 //camera Data #define SCSD PB_13 // sclk SD #define MISD PB_14 // miso SD #define MOSD PB_15 // mosi SD #define PD2 PD_2 /: CS SD DigitalOut myled(LED1); InterruptIn my_button(USER_BUTTON); AnalogIn analog_value0(A0); AnalogIn analog_value1(A1); AnalogIn analog_value2(A2); AnalogIn analog_value3(A3); Timer Time; int mask =0x1FFC; #define QQVGA 19200 //160*120 Serial pc(USBTX,USBRX); //camera OV7670 OV7670(I2C_D,I2C_CLK,XCLK,PortC,mask,RESET); // 4.7 Kohm pull up on I2C_D // the TFT is connected to SPI pin SPI_TFT_ILI9341 TFT(MOSITFT, MISOTFT, SCTFT, PB6, PA11, PA9,"TFT"); // mosi, miso, sclk, cs, reset, dc // LED on 3.3V with 1Kohm SDFileSystem sd(MOSD, MISD, SCSD, PD_2, "sd",NC,SDFileSystem::SWITCH_NONE,2500000); // mosi, miso, sclk, cs, cd unused, switchtype, speed spi char desfile[25]; char patfile[25]; char filename[25]; const int tmarray = nc*2*nl; unsigned char bank[tmarray]; unsigned char bankt[nl][nc]; unsigned char bankf[tmarray]; unsigned char banktc[nl][nc]; float meas0,measold0,meas1,measold1,meas2,measold2, meas3, measold3; int volatile statc=0; bool volatile captur =false; FILE *fp; void pressed() { wait (0.1); if (my_button==0) { if (statc==0) { pc.printf("capture requested\r\n"); captur=true; TFT.foreground(Red); TFT.locate(0,0); } if (statc==1) { pc.printf("visu \r\n"); fp = fopen(desfile, "r"); for (int i=0; i<tmarray; i++) { bankf[i] =fgetc(fp); } fclose(fp); } if (statc==2) { statc=0; } else { statc=statc+1; } } } void pressedtargnewca() { //start from first image cat extract target in desfile wait (0.1); if (my_button==0) { if (statc==0) { pc.printf("capture target requested \r\n"); //imagetr.rgbtoy(); imagetr.ytorgb(banktc); fp = fopen(desfile, "w"); for (int i=0; i<tmarray; i++) { fputc(bank[i], fp); } TFT.Bitmap(160,0,160,120,bank); pc.printf("captured target done \r\n"); TFT.foreground(Green); TFT.locate(0,0); printf(" capture done"); fclose(fp); pc.printf("open target file \r\n"); fp = fopen(desfile, "r"); for (int i=0; i<tmarray; i++) { bank[i] =fgetc(fp); } fclose(fp); TFT.Bitmap(0,120,160,120,bank); imagetr.rgbtoy(); imagetr.ytorgb(bankt); } if (statc==1) { printf(" target capture done"); imagetr.extrta(); imagetr.ytorgbta(bankta,0,patfile); TFT.fillrect(160,0,160,240,Green); TFT.Bitmap(160,10,ncta,nlta,bank); pc.printf("clear bank \r\n"); for (int i=0; i<tmarray; i++) { bank[i]=78; } fp = fopen(patfile, "r"); pc.printf("get targetf \r\n"); for (int i=0; i<tmarrayta; i++) { bank[i] =fgetc(fp); } fclose(fp); imagetr.rgbtoyta(); for (int i = 0; i<7; i++) { imagetr.ytorgbtas(bankta,i); TFT.Bitmap(40*(i/3),120+30* (i%3),ncta,nlta,bank); } } if (statc==2) { statc=0; } else { statc=statc+1; } pc.printf("new s:%d \r\n", statc); } } void pressedtargca() { //start from first image from camera extract wait (0.1); if (my_button==0) { if (statc==0) { pc.printf("view \r\n"); } if (statc==1) { pc.printf("search \r\n"); } if (statc==2) { statc=0; } else { statc=statc+1; } } } void sdtofile(const char sou[],const char des[]) { pc.printf("open .bmp \r\n"); int err = imagetr.BMP_tofile(0, 0, sou); if (err != 1) TFT.printf(" - Err: %d",err); TFT.Bitmap(0,0,160,120,bank); pc.printf("open .txt in write \r\n"); fp = fopen(des, "w"); for (int i=0; i<tmarray; i++) { fputc(bank[i], fp); } fclose(fp); pc.printf("open .txt in read \r\n"); fp = fopen(des, "r"); for (int i=0; i<tmarray; i++) { bank[i] =fgetc(fp); } fclose(fp); TFT.Bitmap(0,120,160,120,bank); } void pressedtargsd() { //start from first image in bankt extract target in bankta generate different target wait (0.1); if (my_button==0) { imagetr.extrta(); imagetr.ytorgbta(bankta,0,desfile); TFT.Bitmap(160,10,ncta,nlta,bank); TFT.fillrect(0,120,160,240,Green); pc.printf("clear bank \r\n"); for (int i=0; i<tmarray; i++) { bank[i]=78; } fp = fopen(desfile, "r"); pc.printf("get targetf \r\n"); for (int i=0; i<tmarrayta; i++) { bank[i] =fgetc(fp); } fclose(fp); imagetr.rgbtoyta(); TFT.Bitmap(0,120,ncta,nlta,bank); for (int i = 0; i<7; i++) { imagetr.ytorgbtas(bankta,i); TFT.Bitmap(40*(i/3),120+30* (i%3),ncta,nlta,bank); } //sdtofile(des); } } void affinem(bool rec) { bool c = false; float ad; meas0 = analog_value0.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas0 = meas0 * 320-160 ; // x colonnes if( fabs(meas0-measold0)>1 ) { measold0=meas0; c=true; } meas1 = analog_value1.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas1 = meas1 * 240 -120; // y lines if( fabs(meas1-measold1)>1 ) { measold1=meas1; c=true; } meas2 = analog_value2.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas2 = meas2 -0.5f; // angle -0.5 a +0.5 (radiant) if( fabs(meas2-measold2)>0.1f ) { measold2=meas2; c=true; } meas3 = analog_value3.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas3 = 0.5f + (meas3 * 1.5f); // zoom max1.5 if( fabs(meas3-measold3)>0.5f ) { measold3=meas3; c=true; } if(c) { ad=180*meas2/3.14f; TFT.foreground(White); pc.printf("x: %d, y: %d, angle: %.2f zoom: %.2f \r\n", int(meas0),int(meas1), meas2, meas3); TFT.locate(170,45); printf("x %d",int(meas0)); TFT.locate(170,65); printf("y %d",int(meas1)); TFT.locate(170,105); printf("zoom %.2f",meas3); TFT.locate(170,85); printf("angle %.2f",ad); // imagetr.affine(0,0,0, 1.2); imagetr.affine(meas1,meas0,meas2, meas3); if (rec) { TFT.rect(160,120,160+ncta,120+nlta,Red); } } } void gentam(void) { bool c = false; float ad; meas0 = analog_value0.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas0 = meas0 * 0.2f + 0.8f; // tilt x 0-20% if( fabs(meas0-measold0)>0.05f ) { measold0=meas0; c=true; } meas1 = analog_value1.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas1 = meas1 * 0.2f+0.8f; // tilt y lines 0-20% if( fabs(meas1-measold1)>0.05f ) { measold1=meas1; c=true; } meas2 = analog_value2.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas2 = meas2 -0.5f; // angle -0.5 a +0.5 (radiant) if( fabs(meas2-measold2)>0.1f ) { measold2=meas2; c=true; } meas3 = analog_value3.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas3 = 0.5f + (meas3 * 1.5f); // zoom max1.5 if( fabs(meas3-measold3)>0.3f ) { measold3=meas3; c=true; } if(c) { ad=180*meas2/3.14f; TFT.foreground(White); //pc.printf("x: %d, y: %d, angle: %.2f zoom: %.2f \r\n", int(meas0),int(meas1), meas2, meas3); TFT.locate(170,45); printf("tiltx %2f",meas0); TFT.locate(170,65); printf("tilty %2f",meas1); TFT.locate(170,105); printf("zoom %.2f",meas3); TFT.locate(170,85); printf("angle %.2f",ad); // imagetr.affine(0,0,0, 1.2); imagetr.genta(meas1,meas0,meas2, meas3); } } void luma(void) { float meas,measold; meas = analog_value3.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas = meas * 3; // 0 a 10 if( fabs(meas-measold)>0.1f ) { pc.printf("lumi: %04f \r\n", meas); TFT.locate(170,85); TFT.foreground(White); printf("lumi %f",meas); imagetr.lumi(meas); measold=meas; } } void searchp(void) { bool c = false; float ad; meas0 = analog_value0.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas0 = meas0 * 320-160 ; // x colonnes if( fabs(meas0-measold0)>1 ) { measold0=meas0; c=true; } meas1 = analog_value1.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas1 = meas1 * 1000000; // 0 a 4000 if( fabs(meas1-measold1)>200 ) { c=true; } meas2 = analog_value2.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas2 = meas2 -0.5f; // angle -0.5 a +0.5 (radiant) if( fabs(meas2-measold2)>0.1f ) { measold2=meas2; c=true; } meas3 = analog_value3.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas3 = 0.5f + (meas3 * 1.5f); // zoom max1.5 if( fabs(meas3-measold3)>0.5f ) { measold3=meas3; c=true; } if(c) { ad=180*meas2/3.14f; TFT.foreground(White); //pc.printf("x: %d, y: %d, angle: %.2f zoom: %.2f \r\n", int(meas0),int(meas1), meas2, meas3); TFT.locate(170,45); printf("x %3d",int(meas0)); TFT.locate(170,65); printf("threshold %6d",int(meas1)); TFT.locate(170,105); printf("zoom %.2f",meas3); TFT.locate(170,85); printf("angle %.2f",ad); imagetr.affine(0,meas0,meas2, meas3); imagetr.searchpat(meas1); } } void viewf(void) { imagetr.ytorgb(banktc); TFT.Bitmap(160,120,160,120,bank); } void extedgem(void) { bool c = false; meas0 = analog_value0.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas0 = meas0 * 50; // 0 to 50 max threshod if( fabs(meas0-measold0)>1) { measold0=meas0; c=true; } meas1 = analog_value1.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas1 = meas1 * 50 ; // min threshold 0 50 if( fabs(meas1-measold1)>1 ) { measold1=meas1; c=true; } meas2 = analog_value2.read(); // Converts and read the analog input value (value from 0.0 to 1.0) meas2 = meas2 * 5 ; // thrshold if( fabs(meas2-measold2)>1 ) { measold2=meas2; c=true; } if (c) { //pc.printf("x: %d, y: %d \r\n", int(meas0),int(meas1)); imagetr.extedge(meas1,meas0, meas2); } } void loadtargettxt(const char sou[]) { imagetr.getimage(sou); TFT.Bitmap(0,0,160,120,bank); imagetr.rgbtoy(); imagetr.ytorgb(bankt); TFT.Bitmap(160,120,160,120,bank); } void loadtarget(const char sou[]) { int err = imagetr.BMP_tofile(0, 0, sou); if (err != 1) TFT.printf(" - Err: %d",err); TFT.Bitmap(0,0,160,120,bank); imagetr.rgbtoy(); //imagetr.ytorgb(bankt); //TFT.Bitmap(160,120,160,120,bank); } void loadtargeted(const char sou[]) { int err = imagetr.BMP_tofile(0, 0, sou); if (err != 1) TFT.printf(" - Err: %d",err); TFT.Bitmap(0,0,160,120,bank); imagetr.rgbtoy(); imagetr.extedge(0,0,2); for (int i=0; i<nl; i=i+1) { for (int j=0; j<nc; j=j+1) { bankt[i][j]= banktc[i][j]; } } imagetr.ytorgb(bankt); TFT.Bitmap(160,120,160,120,bank); } void loadpat(const char pat[]) { imagetr.getimage(pat); TFT.Bitmap(160,0,ncta,nlta,bank); imagetr.rgbtoyta(); for (int i = 0; i<7; i++) { imagetr.ytorgbtas(bankta,i); TFT.Bitmap(40*(i/3),120+30* (i%3),ncta,nlta,bank); } } void loadpated(const char pat[]) { imagetr.getimage(pat); TFT.Bitmap(160,0,ncta,nlta,bank); imagetr.rgbtoytaed(); for (int i = 0; i<7; i++) { imagetr.ytorgbtas(bankta,i); TFT.Bitmap(40*(i/3),120+30* (i%3),ncta,nlta,bank); } } void readregister() { int tempo ; pc.printf("PID %02x \r\n", OV7670.ReadReg(REG_PID)); pc.printf("VER %0.2x \r\n", OV7670.ReadReg(REG_VER)); pc.printf("Lecture Registres...\r\n") ; pc.printf("AD : +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F") ; for (int i=0; i<OV7670_REGMAX; i++) { tempo = OV7670.ReadReg(i) ; // READ REG if ((i & 0x0F) == 0) { pc.printf("\r\n%02X : ",i) ; } pc.printf("%02X ",tempo) ; } pc.printf("\r\n") ; } void testsd(void) { //Perform a write test to SD // Set up the SD sd.disk_initialize(); pc.printf("\nWriting to SD card..."); fp = fopen("/sd/sdtest.txt", "w"); if (fp != NULL) { fprintf(fp, "We're writing to an SD card!"); fclose(fp); pc.printf("success!\r\n"); } else { pc.printf("failed!\r\n"); } //Perform a read test pc.printf("Reading from SD card..."); fp = fopen("/sd/sdtest.txt", "r"); if (fp != NULL) { char c = fgetc(fp); if (c == 'W') pc.printf("success!\r\n"); else pc.printf("incorrect char (%c)!\r\n", c); fclose(fp); } else { pc.printf("failed!\r\n"); } } void capturecycle(const char des[]) { strcpy( desfile,des); if (statc==0||statc==1) { OV7670.CaptureNext() ; OV7670.exrgbf(0); TFT.Bitmap(0,120,160,120,bankf); OV7670.exrgbf(1); TFT.Bitmap(160,120,160,120,bankf); OV7670.exrgbf(2); TFT.Bitmap(0,0,160,120,bankf); OV7670.exrgbf(3); TFT.Bitmap(160,0,160,120,bankf); } if (statc==2) { OV7670.CaptureNext() ; TFT.fillrect(0,120,160,240,Green); TFT.fillrect(160,0,320,120,Green); TFT.foreground(Yellow); TFT.locate(170,108); printf("captured picture"); TFT.Bitmap(0,0,160,120,bank); TFT.Bitmap(160,120,160,120,bankf); } } void epatternmatch(const char tar[],const char pat[]) { int i=0; loadtarget(tar); loadpat(pat); for (i=0; i<25; i++) { filename[i]=pat[i+4]; } pc . printf("f : %s\r\n", filename); TFT.set_font((unsigned char*) Arial12x12); TFT.foreground(Red); } void epatternmatched(const char tar[],const char pat[]) { int i=0; loadtargeted(tar); loadpated(pat); for (i=0; i<25; i++) { filename[i]=pat[i+4]; } pc . printf("f : %s\r\n", filename); TFT.set_font((unsigned char*) Arial12x12); TFT.foreground(Red); } void epatca(const char tar[],const char pat[]) { loadtargettxt(tar); loadpat(pat); TFT.set_font((unsigned char*) Arial12x12); TFT.foreground(Red); } void patternmatch(const char pat[]) { my_button.fall(&pressedtargca); OV7670.CaptureNext() ; TFT.Bitmap(0,0,160,120,bank); loadpat(pat); TFT.set_font((unsigned char*) Arial12x12); TFT.foreground(Red); } void targetfromca(const char des[],const char pat[]) { OV7670.CaptureNext() ; TFT.Bitmap(0,0,160,120,bank); imagetr.rgbtoy(); strcpy( desfile,des); strcpy( patfile,pat); my_button.fall(&pressedtargnewca); } void loadnewca() { OV7670.CaptureNext() ; TFT.Bitmap(0,0,160,120,bank); imagetr.rgbtoy(); } void targetfromsd(const char sou[],const char des[]) { int err = imagetr.BMP_tofile(0, 0, sou); if (err != 1) pc.printf(" - Err: %d",err); TFT.Bitmap(0,0,160,120,bank); imagetr.rgbtoy(); strcpy( desfile,des); TFT.rect(160,120,160+ncta,120+nlta,Red); my_button.fall(&pressedtargsd); } int main() { myled=0; statc=0; // Set up the TFT TFT.claim(stdout); // Send stdout to the TFT display TFT.background(Black); // Set background to black TFT.foreground(White); // Set chars to white TFT.cls(); // Clear the screen TFT.set_font((unsigned char*) Arial12x12); // Select the font TFT.set_orientation(3); // Select orientation TFT.locate(0,0); printf(" Hello Mbed "); OV7670.Reset(); OV7670.Init("RGB", QQVGA); pc.printf("Hello World !\r\n"); ////////////////////////////////////////////////////////// // to view camera my_button.fall(&pressed); while (1) { capturecycle("/sd/picture.txt"); } } ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// // to create a target from a .bmp to sd /* targetfromsd("/sd/manchodou.bmp","/sd/manchodou.txt"); while (1) { viewf(); __disable_irq(); // Disable Interrupts affinem(true); __enable_irq(); // Enable Interrupts } } */ ////////////////////////////////////////////////////////// // to recognise a target from bmp and target on sd /* epatternmatch("/sd/manchodou.bmp","/sd/manchodou.txt"); while (1) { viewf(); searchp(); } } */ ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// // to recognise a target from bmp and target on sd, on edge /* epatternmatched("/sd/manchodou.bmp","/sd/manchodou.txt"); while (1) { viewf(); searchp(); } } */ ////////////////////////////////////////////////////////// //to create a target from camera /* targetfromca("/sd/man.txt","/sd/man2.txt"); while (1) { __disable_irq(); // Disable Interrupts if (statc==0) { loadnewca(); } affinem(true); __enable_irq(); // Enable Interrupts // if (statc==0) { searchp();} else {affinem(false);} viewf(); } } */ //////////////////////////////////////////// //to search pattern from .txt /* epatca("/sd/man.txt","/sd/man2.txt"); while (1) { viewf(); searchp(); } } */ //////////////////////////////////////////// //to search pattern from camera /* patternmatch("/sd/man2.txt"); while (1) { loadnewca(); viewf(); if (statc==0) { searchp(); } else { affinem(false); } } } */ //////////////////////////////////////////// // to extract edge from image in bmp /* loadtarget("/sd/manchodou.bmp"); while (1) { viewf(); extedgem(); } } */