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