acidportal

- 😈 Worlds smallest Evil Portal on a LilyGo T-QT
git clone git://git.acid.vegas/acidportal.git
Log | Files | Refs | Archive | README | LICENSE

Keypad_240x320.ino (8427B)

      1 /*
      2   The TFT_eSPI library incorporates an Adafruit_GFX compatible
      3   button handling class, this sketch is based on the Arduin-o-phone
      4   example.
      5 
      6   This example diplays a keypad where numbers can be entered and
      7   send to the Serial Monitor window.
      8 
      9   The sketch has been tested on the ESP8266 (which supports SPIFFS)
     10 
     11   The minimum screen size is 320 x 240 as that is the keypad size.
     12 */
     13 
     14 // The SPIFFS (FLASH filing system) is used to hold touch screen
     15 // calibration data
     16 
     17 #include "FS.h"
     18 
     19 #include <SPI.h>
     20 #include <TFT_eSPI.h>      // Hardware-specific library
     21 
     22 TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
     23 
     24 // This is the file name used to store the calibration data
     25 // You can change this to create new calibration files.
     26 // The SPIFFS file name must start with "/".
     27 #define CALIBRATION_FILE "/TouchCalData1"
     28 
     29 // Set REPEAT_CAL to true instead of false to run calibration
     30 // again, otherwise it will only be done once.
     31 // Repeat calibration if you change the screen rotation.
     32 #define REPEAT_CAL false
     33 
     34 // Keypad start position, key sizes and spacing
     35 #define KEY_X 40 // Centre of key
     36 #define KEY_Y 96
     37 #define KEY_W 62 // Width and height
     38 #define KEY_H 30
     39 #define KEY_SPACING_X 18 // X and Y gap
     40 #define KEY_SPACING_Y 20
     41 #define KEY_TEXTSIZE 1   // Font size multiplier
     42 
     43 // Using two fonts since numbers are nice when bold
     44 #define LABEL1_FONT &FreeSansOblique12pt7b // Key label font 1
     45 #define LABEL2_FONT &FreeSansBold12pt7b    // Key label font 2
     46 
     47 // Numeric display box size and location
     48 #define DISP_X 1
     49 #define DISP_Y 10
     50 #define DISP_W 238
     51 #define DISP_H 50
     52 #define DISP_TSIZE 3
     53 #define DISP_TCOLOR TFT_CYAN
     54 
     55 // Number length, buffer for storing it and character index
     56 #define NUM_LEN 12
     57 char numberBuffer[NUM_LEN + 1] = "";
     58 uint8_t numberIndex = 0;
     59 
     60 // We have a status line for messages
     61 #define STATUS_X 120 // Centred on this
     62 #define STATUS_Y 65
     63 
     64 // Create 15 keys for the keypad
     65 char keyLabel[15][5] = {"New", "Del", "Send", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", "0", "#" };
     66 uint16_t keyColor[15] = {TFT_RED, TFT_DARKGREY, TFT_DARKGREEN,
     67                          TFT_BLUE, TFT_BLUE, TFT_BLUE,
     68                          TFT_BLUE, TFT_BLUE, TFT_BLUE,
     69                          TFT_BLUE, TFT_BLUE, TFT_BLUE,
     70                          TFT_BLUE, TFT_BLUE, TFT_BLUE
     71                         };
     72 
     73 // Invoke the TFT_eSPI button class and create all the button objects
     74 TFT_eSPI_Button key[15];
     75 
     76 //------------------------------------------------------------------------------------------
     77 
     78 void setup() {
     79   // Use serial port
     80   Serial.begin(9600);
     81 
     82   // Initialise the TFT screen
     83   tft.init();
     84 
     85   // Set the rotation before we calibrate
     86   tft.setRotation(0);
     87 
     88   // Calibrate the touch screen and retrieve the scaling factors
     89   touch_calibrate();
     90 
     91   // Clear the screen
     92   tft.fillScreen(TFT_BLACK);
     93 
     94   // Draw keypad background
     95   tft.fillRect(0, 0, 240, 320, TFT_DARKGREY);
     96 
     97   // Draw number display area and frame
     98   tft.fillRect(DISP_X, DISP_Y, DISP_W, DISP_H, TFT_BLACK);
     99   tft.drawRect(DISP_X, DISP_Y, DISP_W, DISP_H, TFT_WHITE);
    100 
    101   // Draw keypad
    102   drawKeypad();
    103 }
    104 
    105 //------------------------------------------------------------------------------------------
    106 
    107 void loop(void) {
    108   uint16_t t_x = 0, t_y = 0; // To store the touch coordinates
    109 
    110   // Pressed will be set true is there is a valid touch on the screen
    111   bool pressed = tft.getTouch(&t_x, &t_y);
    112 
    113   // / Check if any key coordinate boxes contain the touch coordinates
    114   for (uint8_t b = 0; b < 15; b++) {
    115     if (pressed && key[b].contains(t_x, t_y)) {
    116       key[b].press(true);  // tell the button it is pressed
    117     } else {
    118       key[b].press(false);  // tell the button it is NOT pressed
    119     }
    120   }
    121 
    122   // Check if any key has changed state
    123   for (uint8_t b = 0; b < 15; b++) {
    124 
    125     if (b < 3) tft.setFreeFont(LABEL1_FONT);
    126     else tft.setFreeFont(LABEL2_FONT);
    127 
    128     if (key[b].justReleased()) key[b].drawButton();     // draw normal
    129 
    130     if (key[b].justPressed()) {
    131       key[b].drawButton(true);  // draw invert
    132 
    133       // if a numberpad button, append the relevant # to the numberBuffer
    134       if (b >= 3) {
    135         if (numberIndex < NUM_LEN) {
    136           numberBuffer[numberIndex] = keyLabel[b][0];
    137           numberIndex++;
    138           numberBuffer[numberIndex] = 0; // zero terminate
    139         }
    140         status(""); // Clear the old status
    141       }
    142 
    143       // Del button, so delete last char
    144       if (b == 1) {
    145         numberBuffer[numberIndex] = 0;
    146         if (numberIndex > 0) {
    147           numberIndex--;
    148           numberBuffer[numberIndex] = 0;//' ';
    149         }
    150         status(""); // Clear the old status
    151       }
    152 
    153       if (b == 2) {
    154         status("Sent value to serial port");
    155         Serial.println(numberBuffer);
    156       }
    157       // we dont really check that the text field makes sense
    158       // just try to call
    159       if (b == 0) {
    160         status("Value cleared");
    161         numberIndex = 0; // Reset index to 0
    162         numberBuffer[numberIndex] = 0; // Place null in buffer
    163       }
    164 
    165       // Update the number display field
    166       tft.setTextDatum(TL_DATUM);        // Use top left corner as text coord datum
    167       tft.setFreeFont(&FreeSans18pt7b);  // Choose a nicefont that fits box
    168       tft.setTextColor(DISP_TCOLOR);     // Set the font colour
    169 
    170       // Draw the string, the value returned is the width in pixels
    171       int xwidth = tft.drawString(numberBuffer, DISP_X + 4, DISP_Y + 12);
    172 
    173       // Now cover up the rest of the line up by drawing a black rectangle.  No flicker this way
    174       // but it will not work with italic or oblique fonts due to character overlap.
    175       tft.fillRect(DISP_X + 4 + xwidth, DISP_Y + 1, DISP_W - xwidth - 5, DISP_H - 2, TFT_BLACK);
    176 
    177       delay(10); // UI debouncing
    178     }
    179   }
    180 }
    181 
    182 //------------------------------------------------------------------------------------------
    183 
    184 void drawKeypad()
    185 {
    186   // Draw the keys
    187   for (uint8_t row = 0; row < 5; row++) {
    188     for (uint8_t col = 0; col < 3; col++) {
    189       uint8_t b = col + row * 3;
    190 
    191       if (b < 3) tft.setFreeFont(LABEL1_FONT);
    192       else tft.setFreeFont(LABEL2_FONT);
    193 
    194       key[b].initButton(&tft, KEY_X + col * (KEY_W + KEY_SPACING_X),
    195                         KEY_Y + row * (KEY_H + KEY_SPACING_Y), // x, y, w, h, outline, fill, text
    196                         KEY_W, KEY_H, TFT_WHITE, keyColor[b], TFT_WHITE,
    197                         keyLabel[b], KEY_TEXTSIZE);
    198       key[b].drawButton();
    199     }
    200   }
    201 }
    202 
    203 //------------------------------------------------------------------------------------------
    204 
    205 void touch_calibrate()
    206 {
    207   uint16_t calData[5];
    208   uint8_t calDataOK = 0;
    209 
    210   // check file system exists
    211   if (!SPIFFS.begin()) {
    212     Serial.println("Formating file system");
    213     SPIFFS.format();
    214     SPIFFS.begin();
    215   }
    216 
    217   // check if calibration file exists and size is correct
    218   if (SPIFFS.exists(CALIBRATION_FILE)) {
    219     if (REPEAT_CAL)
    220     {
    221       // Delete if we want to re-calibrate
    222       SPIFFS.remove(CALIBRATION_FILE);
    223     }
    224     else
    225     {
    226       File f = SPIFFS.open(CALIBRATION_FILE, "r");
    227       if (f) {
    228         if (f.readBytes((char *)calData, 14) == 14)
    229           calDataOK = 1;
    230         f.close();
    231       }
    232     }
    233   }
    234 
    235   if (calDataOK && !REPEAT_CAL) {
    236     // calibration data valid
    237     tft.setTouch(calData);
    238   } else {
    239     // data not valid so recalibrate
    240     tft.fillScreen(TFT_BLACK);
    241     tft.setCursor(20, 0);
    242     tft.setTextFont(2);
    243     tft.setTextSize(1);
    244     tft.setTextColor(TFT_WHITE, TFT_BLACK);
    245 
    246     tft.println("Touch corners as indicated");
    247 
    248     tft.setTextFont(1);
    249     tft.println();
    250 
    251     if (REPEAT_CAL) {
    252       tft.setTextColor(TFT_RED, TFT_BLACK);
    253       tft.println("Set REPEAT_CAL to false to stop this running again!");
    254     }
    255 
    256     tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);
    257 
    258     tft.setTextColor(TFT_GREEN, TFT_BLACK);
    259     tft.println("Calibration complete!");
    260 
    261     // store data
    262     File f = SPIFFS.open(CALIBRATION_FILE, "w");
    263     if (f) {
    264       f.write((const unsigned char *)calData, 14);
    265       f.close();
    266     }
    267   }
    268 }
    269 
    270 //------------------------------------------------------------------------------------------
    271 
    272 // Print something in the mini status bar
    273 void status(const char *msg) {
    274   tft.setTextPadding(240);
    275   //tft.setCursor(STATUS_X, STATUS_Y);
    276   tft.setTextColor(TFT_WHITE, TFT_DARKGREY);
    277   tft.setTextFont(0);
    278   tft.setTextDatum(TC_DATUM);
    279   tft.setTextSize(1);
    280   tft.drawString(msg, STATUS_X, STATUS_Y);
    281 }
    282 
    283 //------------------------------------------------------------------------------------------
    284