Using V1 of this screen (STMPE610 touch controller) https://www.adafruit.com/product/3651
using Arduino IDE 2.3.4 with the adafruit sdfat library instead of the teensy sdfat library.
The following code works with the TFT using a Teensy 3.2 but is a bit slow, thus the change to 4.0. Code compiles fine (ignore the unused variable warning, it's a work in progress) but fails to initialize the SD Card. Looking at the pinout, pins 3, 4, and 8 (3.2 pins for STMPE_CS, TFT_CS, and SD_CS respectively) do not have the same functions on the 4.0. This seems to be supported by the fact that the example code for the TFT that works on the 3.2, also doesn't work on the 4.0.
Any ideas on how to port this code over? I'm using this adapter board that "should" work, but maybe this is the edge case where it doesn't. https://www.adafruit.com/product/3200
Any help would be appreciated, and any feedback as well - keeping in mind this is definitely a work in progress - but I have thick skin. Thanks!
using Arduino IDE 2.3.4 with the adafruit sdfat library instead of the teensy sdfat library.
The following code works with the TFT using a Teensy 3.2 but is a bit slow, thus the change to 4.0. Code compiles fine (ignore the unused variable warning, it's a work in progress) but fails to initialize the SD Card. Looking at the pinout, pins 3, 4, and 8 (3.2 pins for STMPE_CS, TFT_CS, and SD_CS respectively) do not have the same functions on the 4.0. This seems to be supported by the fact that the example code for the TFT that works on the 3.2, also doesn't work on the 4.0.
Any ideas on how to port this code over? I'm using this adapter board that "should" work, but maybe this is the edge case where it doesn't. https://www.adafruit.com/product/3200
Any help would be appreciated, and any feedback as well - keeping in mind this is definitely a work in progress - but I have thick skin. Thanks!
Code:
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_HX8357.h> // Hardware-specific library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
#include <Adafruit_STMPE610.h> // Rev 1 3.5" 320x480 with STMPE resistive touch screen controller uncomment this line:
// Comment out the next line to load from SPI/QSPI flash instead of SD card:
#define USE_SD_CARD
// Variable definitions for test rig
#define TFT_DC 10
#define TFT_CS 4
#define STMPE_CS 3
#define SD_CS 8
#define TFT_RST -1
// STMPE610 block
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);
// This is calibration data for the raw touch data to the screen coordinates
// For STMPE811/STMPE610
#define STMPE_TS_MINX 300
#define STMPE_TS_MAXX 3700
#define STMPE_TS_MINY 300
#define STMPE_TS_MAXY 3750
#define TOUCH_THRESHOLD 20
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 480
// we will assign the calibration values on init
int16_t min_x, max_x, min_y, max_y;
// Redefine original colors, add additional colors to match those available with the ILI9341 library
#define HX8357_BLACK 0x0000 ///< 0, 0, 0
#define HX8357_NAVY 0x000F ///< 0, 0, 123
#define HX8357_DARKGREEN 0x03E0 ///< 0, 125, 0
#define HX8357_DARKCYAN 0x03EF ///< 0, 125, 123
#define HX8357_MAROON 0x7800 ///< 123, 0, 0
#define HX8357_PURPLE 0x780F ///< 123, 0, 123
#define HX8357_OLIVE 0x7BE0 ///< 123, 125, 0
#define HX8357_LIGHTGREY 0xC618 ///< 198, 195, 198
#define HX8357_DARKGREY 0x7BEF ///< 123, 125, 123
#define HX8357_BLUE 0x001F ///< 0, 0, 255
#define HX8357_GREEN 0x07E0 ///< 0, 255, 0
#define HX8357_CYAN 0x07FF ///< 0, 255, 255
#define HX8357_RED 0xF800 ///< 255, 0, 0
#define HX8357_MAGENTA 0xF81F ///< 255, 0, 255
#define HX8357_WHITE 0xFFFF ///< 255, 255, 255
#define HX8357_ORANGE 0xFD20 ///< 255, 165, 0
#define HX8357_GREENYELLOW 0xAFE5 ///< 173, 255, 41
#define HX8357_PINK 0xFC18 ///< 255, 130, 198
// Cycle Number and Delay Variables
int cycleTarget = 0000;
int delayMS = 0000;
int cycleComplete = 0000;
int cycleToGo = 0000;
int cycleDisplayCounter = 0;
int returnDelay = 250;
// String Variables
String profileName = "default";
String filename = "";
String fileName = "";
String firstLine = "";
// Other variables
int screen = 0;
int isPaused = 0;
bool firstBoot = true;
bool cycleView = true;
int prevScreen = 0;
// Target Cycle Digits locations
const int digitPositions[4] = {4, 57, 110, 163}; // Fixed positions for digits
const int cycleDigitY = 263; // Fixed Y position for home screen digits
//complete cycles digit locations
const int digitCompletePositions[4] = {30, 99, 166, 233}; // Fixed positions for digits
const int completeCycleY = 320; // Fixed Y position for run cycles digits
// Delay Digits locations
const int delayPositions[4] = {20, 67, 113, 160}; // Positions for delay digits
const int delayDigitY = 191;
//Cycle Display Buttons Bounds
const int upCycleButtonBounds[4][4] = {
{5, 217, 55, 254}, // 1kUp
{59, 217, 109, 254}, // 1hUp
{110, 217, 160, 254}, // 10Up
{164, 217, 214, 254} // 01Up
};
const int downCycleButtonBounds[4][4] = {
{5, 325, 55, 361}, // 1kDn
{59, 325, 109, 361}, // 1hDn
{110, 325, 160, 361},// 10Dn
{164, 325, 214, 361} // 01Dn
};
//Delay Display Buttons Bounds
const int delayUpButtonBounds[4][4] = {
{20, 151, 58, 182}, // 1kUp
{66, 151, 105, 182}, // 1hUp
{112, 151, 151, 182}, // 10Up
{159, 151, 196, 182} // 01Up
};
const int delayDownButtonBounds[4][4] = {
{20, 245, 58, 277}, // 1kDn
{66, 245, 105, 277}, // 1hDn
{112, 245, 151, 277},// 10Dn
{159, 245, 196, 277} // 01Dn
};
// Other touch zones
const int additionalTouchZones[4][4] = {
{0, 0, 50, 50}, // spike
{87, 130, 233, 174}, // loadProfile
{234, 262, 308, 319}, // reset
{32, 405, 291, 470} // start
};
const int runTouchZones[4][4] = {
{238, 190, 296, 240}, //save
{22, 404, 144, 469}, //resume
{183, 404, 290, 469}, //stop
{17, 187, 201, 241} //complete cycle toggle
};
const int loadTouchZones[2][4] = {
{87, 130, 233, 174}, //new profile
{30, 403, 289, 471} //load profile
};
#if defined(USE_SD_CARD)
SdFat SD; // SD card filesystem
Adafruit_ImageReader reader(SD); // Image-reader object, pass in SD filesys
#else
// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
#if defined(__SAMD51__) || defined(NRF52840_XXAA)
Adafruit_FlashTransport_QSPI flashTransport(PIN_QSPI_SCK, PIN_QSPI_CS,
PIN_QSPI_IO0, PIN_QSPI_IO1, PIN_QSPI_IO2, PIN_QSPI_IO3);
#else
#if (SPI_INTERFACES_COUNT == 1)
Adafruit_FlashTransport_SPI flashTransport(SS, &SPI);
#else
Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, TFT_RST);
Adafruit_Image img; // An image loaded into RAM
int32_t width = 0, // BMP image dimensions
height = 0;
void setup() {
// pin inits
pinMode(2, OUTPUT); digitalWrite(2, HIGH);
pinMode(5, OUTPUT); digitalWrite(5, HIGH);
pinMode(14, INPUT);
Serial.begin(115200);
//#if !defined(ESP32)
// while(!Serial); // Wait for Serial Monitor before continuing
//#endif
delay(1000); // pause before screen init
tft.begin(40000000); // Initialize screen
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)
// SD card is pretty straightforward, a single call...
if(!SD.begin(SD_CS, SPI_FULL_SPEED)) { // ESP32 requires 25 MHz limit
Serial.println(F("SD begin() failed"));
for(;;); // Fatal error, do not continue
}
#else
// SPI or QSPI flash requires two steps, one to access the bare flash
// memory itself, then the second to access the filesystem within...
if(!flash.begin()) {
Serial.println(F("flash begin() failed"));
for(;;);
}
if(!filesys.begin(&flash)) {
Serial.println(F("filesys begin() failed"));
for(;;);
}
#endif
Serial.println(F("OK!"));
// Fill screen blue. Not a required step, this just shows that we're
// successfully communicating with the screen.
tft.fillScreen(HX8357_BLUE);
// background home image
//reader.drawBMP("/home.bmp", tft, 0, 0);
// delay digit init
// displayDelayMS(-1);
// displayDelayMS(delayMS);
//STMPE610 init
if (!ts.begin()) {
Serial.println("STMPE610 not detected!");
while (1); // Stop execution
} else {
Serial.println("STMPE610 initialized successfully.");
}
if(firstBoot == true) {
// cycle target digit init
reader.drawBMP("home.bmp", tft, 0, 0);
displayCycleTarget(-1);
displayCycleTarget(cycleTarget);
}
}
// Function for cycle target digit display on home screen
bool displayCycleTarget(int cycleTarget) {
static char prevNumberStr[11] = "----";
if (cycleTarget < 0) cycleTarget = 0; // Ensure cycleTarget is non-negative
char numberStr[11];
sprintf(numberStr, "%04d", cycleTarget);
if (strcmp(numberStr, prevNumberStr) == 0) return true; // Skip update if unchanged
strcpy(prevNumberStr, numberStr);
for (size_t i = 0; i < strlen(numberStr); i++) {
int digit = numberStr[i] - '0';
if (digit < 0 || digit > 9) return false; // Invalid character
filename = "/" + String(digit) + ".bmp";
reader.drawBMP(filename.c_str(), tft, digitPositions[i], cycleDigitY);
}
if (cycleTarget < 0 || cycleTarget > 9999) cycleTarget = 0;
return true; // Success
}
// Function for completed cycles digit display on run screen
bool displayCompleteCycles(int cycleComplete) {
static char prevNumberStr[11] = "----";
if (cycleComplete < 0) cycleComplete = 0; // Ensure cycleTarget is non-negative
char numberStr[11];
sprintf(numberStr, "%04d", cycleComplete);
if (strcmp(numberStr, prevNumberStr) == 0) return true; // Skip update if unchanged
strcpy(prevNumberStr, numberStr);
for (size_t i = 0; i < strlen(numberStr); i++) {
int digit = numberStr[i] - '0';
if (digit < 0 || digit > 9) return false; // Invalid character
filename = "/" + String(digit) + "lg.bmp";
reader.drawBMP(filename.c_str(), tft, digitCompletePositions[i], completeCycleY);
}
return true; // Success
}
// Function for cycles to go digit display on run screen
bool displayCyclesToGo(int cycleTarget, int cycleComplete) {
cycleToGo = cycleTarget - cycleComplete;
static char prevNumberStr[6] = "----";
if (cycleToGo < 0) cycleToGo = 0; // Ensure cycleTarget is non-negative
char numberStr[6];
sprintf(numberStr, "%04d", cycleToGo);
if (strcmp(numberStr, prevNumberStr) == 0) return true; // Skip update if unchanged
strcpy(prevNumberStr, numberStr);
for (size_t i = 0; i < strlen(numberStr); i++) {
int digit = numberStr[i] - '0';
if (digit < 0 || digit > 9) return false; // Invalid character
filename = "/" + String(digit) + "lg.bmp";
reader.drawBMP(filename.c_str(), tft, digitCompletePositions[i], completeCycleY);
}
return true; // Success
}
//Function for delay display
bool displayDelayMS(int delayMS) {
static char prevDelayStr[11] = "----";
if (delayMS < 0) delayMS = 0; // Ensure delayMS is non-negative
char delayStr[11]; // Increased buffer size to prevent overflow
sprintf(delayStr, "%04d", delayMS);
if (strcmp(delayStr, prevDelayStr) == 0) return true; // Skip update if unchanged
strcpy(prevDelayStr, delayStr);
for (size_t i = 0; i < strlen(delayStr); i++) {
int digit = delayStr[i] - '0';
if (digit < 0 || digit > 9) return false; // Invalid character
filename = "/" + String(digit) + "sm.bmp";
reader.drawBMP(filename.c_str(), tft, delayPositions[i], delayDigitY);
}
if (delayMS < 0 || delayMS > 99) delayMS = 0;
return true; // Success
}
// Display Profile Function
void displayProfile(String profileName) {
fileName = profileName + ".txt"; // Construct filename with extension
File32 profileFile = SD.open(fileName, FILE_READ);
if (!profileFile) {
Serial.println("Failed to open file: " + fileName);
tft.setTextSize(3); // Adjust text size (size 3 ~ 35px height)
tft.setTextColor(HX8357_WHITE, HX8357_BLACK); // White text on black background
tft.setCursor(11, 88);
tft.print("error opening" + profileName);
return;
}
firstLine = profileFile.readStringUntil('\n'); // Read first line
delayMS = firstLine.toInt(); // Convert to integer
Serial.print("Read value: ");
Serial.println(delayMS);
Serial.println(delayMS);
// Extract filename without extension
//String displayName = profileName;
// Set text properties
tft.setTextSize(3); // Adjust text size (size 3 ~ 35px height)
tft.setTextColor(HX8357_WHITE, HX8357_BLACK); // White text on black background
tft.setCursor(11, 88);
tft.print(profileName);
profileFile.close();
}
void homeScreen() {
screen = 0;
//draw home background
if(firstBoot == true) {
firstBoot = false;
displayProfile(); //display profile name
}
else {
reader.drawBMP("home.bmp", tft, 0, 0);
displayCycleTarget(-1);
if (prevScreen != screen) {
displayProfile(); //display profile name
}
displayCycleTarget(cycleTarget); //display target cycles
}
prevScreen = 0;
handleTouchInput(screen);
}
void cycleRun(int cycleTarget, String profileName) {
if (isPaused == 1) {
screen = 2;
reader.drawBMP("runbut.bmp", tft, 0, 400); // draw button
prevScreen = 1;
handleTouchInput(screen);
}
if (isPaused == 0) {
screen = 1; //set screen number
handleTouchInput(screen);
reader.drawBMP("run.bmp", tft, 0, 0); // draw background
displayDelayMS(-1);
displayProfile(profileName); //display profile name
displayDelayMS(delayMS); // draw delay digits init
if (cycleView == true) {
displayCompleteCycles(cycleComplete); // draw complete digits init
}
if (cycleView == false) {
displayCyclesToGo(cycleTarget, cycleComplete);
}
for (int i = cycleComplete; i <= cycleTarget; i++) {
handleTouchInput(screen);
if ( cycleView == true) {
displayCompleteCycles(cycleComplete);
}
if ( cycleView == false) {
displayCyclesToGo(cycleTarget, cycleComplete);
}
tft.fillRect(270, 0, 50, 50, HX8357_CYAN); // Flash cyan rectangle
digitalWrite(2, LOW); //Slide Pusher Solenoid
unsigned long startTime = millis();
// while (digitalRead(14) != HIGH) {
// if (millis() - startTime > 5000) {
// tft.fillRect(270, 0, 50, 50, HX8357_RED); // Flash red rectangle
// while (!ts.touched()) { delay(20); } // Wait for "start" touch to pause
// homeScreen(); //goto home screen
// return;
// }
// }
handleTouchInput(screen);
delay(delayMS); //Delay
digitalWrite(2, HIGH);//Retract
handleTouchInput(screen);
digitalWrite(5, LOW);//slide release solenoid activate
startTime = millis();
// while (digitalRead(14) != LOW) {
// if (millis() - startTime > 5000) {
// tft.fillRect(270, 0, 50, 50, HX8357_RED); // Flash red rectangle
// while (!ts.touched()) { delay(20); } // Wait for "start" touch
// homeScreen();
// return;
// }
// }
handleTouchInput(screen);
digitalWrite(5, HIGH);//slide release solenoid deactivate
tft.fillRect(270, 0, 50, 50, HX8357_MAGENTA); // Flash magenta rectangle
delay(returnDelay);
cycleComplete++;
handleTouchInput(screen);
}
// Write cycles to profile log
fileName = profileName + "log.txt"; // Construct filename with log plus extension
File32 profileFile = SD.open(fileName, O_APPEND | O_WRITE);
if (!profileFile) {
Serial.println("Failed to open file: " + fileName);
// return;
}
profileFile.print(cycleComplete - 1); profileFile.println(" Cycles Completed"); //write log to file
delay(30);
profileFile.close();
Serial.print(cycleComplete-1); Serial.println(" Cycles Completed"); //serial output confirming
tft.fillRect(233, 125, 50, 50, HX8357_GREEN);
while (!ts.touched()) { delay(10); } // Wait for "start" touch
cycleComplete = 0; //zero out cycle counter value
homeScreen();
}
prevScreen = 1;
}
void pauseCycle() {
screen = 2; //set screen number
isPaused = 1; //set paused
reader.drawBMP("pause.bmp", tft, 0, 400);
while (isPaused == 1) {
handleTouchInput(screen);
}
}
// Load Profile Function
void loadProfileScreen() {
screen = 3; // set screen to profile screen
reader.drawBMP("load.bmp", tft, 0, 0);
fileName = profileName + ".txt"; // Construct filename with extension
File32 profileFile = SD.open(fileName, FILE_READ);
if (!profileFile) {
Serial.println("Failed to open file: " + fileName);
return;
}
// Extract filename without extension
//String displayName = profileName;
// Set text properties
tft.setTextSize(3); // Adjust text size (size 3 ~ 35px height)
tft.setTextColor(HX8357_WHITE, HX8357_BLACK); // White text on black background
tft.setCursor(11, 88);
tft.print(profileName);
// List available files from SD card and display them at 10,183
tft.setCursor(10, 183);
tft.setTextSize(3);
tft.setTextColor(HX8357_WHITE);
profileFile.close();
File32 root = SD.open("/");
while (true) {
File32 entry = root.openNextFile();
if (!entry) {
break; // No more files
}
fileName = entry.name();
if (fileName.endsWith(".txt") && !fileName.endsWith("log.txt")) {
int dotIndex = fileName.lastIndexOf('.');
if (dotIndex != -1) {
fileName = fileName.substring(0, dotIndex); // Remove extension
}
Serial.println(fileName); //serial output
tft.println(fileName);
}
entry.close();
}
root.close();
handleTouchInput(screen);
prevScreen = 3;
}
void loadProfile() {
fileName = profileName + ".txt"; // Construct filename with extension
File32 profileFile = SD.open(fileName, FILE_READ);
if (!profileFile) {
Serial.println("Failed to open file: " + fileName);
screen = 3;
return;
}
firstLine = profileFile.readStringUntil('\n'); // Read first line
delayMS = firstLine.toInt(); // Convert to integer
Serial.print("Read value: ");
Serial.println(delayMS);
Serial.println(delayMS);
profileFile.close();
screen = 0; //set to home screen
handleTouchInput(screen);
}
void loadSelectedProfile() {} // needs to be finished
void saveProfile(String profileName) {
fileName = profileName + ".txt"; // Construct filename with extension
File32 profileFile = SD.open(fileName, O_RDWR | O_WRITE);
if (!profileFile) {
Serial.println("Failed to open file: " + fileName);
// return;
}
profileFile.print(delayMS);
// Set text properties
tft.setTextSize(3); // Adjust text size (size 3 ~ 35px height)
tft.setTextColor(HX8357_WHITE, HX8357_BLACK); // White text on black background
tft.setCursor(11, 88);
tft.print(profileName);
// List available files from SD card and display them at 10,183
tft.setCursor(10, 183);
tft.setTextSize(3);
tft.setTextColor(HX8357_WHITE);
profileFile.close();
handleTouchInput(screen);
}
void displayProfile() {
fileName = profileName + ".txt"; // Construct filename with extension
File32 profileFile = SD.open(fileName, FILE_READ);
if (!profileFile) {
Serial.println("Failed to open file: " + fileName);
return;
}
// Extract filename without extension
//String displayName = profileName;
// Set text properties
tft.setTextSize(3); // Adjust text size (size 3 ~ 35px height)
tft.setTextColor(HX8357_WHITE, HX8357_BLACK); // White text on black background
tft.setCursor(11, 88);
tft.print(profileName);
profileFile.close();
}
void newProfile() {} // needs to be finished
void debugScreen() {
screen = 4; //set to debug screen
prevScreen = 4;
} // needs to be finished
// touch input handling
void handleTouchInput(int screen) {
TS_Point p, pt;
if (!ts.touched()) {
return;
}
while (ts.touched()) {
pt = ts.getPoint();
if(pt.x != 0){
p = pt;
}
}
if (p.z < TOUCH_THRESHOLD) return; // Reject weak presses
int px = map(p.x, STMPE_TS_MINX, STMPE_TS_MAXX, 0, SCREEN_WIDTH);
int py = map(p.y, STMPE_TS_MINY, STMPE_TS_MAXY, 0, SCREEN_HEIGHT);
p.x = px;
p.y = py;
uint16_t x = p.x, y = p.y;
ts.writeRegister8(STMPE_INT_STA, 0xFF); // Clear interrupt
// Home screen touch handling
if (screen == 0) {
// Cycle Buttons
for (int i = 0; i < 4; i++) {
if (x >= upCycleButtonBounds[i][0] && x <= upCycleButtonBounds[i][2] &&
y >= upCycleButtonBounds[i][1] && y <= upCycleButtonBounds[i][3]) {
cycleTarget += (i == 0 ? 1000 : i == 1 ? 100 : i == 2 ? 10 : 1);
break;
}
else if (x >= downCycleButtonBounds[i][0] && x <= downCycleButtonBounds[i][2] &&
y >= downCycleButtonBounds[i][1] && y <= downCycleButtonBounds[i][3]) {
cycleTarget -= (i == 0 ? 1000 : i == 1 ? 100 : i == 2 ? 10 : 1);
break;
}
}
// Load Profile Button
if (x >= additionalTouchZones[1][0] && x <= additionalTouchZones[1][2] &&
y >= additionalTouchZones[1][1] && y <= additionalTouchZones[1][3]) {
loadProfileScreen();
}
// Reset Cycles Button
if (x >= additionalTouchZones[2][0] && x <= additionalTouchZones[2][2] &&
y >= additionalTouchZones[2][1] && y <= additionalTouchZones[2][3]) {
cycleTarget = 0;
Serial.println("reset");
}
// Start button
if (x >= additionalTouchZones[3][0] && x <= additionalTouchZones[3][2] &&
y >= additionalTouchZones[3][1] && y <= additionalTouchZones[3][3]) {
cycleRun(cycleTarget, profileName);
}
// Spike button
if (x >= additionalTouchZones[0][0] && x <= additionalTouchZones[0][2] &&
y >= additionalTouchZones[0][1] && y <= additionalTouchZones[0][3]) {
debugScreen();
}
if (cycleTarget < 0 || cycleTarget > 9999) cycleTarget = 0;
displayCycleTarget(cycleTarget);
}
// Run screen touch handling
if (screen == 1) {
// Delay buttons
for (int i = 0; i < 4; i++) {
if (x >= delayUpButtonBounds[i][0] && x <= delayUpButtonBounds[i][2] &&
y >= delayUpButtonBounds[i][1] && y <= delayUpButtonBounds[i][3]) {
delayMS += (i == 0 ? 1000 : i == 1 ? 100 : i == 2 ? 10 : 1);
displayDelayMS(delayMS);
break;
}
else if (x >= delayDownButtonBounds[i][0] && x <= delayDownButtonBounds[i][2] &&
y >= delayDownButtonBounds[i][1] && y <= delayDownButtonBounds[i][3]) {
delayMS -= (i == 0 ? 1000 : i == 1 ? 100 : i == 2 ? 10 : 1);
displayDelayMS(delayMS);
break;
}
}
// Save Profile button
if (x >= runTouchZones[0][0] && x <= runTouchZones[0][2] &&
y >= runTouchZones[0][1] && y <= runTouchZones[0][3]) {
saveProfile(profileName); //update profile file data
}
// Pause button
if (x >= additionalTouchZones[3][0] && x <= additionalTouchZones[3][2] &&
y >= additionalTouchZones[3][1] && y <= additionalTouchZones[3][3]) {
pauseCycle(); // pause screen
}
// cycle display toggle button
if (x >= runTouchZones[3][0] && x <= runTouchZones[3][2] &&
y >= runTouchZones[3][1] && y <= runTouchZones[3][3]) {
pauseCycle(); // pause screen
}
}
// Pause screen
if (screen == 2) {
// Delay buttons
for (int i = 0; i < 4; i++) {
if (x >= delayUpButtonBounds[i][0] && x <= delayUpButtonBounds[i][2] &&
y >= delayUpButtonBounds[i][1] && y <= delayUpButtonBounds[i][3]) {
delayMS += (i == 0 ? 1000 : i == 1 ? 100 : i == 2 ? 10 : 1);
displayDelayMS(delayMS);
break;
}
else if (x >= delayDownButtonBounds[i][0] && x <= delayDownButtonBounds[i][2] &&
y >= delayDownButtonBounds[i][1] && y <= delayDownButtonBounds[i][3]) {
delayMS -= (i == 0 ? 1000 : i == 1 ? 100 : i == 2 ? 10 : 1);
displayDelayMS(delayMS);
break;
}
}
// Save Profile button
if (x >= runTouchZones[0][0] && x <= runTouchZones[0][2] &&
y >= runTouchZones[0][1] && y <= runTouchZones[0][3]) {
saveProfile(profileName); //update profile file data
}
// Resume button
if (x >= runTouchZones[1][0] && x <= runTouchZones[1][2] &&
y >= runTouchZones[1][1] && y <= runTouchZones[1][3]) {
prevScreen = 2;
isPaused = 0;
// cycleRun(cycleToGo, profileName); // goto run screen
}
// Stop button
if (x >= runTouchZones[2][0] && x <= runTouchZones[2][2] &&
y >= runTouchZones[2][1] && y <= runTouchZones[2][3]) {
prevScreen = 2;
isPaused = 0;
homeScreen(); // go to home screen
}
if (delayMS < 0 || delayMS > 9999) delayMS = 0;
}
// Profile screen
if (screen == 3) {
// new profile button
if (x >= loadTouchZones[0][0] && x <= loadTouchZones[0][2] &&
y >= loadTouchZones[0][1] && y <= loadTouchZones[0][3]) {
newProfile();
}
// load profile button
if (x >= loadTouchZones[1][0] && x <= loadTouchZones[1][2] &&
y >= loadTouchZones[1][1] && y <= loadTouchZones[1][3]) {
loadSelectedProfile();
}
}
// Debug screen
if (screen == 4) {
// Cycle Buttons
for (int i = 0; i < 4; i++) {
if (x >= upCycleButtonBounds[i][0] && x <= upCycleButtonBounds[i][2] &&
y >= upCycleButtonBounds[i][1] && y <= upCycleButtonBounds[i][3]) {
cycleTarget += (i == 0 ? 1000 : i == 1 ? 100 : i == 2 ? 10 : 1);
break;
}
else if (x >= downCycleButtonBounds[i][0] && x <= downCycleButtonBounds[i][2] &&
y >= downCycleButtonBounds[i][1] && y <= downCycleButtonBounds[i][3]) {
cycleTarget -= (i == 0 ? 1000 : i == 1 ? 100 : i == 2 ? 10 : 1);
break;
}
}
// Start button
if (x >= additionalTouchZones[3][0] && x <= additionalTouchZones[3][2] &&
y >= additionalTouchZones[3][1] && y <= additionalTouchZones[3][3]) {
homeScreen();
}
}
}
void loop() {
if(firstBoot == true) {
homeScreen();
}
handleTouchInput(screen);
}