Touchscreen digit recognition.

Dependencies:   mbed TFT_fonts SPI_TFT_ILI9341 Adafruit_GFX FT6206 MMA8451Q

Revision:
1:c44001c6bbf8
Parent:
0:5264c6cecce9
Child:
2:1ab6ba7c2c90
--- a/main.cpp	Mon Mar 23 20:02:09 2015 +0000
+++ b/main.cpp	Thu Jan 16 23:07:38 2020 +0000
@@ -1,8 +1,29 @@
 #include "mbed.h"
 #include "SPI_TFT_ILI9341.h"
 #include "FT6206.h"
+#include <algorithm>
+#include <string>
+#include "weigths.hpp"
+
+// Accelorameter
+#include "MMA8451Q.h"
+#if   defined (TARGET_KL25Z) || defined (TARGET_KL46Z)
+  PinName const SDA = PTE25;
+  PinName const SCL = PTE24;
+#elif defined (TARGET_KL05Z)
+  PinName const SDA = PTB4;
+  PinName const SCL = PTB3;
+#elif defined (TARGET_K20D50M)
+  PinName const SDA = PTB1;
+  PinName const SCL = PTB0;
+#else
+  #error TARGET NOT DEFINED
+#endif
+#define MMA8451_I2C_ADDRESS (0x1d<<1)
 
 #include "Arial12x12.h"
+#include "Arial24x23.h"
+#include "Arial28x28.h"
 
 #define PIN_XP          A3
 #define PIN_XM          A1
@@ -20,8 +41,8 @@
 #define PORTRAIT        0
 #define LANDSCAPE       1
 
-#define PIN_SCL_FT6206  P0_28
-#define PIN_SDA_FT6206  P0_27
+#define PIN_SCL_FT6206  A5
+#define PIN_SDA_FT6206  A4
 #define PIN_INT_FT6206  D7
 
 #define ILI9341_TFTWIDTH  320
@@ -33,66 +54,302 @@
 DigitalOut led4(LED4);
 
 //SPI_TFT_ILI9341 TFT(p5, p6, p7, p8, p9, p10,"TFT"); // mosi, miso, sclk, cs, reset, dc
-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 
+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
 FT6206 FT6206(PIN_SDA_FT6206, PIN_SCL_FT6206, PIN_INT_FT6206); // sda, scl, int
+MMA8451Q acc(SDA, SCL, MMA8451_I2C_ADDRESS);
 
-int main()
+int maxIndex(float vector_name[])
+{
+    double max = vector_name[0];
+    int index = 0;
+    for (int i = 0; i != 10; i++) {
+        if (max < vector_name[i]) {
+            max = vector_name[i];
+            index = i;
+        }
+    }
+    return index;
+}
+
+float RELU(float x)
+{
+    return std::max(0.0f, x);
+}
+
+int FeedForward()
+{
+    float convImages[kernel_count][convImageSize][convImageSize] = {0.0f};
+
+    for (unsigned f = 0; f != kernel_count; f++) {
+        for (unsigned i = 0; i <= image_size - kernel_size; i += stride) {
+            for (unsigned j = 0; j <= image_size - kernel_size; j += stride) {
+                for (unsigned k = i; k < i + kernel_size; k++) {
+                    for (unsigned l = j; l < j + kernel_size; l++) {
+                        convImages[f][i / stride][j / stride] += image[k][l] * kernels[f][k - i][l - j];
+                    }
+                }
+                convImages[f][i / stride][j / stride] += bias_kernels[f];
+            }
+        }
+    }    
+
+    unsigned elem = 0;
+    for (unsigned f = 0; f != kernel_count; f++) {
+        for (unsigned j = 0; j != convImageSize; j++) {
+            for (unsigned k = 0; k != convImageSize; k++) {
+                activated[elem++] = RELU(convImages[f][j][k]);
+            }
+        }
+    }
+
+    float z[10] = {0.0f};
+    for (unsigned i = 0; i != 10; i++) {
+        z[i] = 0.0f;
+        for (unsigned j = 0; j != kernel_count * convImageSize * convImageSize; j++) {
+            z[i] += weights[i][j] * activated[j];
+        }
+        z[i] += bias_weights[i];
+    }
+    int ymax = maxIndex(z);
+    return ymax;
+}
+
+void landscapeInit()
 {
     //Configure the display driver
     TFT.claim(stdout);
-    TFT.background(Black);
-    TFT.foreground(White);
+    TFT.background(LightGrey);
+    TFT.foreground(Green);
     TFT.set_orientation(LANDSCAPE);
     TFT.cls();
 
     //Print a welcome message
+    TFT.fillrect(240, 25, 292, 45, Red);
     TFT.set_font((unsigned char*) Arial12x12);
-    TFT.locate(0,0);
-    TFT.printf("Hello mbed!\n");
+    TFT.locate(245, 30);
+    TFT.background(Red);
+    TFT.printf("Guess");
+
+    //Print a welcome message
+    TFT.fillrect(240, 205, 292, 225, Red);
+    TFT.set_font((unsigned char*) Arial12x12);
+    TFT.locate(245, 210);
+    TFT.background(Red);
+    TFT.printf("Clear");
+
+    TFT.fillrect(20, 50, 160, 190, DarkGrey);
+}
+
+void portraitInit()
+{
+    //Configure the display driver
+    TFT.claim(stdout);
+    TFT.background(LightGrey);
+    TFT.foreground(Green);
+    TFT.set_orientation(PORTRAIT);
+    TFT.cls();
+
+    //Print a welcome message
+    TFT.fillrect(15, 25, 67, 45, Red);
+    TFT.set_font((unsigned char*) Arial12x12);
+    TFT.locate(20, 30);
+    TFT.background(Red);
+    TFT.printf("Guess");
 
-    FT6206.begin();
-    int X1, Y1, X2, Y2;
-    X2 = -100;
-    while(1) {
-//        if (FT6206.touched()) {
-        if (FT6206.dataReceived()) {
-//            led1 = !led1;
-            // Retrieve a point  
-            TS_Point p = FT6206.getPoint();
-            X1 = X2;
-            Y1 = Y2;
-            X2 = p.x;
-            Y2 = p.y;
-//            printf("Touch %3d %3d\n", p.x, p.y);
-            if ((X1 > 0) && (Y1 > 0) && (X2 > 0) && (Y2 > 0)) {
-                TFT.line(X1, Y1, X2, Y2, Yellow);
-            }
+    //Print a welcome message
+    TFT.fillrect(160, 25, 212, 45, Red);
+    TFT.set_font((unsigned char*) Arial12x12);
+    TFT.locate(175, 30);
+    TFT.background(Red);
+    TFT.printf("Clear");
+
+    TFT.fillrect(50, 160, 190, 300, DarkGrey);
+}
+
+int main(void)
+{
+    // Get accelerometer data
+    float x, y, z;
+    x = abs(acc.getAccX());
+    y = abs(acc.getAccY());
+    z = abs(acc.getAccZ());
+    bool horizontal = z < 0.5 ? y > x : true;
+    bool currentHorizontal = horizontal;
+    
+    if (currentHorizontal)
+        landscapeInit();
+    else
+        portraitInit();
+    
+    
+    // Initialize weights
+    for (unsigned i = 0; i != 28; i++)
+    {
+        for (unsigned j = 0; j != 28; j++)
+        {
+            image[i][j] = -0.5f;
         }
+    }
+
 
 
-//        TFT.printf("Jacksoft\n");
-//        wait(0.05);
+    FT6206.begin();
+    while(1)
+    {
+        for (unsigned int i = 0; i != 1000000; i++) {
+        if (i == 0) {
+            // Get accelerometer data
+            float x, y, z;
+            
+            x = abs(acc.getAccX());
+            y = abs(acc.getAccY());
+            z = abs(acc.getAccZ());
+            
+            horizontal = z < 0.5 ? y > x : horizontal;
+        }
+        
+        if (currentHorizontal != horizontal)
+        {
+            currentHorizontal = horizontal;
+            if (currentHorizontal)
+                landscapeInit();
+            else
+                portraitInit();
+        }
+                
+        
+        if (FT6206.dataReceived())
+        {
+            TS_Point p = FT6206.getPoint();
+            
+            
+            if (horizontal) {
+            
+            if (p.x >= 25 and p.x <= 155 and p.y >= 55 and p.y <= 185)
+            {
+                // Handwriting panel has been pressed
+                TFT.fillcircle(p.x, p.y, 4, Yellow);
+                int image_y = (p.x-20)/5;
+                int image_x = (p.y-50)/5;
+                if (image_x > 0 and image_y > 0)
+                {
+                    image[image_x-1][image_y-1] = 0.5f;
+                    image[image_x-1][image_y] = 0.5f;
+                    image[image_x-1][image_y+1] = 0.5f;
+                    image[image_x][image_y-1] = 0.5f;
+                    image[image_x][image_y] = 0.5f;
+                    image[image_x][image_y+1] = 0.5f;
+                    image[image_x+1][image_y-1] = 0.5f;
+                    image[image_x+1][image_y] = 0.5f;
+                    image[image_x+1][image_y+1] = 0.5f;
+                }
+            } 
+            else if (p.y >= 0 and p.y <= 60 and p.x >= 200 and p.x <= 320)
+            {
+                // Guess button has been pressed
+                TFT.fillrect(180, 50, 320, 190, LightGrey);
+                char prediction = FeedForward();
+                TFT.locate(270, 110);
+                TFT.background(LightGrey);
+                TFT.foreground(Green);
+                
+                TFT.set_font((unsigned char*) Arial28x28);
+                switch (prediction)
+                {
+                    case 0: TFT.printf("0"); break;
+                    case 1: TFT.printf("1"); break;
+                    case 2: TFT.printf("2"); break;
+                    case 3: TFT.printf("3"); break;
+                    case 4: TFT.printf("4"); break;
+                    case 5: TFT.printf("5"); break;
+                    case 6: TFT.printf("6"); break;
+                    case 7: TFT.printf("7"); break;
+                    case 8: TFT.printf("8"); break;
+                    case 9: TFT.printf("9"); break;
+                    default: TFT.printf("noidea\n");
+                }
+            } 
+            else if (p.y >= 185 and p.y <= 240 and p.x >= 220 and p.x <= 320)
+            {
+                // Clear button has been pressed
+                TFT.fillrect(15, 45, 165, 195, LightGrey);
+                TFT.fillrect(20, 50, 160, 190, DarkGrey);
+                for (unsigned i = 0; i != 28; i++)
+                {
+                    for (unsigned j = 0; j != 28; j++)
+                    {
+                        image[i][j] = -0.5f;
+                    }
+                }
+            }
+            //horizantal end
+            }
+            else
+            {
+            if (p.x >= 160 and p.x <= 300 and p.y >= 50 and p.y <= 190)
+            {
+                // Handwriting panel has been pressed
+                TFT.fillcircle(240-p.y, p.x, 4, Yellow);
+                int image_x = (p.x-160)/5;
+                int image_y = (240- p.y-50)/5;
+                if (image_x > 0 and image_y > 0)
+                {
+                    image[image_x-1][image_y-1] = 0.5f;
+                    image[image_x-1][image_y] = 0.5f;
+                    image[image_x-1][image_y+1] = 0.5f;
+                    image[image_x][image_y-1] = 0.5f;
+                    image[image_x][image_y] = 0.5f;
+                    image[image_x][image_y+1] = 0.5f;
+                    image[image_x+1][image_y-1] = 0.5f;
+                    image[image_x+1][image_y] = 0.5f;
+                    image[image_x+1][image_y+1] = 0.5f;
+                }
+            } 
+            else if (p.y >= 140 and p.y <= 240 and p.x >= 1 and p.x <= 70)
+            {
+                // Guess button has been pressed
+                TFT.fillrect(90, 0, 140, 60, LightGrey);
+                char prediction = FeedForward();
+                TFT.locate(110, 30);
+                TFT.background(LightGrey);
+                TFT.foreground(Green);
+                
+                TFT.set_font((unsigned char*) Arial28x28);
+                switch (prediction)
+                {
+                    case 0: TFT.printf("0"); break;
+                    case 1: TFT.printf("1"); break;
+                    case 2: TFT.printf("2"); break;
+                    case 3: TFT.printf("3"); break;
+                    case 4: TFT.printf("4"); break;
+                    case 5: TFT.printf("5"); break;
+                    case 6: TFT.printf("6"); break;
+                    case 7: TFT.printf("7"); break;
+                    case 8: TFT.printf("8"); break;
+                    case 9: TFT.printf("9"); break;
+                    default: TFT.printf("noidea\n");
+                }
+            } 
+            else if (p.y >= 1 and p.y <= 80 and p.x >= 0 and p.x <= 70)
+            {
+                // Clear button has been pressed
+                TFT.fillrect(45, 155, 195, 305, LightGrey);
+                TFT.fillrect(50, 160, 190, 300, DarkGrey);
+                for (unsigned i = 0; i != 28; i++)
+                {
+                    for (unsigned j = 0; j != 28; j++)
+                    {
+                        image[i][j] = -0.5f;
+                    }
+                }
+            }   
+                
+            // portrait end   
+            }
+            
+            
+            
+        }
+        }
     }
 }
-
-
-/*
-#include "mbed.h"
-
-PwmOut mypwm(PWM_OUT);
-
-DigitalOut myled(LED1);
-
-int main() {
-    
-    mypwm.period_ms(10);
-    mypwm.pulsewidth_ms(1);
-  
-    printf("pwm set to %.2f %%\n", mypwm.read() * 100);
-    
-    while(1) {
-        myled = !myled;
-        wait(1);
-    }
-}
-*/