Touchscreen digit recognition

Dependencies:   mbed TFT_fonts SPI_TFT_ILI9341 Adafruit_GFX FT6206 MMA8451Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "SPI_TFT_ILI9341.h"
00003 #include "FT6206.h"
00004 #include <algorithm>
00005 #include <string>
00006 #include "weigths.hpp"
00007 
00008 // Accelorameter
00009 #include "MMA8451Q.h"
00010 #if   defined (TARGET_KL25Z) || defined (TARGET_KL46Z)
00011   PinName const SDA = PTE25;
00012   PinName const SCL = PTE24;
00013 #elif defined (TARGET_KL05Z)
00014   PinName const SDA = PTB4;
00015   PinName const SCL = PTB3;
00016 #elif defined (TARGET_K20D50M)
00017   PinName const SDA = PTB1;
00018   PinName const SCL = PTB0;
00019 #else
00020   #error TARGET NOT DEFINED
00021 #endif
00022 #define MMA8451_I2C_ADDRESS (0x1d<<1)
00023 
00024 #include "Arial12x12.h"
00025 #include "Arial24x23.h"
00026 #include "Arial28x28.h"
00027 
00028 #define PIN_XP          A3
00029 #define PIN_XM          A1
00030 #define PIN_YP          A2
00031 #define PIN_YM          A0
00032 #define PIN_SCLK        D13
00033 #define PIN_MISO        D12
00034 #define PIN_MOSI        D11
00035 #define PIN_CS_TFT      D10  // chip select pin
00036 #define PIN_DC_TFT      D9   // data/command select pin.
00037 #define PIN_RESET_TFT   D8
00038 //#define PIN_BL_TFT      D7
00039 #define PIN_CS_SD       D4
00040 
00041 #define PORTRAIT        0
00042 #define LANDSCAPE       1
00043 
00044 #define PIN_SCL_FT6206  A5
00045 #define PIN_SDA_FT6206  A4
00046 #define PIN_INT_FT6206  D7
00047 
00048 #define ILI9341_TFTWIDTH  320
00049 #define ILI9341_TFTHEIGHT 240
00050 
00051 DigitalOut led1(LED1);
00052 DigitalOut led2(LED2);
00053 DigitalOut led3(LED3);
00054 DigitalOut led4(LED4);
00055 
00056 //SPI_TFT_ILI9341 TFT(p5, p6, p7, p8, p9, p10,"TFT"); // mosi, miso, sclk, cs, reset, dc
00057 SPI_TFT_ILI9341 TFT(PIN_MOSI, PIN_MISO, PIN_SCLK, PIN_CS_TFT, PIN_RESET_TFT, PIN_DC_TFT, "TFT"); // mosi, miso, sclk, cs, reset, dc
00058 FT6206 FT6206(PIN_SDA_FT6206, PIN_SCL_FT6206, PIN_INT_FT6206); // sda, scl, int
00059 MMA8451Q acc(SDA, SCL, MMA8451_I2C_ADDRESS);
00060 
00061 int maxIndex(float vector_name[])
00062 {
00063     double max = vector_name[0];
00064     int index = 0;
00065     for (int i = 0; i != 10; i++) {
00066         if (max < vector_name[i]) {
00067             max = vector_name[i];
00068             index = i;
00069         }
00070     }
00071     return index;
00072 }
00073 
00074 float RELU(float x)
00075 {
00076     return std::max(0.0f, x);
00077 }
00078 
00079 int FeedForward()
00080 {
00081     float convImages[kernel_count][convImageSize][convImageSize] = {0.0f};
00082 
00083     for (unsigned f = 0; f != kernel_count; f++) {
00084         for (unsigned i = 0; i <= image_size - kernel_size; i += stride) {
00085             for (unsigned j = 0; j <= image_size - kernel_size; j += stride) {
00086                 for (unsigned k = i; k < i + kernel_size; k++) {
00087                     for (unsigned l = j; l < j + kernel_size; l++) {
00088                         convImages[f][i / stride][j / stride] += image[k][l] * kernels[f][k - i][l - j];
00089                     }
00090                 }
00091                 convImages[f][i / stride][j / stride] += bias_kernels[f];
00092             }
00093         }
00094     }    
00095 
00096     unsigned elem = 0;
00097     for (unsigned f = 0; f != kernel_count; f++) {
00098         for (unsigned j = 0; j != convImageSize; j++) {
00099             for (unsigned k = 0; k != convImageSize; k++) {
00100                 activated[elem++] = RELU(convImages[f][j][k]);
00101             }
00102         }
00103     }
00104 
00105     float z[10] = {0.0f};
00106     for (unsigned i = 0; i != 10; i++) {
00107         z[i] = 0.0f;
00108         for (unsigned j = 0; j != kernel_count * convImageSize * convImageSize; j++) {
00109             z[i] += weights[i][j] * activated[j];
00110         }
00111         z[i] += bias_weights[i];
00112     }
00113     int ymax = maxIndex(z);
00114     return ymax;
00115 }
00116 
00117 void landscapeInit()
00118 {
00119     //Configure the display driver
00120     TFT.claim(stdout);
00121     TFT.background(LightGrey);
00122     TFT.foreground(Green);
00123     TFT.set_orientation(LANDSCAPE);
00124     TFT.cls();
00125 
00126     //Print a welcome message
00127     TFT.fillrect(240, 25, 292, 45, Red);
00128     TFT.set_font((unsigned char*) Arial12x12);
00129     TFT.locate(245, 30);
00130     TFT.background(Red);
00131     TFT.printf("Guess");
00132 
00133     //Print a welcome message
00134     TFT.fillrect(240, 205, 292, 225, Red);
00135     TFT.set_font((unsigned char*) Arial12x12);
00136     TFT.locate(245, 210);
00137     TFT.background(Red);
00138     TFT.printf("Clear");
00139 
00140     TFT.fillrect(20, 50, 160, 190, DarkGrey);
00141 }
00142 
00143 void portraitInit()
00144 {
00145     //Configure the display driver
00146     TFT.claim(stdout);
00147     TFT.background(LightGrey);
00148     TFT.foreground(Green);
00149     TFT.set_orientation(PORTRAIT);
00150     TFT.cls();
00151 
00152     //Print a welcome message
00153     TFT.fillrect(15, 25, 67, 45, Red);
00154     TFT.set_font((unsigned char*) Arial12x12);
00155     TFT.locate(20, 30);
00156     TFT.background(Red);
00157     TFT.printf("Guess");
00158 
00159     //Print a welcome message
00160     TFT.fillrect(160, 25, 212, 45, Red);
00161     TFT.set_font((unsigned char*) Arial12x12);
00162     TFT.locate(175, 30);
00163     TFT.background(Red);
00164     TFT.printf("Clear");
00165 
00166     TFT.fillrect(50, 160, 190, 300, DarkGrey);
00167 }
00168 
00169 int main(void)
00170 {
00171     // Get accelerometer data
00172     float x, y, z;
00173     x = abs(acc.getAccX());
00174     y = abs(acc.getAccY());
00175     z = abs(acc.getAccZ());
00176     bool horizontal = z < 0.5 ? y > x : true;
00177     bool currentHorizontal = horizontal;
00178     
00179     if (currentHorizontal)
00180         landscapeInit();
00181     else
00182         portraitInit();
00183     
00184     
00185     // Initialize weights
00186     for (unsigned i = 0; i != 28; i++)
00187     {
00188         for (unsigned j = 0; j != 28; j++)
00189         {
00190             image[i][j] = -0.5f;
00191         }
00192     }
00193 
00194 
00195 
00196     FT6206.begin();
00197     while(1)
00198     {
00199         for (unsigned int i = 0; i != 1000000; i++) {
00200         if (i == 0) {
00201             // Get accelerometer data
00202             float x, y, z;
00203             
00204             x = abs(acc.getAccX());
00205             y = abs(acc.getAccY());
00206             z = abs(acc.getAccZ());
00207             
00208             horizontal = z < 0.5 ? y > x : horizontal;
00209         }
00210         
00211         if (currentHorizontal != horizontal)
00212         {
00213             currentHorizontal = horizontal;
00214             if (currentHorizontal)
00215                 landscapeInit();
00216             else
00217                 portraitInit();
00218         }
00219                 
00220         
00221         if (FT6206.dataReceived())
00222         {
00223             TS_Point p = FT6206.getPoint();
00224             
00225             
00226             if (horizontal) {
00227             
00228             if (p.x >= 25 and p.x <= 155 and p.y >= 55 and p.y <= 185)
00229             {
00230                 // Handwriting panel has been pressed
00231                 TFT.fillcircle(p.x, p.y, 4, Yellow);
00232                 int image_y = (p.x-20)/5;
00233                 int image_x = (p.y-50)/5;
00234                 if (image_x > 0 and image_y > 0)
00235                 {
00236                     image[image_x-1][image_y-1] = 0.5f;
00237                     image[image_x-1][image_y] = 0.5f;
00238                     image[image_x-1][image_y+1] = 0.5f;
00239                     image[image_x][image_y-1] = 0.5f;
00240                     image[image_x][image_y] = 0.5f;
00241                     image[image_x][image_y+1] = 0.5f;
00242                     image[image_x+1][image_y-1] = 0.5f;
00243                     image[image_x+1][image_y] = 0.5f;
00244                     image[image_x+1][image_y+1] = 0.5f;
00245                 }
00246             } 
00247             else if (p.y >= 0 and p.y <= 60 and p.x >= 200 and p.x <= 320)
00248             {
00249                 // Guess button has been pressed
00250                 TFT.fillrect(180, 50, 320, 190, LightGrey);
00251                 char prediction = FeedForward();
00252                 TFT.locate(270, 110);
00253                 TFT.background(LightGrey);
00254                 TFT.foreground(Green);
00255                 
00256                 TFT.set_font((unsigned char*) Arial28x28);
00257                 switch (prediction)
00258                 {
00259                     case 0: TFT.printf("0"); break;
00260                     case 1: TFT.printf("1"); break;
00261                     case 2: TFT.printf("2"); break;
00262                     case 3: TFT.printf("3"); break;
00263                     case 4: TFT.printf("4"); break;
00264                     case 5: TFT.printf("5"); break;
00265                     case 6: TFT.printf("6"); break;
00266                     case 7: TFT.printf("7"); break;
00267                     case 8: TFT.printf("8"); break;
00268                     case 9: TFT.printf("9"); break;
00269                     default: TFT.printf("noidea\n");
00270                 }
00271             } 
00272             else if (p.y >= 185 and p.y <= 240 and p.x >= 220 and p.x <= 320)
00273             {
00274                 // Clear button has been pressed
00275                 TFT.fillrect(15, 45, 165, 195, LightGrey);
00276                 TFT.fillrect(20, 50, 160, 190, DarkGrey);
00277                 for (unsigned i = 0; i != 28; i++)
00278                 {
00279                     for (unsigned j = 0; j != 28; j++)
00280                     {
00281                         image[i][j] = -0.5f;
00282                     }
00283                 }
00284             }
00285             //horizantal end
00286             }
00287             else
00288             {
00289             if (p.x >= 160 and p.x <= 300 and p.y >= 50 and p.y <= 190)
00290             {
00291                 // Handwriting panel has been pressed
00292                 TFT.fillcircle(240-p.y, p.x, 4, Yellow);
00293                 int image_x = (p.x-160)/5;
00294                 int image_y = (240- p.y-50)/5;
00295                 if (image_x > 0 and image_y > 0)
00296                 {
00297                     image[image_x-1][image_y-1] = 0.5f;
00298                     image[image_x-1][image_y] = 0.5f;
00299                     image[image_x-1][image_y+1] = 0.5f;
00300                     image[image_x][image_y-1] = 0.5f;
00301                     image[image_x][image_y] = 0.5f;
00302                     image[image_x][image_y+1] = 0.5f;
00303                     image[image_x+1][image_y-1] = 0.5f;
00304                     image[image_x+1][image_y] = 0.5f;
00305                     image[image_x+1][image_y+1] = 0.5f;
00306                 }
00307             } 
00308             else if (p.y >= 140 and p.y <= 240 and p.x >= 1 and p.x <= 70)
00309             {
00310                 // Guess button has been pressed
00311                 TFT.fillrect(90, 0, 140, 60, LightGrey);
00312                 char prediction = FeedForward();
00313                 TFT.locate(110, 30);
00314                 TFT.background(LightGrey);
00315                 TFT.foreground(Green);
00316                 
00317                 TFT.set_font((unsigned char*) Arial28x28);
00318                 switch (prediction)
00319                 {
00320                     case 0: TFT.printf("0"); break;
00321                     case 1: TFT.printf("1"); break;
00322                     case 2: TFT.printf("2"); break;
00323                     case 3: TFT.printf("3"); break;
00324                     case 4: TFT.printf("4"); break;
00325                     case 5: TFT.printf("5"); break;
00326                     case 6: TFT.printf("6"); break;
00327                     case 7: TFT.printf("7"); break;
00328                     case 8: TFT.printf("8"); break;
00329                     case 9: TFT.printf("9"); break;
00330                     default: TFT.printf("noidea\n");
00331                 }
00332             } 
00333             else if (p.y >= 1 and p.y <= 80 and p.x >= 0 and p.x <= 70)
00334             {
00335                 // Clear button has been pressed
00336                 TFT.fillrect(45, 155, 195, 305, LightGrey);
00337                 TFT.fillrect(50, 160, 190, 300, DarkGrey);
00338                 for (unsigned i = 0; i != 28; i++)
00339                 {
00340                     for (unsigned j = 0; j != 28; j++)
00341                     {
00342                         image[i][j] = -0.5f;
00343                     }
00344                 }
00345             }   
00346                 
00347             // portrait end   
00348             }
00349             
00350             
00351             
00352         }
00353         }
00354     }
00355 }