Migrating adafruit 320x480 TFT from Teensy 3.2 to Teensy 4.0

jkgv

New member
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!

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);

}
 
You might try starting off, running one of the SDFat test sketches from the Adafruit branch, to see if they work at all on the T4.
I have not used this fork of the SDFat library on Teensy boards, I have used it on a few of the Arduino boards.

I would also verify that during the build, that it actually used this version and not the SDFat library that is included with the Teensyduino
install.

I have played with the Adafruit_HX8357 library on these displays. @mjs513 and I also created our own library for these displays that is similar to our ILI9341_t3n and other libraries: https://github.com/mjs513/HX8357_t3n
It has been a while (maybe 4 years) since we last did anything with it.

Good luck
 
You might try starting off, running one of the SDFat test sketches from the Adafruit branch, to see if they work at all on the T4.
I have not used this fork of the SDFat library on Teensy boards, I have used it on a few of the Arduino boards.

I would also verify that during the build, that it actually used this version and not the SDFat library that is included with the Teensyduino
install.

I have played with the Adafruit_HX8357 library on these displays. @mjs513 and I also created our own library for these displays that is similar to our ILI9341_t3n and other libraries: https://github.com/mjs513/HX8357_t3n
It has been a while (maybe 4 years) since we last did anything with it.

Good luck
Thanks for the reply!

I’ve already forced use of the adafruit sdfat fork, that fixed the compile issues with the 3.2.

I guess you’re right, I’ll have to play around with just seeing if I can get the display to work with the 4.0 before going any further. For now I’m just back on the 3.2 and dealing with the adequate but clunky speed. Kind of a bummer, the 4.0 is so good.

I’ll take a look at your libraries and see if it’s something I can use, thanks.
 
Back
Top