acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.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