Touchscreen digit recognition.
Dependencies: mbed TFT_fonts SPI_TFT_ILI9341 Adafruit_GFX FT6206 MMA8451Q
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 }
Generated on Thu Jul 14 2022 14:36:11 by 1.7.2