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