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

Dependents:   Practica4_Camara

main.cpp

Committer:
sylvainkritter
Date:
2016-02-16
Revision:
0:39c9f3b49f5a
Child:
1:7fbc24ad0958

File content as of revision 0:39c9f3b49f5a:

#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 PB13
#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


#define VGA     307200         //640*480
#define QVGA    76800          //320*240
#define QQVGA   19200          //160*120


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;


Serial pc(USBTX,USBRX);
//camera
OV7670 OV7670(I2C_D,I2C_CLK,XCLK,PortC,mask,RESET);

// 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
// image transformation
//imagetr imagetr;

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();
    }
}
*/