Touchscreen digit recognition.

Dependencies:   mbed TFT_fonts SPI_TFT_ILI9341 Adafruit_GFX FT6206 MMA8451Q

main.cpp

Committer:
rankedss
Date:
2020-01-16
Revision:
1:c44001c6bbf8
Parent:
0:5264c6cecce9
Child:
2:1ab6ba7c2c90

File content as of revision 1:c44001c6bbf8:

#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
#define PIN_YP          A2
#define PIN_YM          A0
#define PIN_SCLK        D13
#define PIN_MISO        D12
#define PIN_MOSI        D11
#define PIN_CS_TFT      D10  // chip select pin
#define PIN_DC_TFT      D9   // data/command select pin.
#define PIN_RESET_TFT   D8
//#define PIN_BL_TFT      D7
#define PIN_CS_SD       D4

#define PORTRAIT        0
#define LANDSCAPE       1

#define PIN_SCL_FT6206  A5
#define PIN_SDA_FT6206  A4
#define PIN_INT_FT6206  D7

#define ILI9341_TFTWIDTH  320
#define ILI9341_TFTHEIGHT 240

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
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
FT6206 FT6206(PIN_SDA_FT6206, PIN_SCL_FT6206, PIN_INT_FT6206); // sda, scl, int
MMA8451Q acc(SDA, SCL, MMA8451_I2C_ADDRESS);

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(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(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");

    //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;
        }
    }



    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   
            }
            
            
            
        }
        }
    }
}