192 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			192 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| // Button widget demo, requires SPI display with touch screen
 | |
| 
 | |
| // Requires widget library here:
 | |
| // https://github.com/Bodmer/TFT_eWidget
 | |
| 
 | |
| #include <FS.h>
 | |
| #include "Free_Fonts.h" // Include the header file attached to this sketch
 | |
| 
 | |
| #include <TFT_eSPI.h>              // Hardware-specific library
 | |
| #include <TFT_eWidget.h>           // Widget library
 | |
| 
 | |
| TFT_eSPI tft = TFT_eSPI();         // Invoke custom library
 | |
| 
 | |
| #define CALIBRATION_FILE "/TouchCalData1"
 | |
| #define REPEAT_CAL false
 | |
| 
 | |
| ButtonWidget btnL = ButtonWidget(&tft);
 | |
| ButtonWidget btnR = ButtonWidget(&tft);
 | |
| 
 | |
| #define BUTTON_W 100
 | |
| #define BUTTON_H 50
 | |
| 
 | |
| // Create an array of button instances to use in for() loops
 | |
| // This is more useful where large numbers of buttons are employed
 | |
| ButtonWidget* btn[] = {&btnL , &btnR};;
 | |
| uint8_t buttonCount = sizeof(btn) / sizeof(btn[0]);
 | |
| 
 | |
| void btnL_pressAction(void)
 | |
| {
 | |
|   if (btnL.justPressed()) {
 | |
|     Serial.println("Left button just pressed");
 | |
|     btnL.drawSmoothButton(true);
 | |
|   }
 | |
| }
 | |
| 
 | |
| void btnL_releaseAction(void)
 | |
| {
 | |
|   static uint32_t waitTime = 1000;
 | |
|   if (btnL.justReleased()) {
 | |
|     Serial.println("Left button just released");
 | |
|     btnL.drawSmoothButton(false);
 | |
|     btnL.setReleaseTime(millis());
 | |
|     waitTime = 10000;
 | |
|   }
 | |
|   else {
 | |
|     if (millis() - btnL.getReleaseTime() >= waitTime) {
 | |
|       waitTime = 1000;
 | |
|       btnL.setReleaseTime(millis());
 | |
|       btnL.drawSmoothButton(!btnL.getState());
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| void btnR_pressAction(void)
 | |
| {
 | |
|   if (btnR.justPressed()) {
 | |
|     btnR.drawSmoothButton(!btnR.getState(), 3, TFT_BLACK, btnR.getState() ? "OFF" : "ON");
 | |
|     Serial.print("Button toggled: ");
 | |
|     if (btnR.getState()) Serial.println("ON");
 | |
|     else  Serial.println("OFF");
 | |
|     btnR.setPressTime(millis());
 | |
|   }
 | |
| 
 | |
|   // if button pressed for more than 1 sec...
 | |
|   if (millis() - btnR.getPressTime() >= 1000) {
 | |
|     Serial.println("Stop pressing my buttton.......");
 | |
|   }
 | |
|   else Serial.println("Right button is being pressed");
 | |
| }
 | |
| 
 | |
| void btnR_releaseAction(void)
 | |
| {
 | |
|   // Not action
 | |
| }
 | |
| 
 | |
| void initButtons() {
 | |
|   uint16_t x = (tft.width() - BUTTON_W) / 2;
 | |
|   uint16_t y = tft.height() / 2 - BUTTON_H - 10;
 | |
|   btnL.initButtonUL(x, y, BUTTON_W, BUTTON_H, TFT_WHITE, TFT_RED, TFT_BLACK, "Button", 1);
 | |
|   btnL.setPressAction(btnL_pressAction);
 | |
|   btnL.setReleaseAction(btnL_releaseAction);
 | |
|   btnL.drawSmoothButton(false, 3, TFT_BLACK); // 3 is outline width, TFT_BLACK is the surrounding background colour for anti-aliasing
 | |
| 
 | |
|   y = tft.height() / 2 + 10;
 | |
|   btnR.initButtonUL(x, y, BUTTON_W, BUTTON_H, TFT_WHITE, TFT_BLACK, TFT_GREEN, "OFF", 1);
 | |
|   btnR.setPressAction(btnR_pressAction);
 | |
|   //btnR.setReleaseAction(btnR_releaseAction);
 | |
|   btnR.drawSmoothButton(false, 3, TFT_BLACK); // 3 is outline width, TFT_BLACK is the surrounding background colour for anti-aliasing
 | |
| }
 | |
| 
 | |
| void setup() {
 | |
|   Serial.begin(115200);
 | |
|   tft.begin();
 | |
|   tft.setRotation(0);
 | |
|   tft.fillScreen(TFT_BLACK);
 | |
|   tft.setFreeFont(FF18);
 | |
| 
 | |
|   // Calibrate the touch screen and retrieve the scaling factors
 | |
|   touch_calibrate();
 | |
|   initButtons();
 | |
| }
 | |
| 
 | |
| void loop() {
 | |
|   static uint32_t scanTime = millis();
 | |
|   uint16_t t_x = 9999, t_y = 9999; // To store the touch coordinates
 | |
| 
 | |
|   // Scan keys every 50ms at most
 | |
|   if (millis() - scanTime >= 50) {
 | |
|     // Pressed will be set true if there is a valid touch on the screen
 | |
|     bool pressed = tft.getTouch(&t_x, &t_y);
 | |
|     scanTime = millis();
 | |
|     for (uint8_t b = 0; b < buttonCount; b++) {
 | |
|       if (pressed) {
 | |
|         if (btn[b]->contains(t_x, t_y)) {
 | |
|           btn[b]->press(true);
 | |
|           btn[b]->pressAction();
 | |
|         }
 | |
|       }
 | |
|       else {
 | |
|         btn[b]->press(false);
 | |
|         btn[b]->releaseAction();
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
| }
 | |
| 
 | |
| void touch_calibrate()
 | |
| {
 | |
|   uint16_t calData[5];
 | |
|   uint8_t calDataOK = 0;
 | |
| 
 | |
|   // check file system exists
 | |
|   if (!LittleFS.begin()) {
 | |
|     Serial.println("Formating file system");
 | |
|     LittleFS.format();
 | |
|     LittleFS.begin();
 | |
|   }
 | |
| 
 | |
|   // check if calibration file exists and size is correct
 | |
|   if (LittleFS.exists(CALIBRATION_FILE)) {
 | |
|     if (REPEAT_CAL)
 | |
|     {
 | |
|       // Delete if we want to re-calibrate
 | |
|       LittleFS.remove(CALIBRATION_FILE);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       File f = LittleFS.open(CALIBRATION_FILE, "r");
 | |
|       if (f) {
 | |
|         if (f.readBytes((char *)calData, 14) == 14)
 | |
|           calDataOK = 1;
 | |
|         f.close();
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (calDataOK && !REPEAT_CAL) {
 | |
|     // calibration data valid
 | |
|     tft.setTouch(calData);
 | |
|   } else {
 | |
|     // data not valid so recalibrate
 | |
|     tft.fillScreen(TFT_BLACK);
 | |
|     tft.setCursor(20, 0);
 | |
|     tft.setTextFont(2);
 | |
|     tft.setTextSize(1);
 | |
|     tft.setTextColor(TFT_WHITE, TFT_BLACK);
 | |
| 
 | |
|     tft.println("Touch corners as indicated");
 | |
| 
 | |
|     tft.setTextFont(1);
 | |
|     tft.println();
 | |
| 
 | |
|     if (REPEAT_CAL) {
 | |
|       tft.setTextColor(TFT_RED, TFT_BLACK);
 | |
|       tft.println("Set REPEAT_CAL to false to stop this running again!");
 | |
|     }
 | |
| 
 | |
|     tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);
 | |
| 
 | |
|     tft.setTextColor(TFT_GREEN, TFT_BLACK);
 | |
|     tft.println("Calibration complete!");
 | |
| 
 | |
|     // store data
 | |
|     File f = LittleFS.open(CALIBRATION_FILE, "w");
 | |
|     if (f) {
 | |
|       f.write((const unsigned char *)calData, 14);
 | |
|       f.close();
 | |
|     }
 | |
|   }
 | |
| }
 |