// Button widget demo, requires 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 // Hardware-specific library #include // Widget library TFT_eSPI tft = TFT_eSPI(); // Invoke custom library #define CALIBRATION_FILE "/TouchCalData1" #define REPEAT_CAL false TFT_eWidget btnL = TFT_eWidget(&tft); TFT_eWidget btnR = TFT_eWidget(&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 TFT_eWidget* 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(); } } }