Teensy 4 with TFT 4.0 (480x320) - TOUCH and TFT_e_SPI , combination working !!

AntiLoop

Well-known member
Hello guys,
i've come at last to manage to make all of this working together and would like to share it with you,i think TFt 4.0 is a nice display
to show the audio stuffs of teeny,and of course with the touch possibilities.
First,i couldn't make my TFT 4.0 working with the ST7796 driver,but i remember it is similar with the ILI9488 driver,and BINGO,it worked! :cool:


---------------------The TFT_e_SPI setup:-----------------------------


#define ILI9488_DRIVER



#define TFT_MISO 12
#define TFT_MOSI 11
#define TFT_SCLK 13
#define TFT_CS 10 // Chip select control pin
#define TFT_DC 9 // Data Command control pin
#define TFT_RST 16 // Reset pin (could connect to RST pin)
//#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST

//#define TOUCH_CLK 18
#define TOUCH_CS 8 // Chip select pin (T_CS) of touch screen
//#define TOUCH_DIN 23
//#define TOUCH_DO 19






#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts


#define SMOOTH_FONT



#define SPI_FREQUENCY 20000000

#define SPI_READ_FREQUENCY 20000000


#define SPI_TOUCH_FREQUENCY 2500000




---------------------The keypad 320x240 sketch from the bodmer library:------------------------




//KEYPAD 320x240 FOR TEENSY


#include <LittleFS.h>
LittleFS_Program myfs;
#define PROG_FLASH_SIZE 1024 * 900 // Specify size to use of onboard Teensy Program Flash chip
// This creates a LittleFS drive in Teensy PCB FLash.

File dataFile; // Specifes that dataFile is of File type
//int record_count = 0;
//bool write_data = false;
uint32_t diskSize;


#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library

TFT_eSPI tft = TFT_eSPI(); // Invoke custom library

#define CALIBRATION_FILE "/TouchCalData2"
#define REPEAT_CAL false



// Keypad start position, key sizes and spacing
#define KEY_X 40 // Centre of key
#define KEY_Y 96
#define KEY_W 62 // Width and height
#define KEY_H 30
#define KEY_SPACING_X 18 // X and Y gap
#define KEY_SPACING_Y 20
#define KEY_TEXTSIZE 1 // Font size multiplier

// Using two fonts since numbers are nice when bold
#define LABEL1_FONT &FreeSansOblique12pt7b // Key label font 1
#define LABEL2_FONT &FreeSansBold12pt7b // Key label font 2

// Numeric display box size and location
#define DISP_X 1
#define DISP_Y 10
#define DISP_W 238
#define DISP_H 50
#define DISP_TSIZE 3
#define DISP_TCOLOR TFT_CYAN

// Number length, buffer for storing it and character index
#define NUM_LEN 12
char numberBuffer[NUM_LEN + 1] = "";
uint8_t numberIndex = 0;

// We have a status line for messages
#define STATUS_X 120 // Centred on this
#define STATUS_Y 65

// Create 15 keys for the keypad
char keyLabel[15][5] = {"New", "Del", "Send", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", "0", "#" };
uint16_t keyColor[15] = {TFT_RED, TFT_DARKGREY, TFT_DARKGREEN,
TFT_BLUE, TFT_BLUE, TFT_BLUE,
TFT_BLUE, TFT_BLUE, TFT_BLUE,
TFT_BLUE, TFT_BLUE, TFT_BLUE,
TFT_BLUE, TFT_BLUE, TFT_BLUE
};

// Invoke the TFT_eSPI button class and create all the button objects
TFT_eSPI_Button key[15];

//------------------------------------------------------------------------------------------

void setup() {
// Use serial port
Serial.begin(115200);

// Initialise the TFT screen
tft.init();

// Set the rotation before we calibrate
tft.setRotation(1);

// Calibrate the touch screen and retrieve the scaling factors
touch_calibrate();

// Clear the screen
tft.fillScreen(TFT_BLACK);

// Draw keypad background
tft.fillRect(0, 0, 240, 320, TFT_DARKGREY);

// Draw number display area and frame
tft.fillRect(DISP_X, DISP_Y, DISP_W, DISP_H, TFT_BLACK);
tft.drawRect(DISP_X, DISP_Y, DISP_W, DISP_H, TFT_WHITE);

// Draw keypad
drawKeypad();
}

//------------------------------------------------------------------------------------------


void loop(void) {
uint16_t t_x = 0, t_y = 0; // To store the touch coordinates

// Pressed will be set true is there is a valid touch on the screen
boolean pressed = tft.getTouch(&t_x, &t_y);

// / Check if any key coordinate boxes contain the touch coordinates
for (uint8_t b = 0; b < 15; b++) {
if (pressed && key.contains(t_x, t_y)) {
key.press(true); // tell the button it is pressed
} else {
key.press(false); // tell the button it is NOT pressed
}
}

// Check if any key has changed state
for (uint8_t b = 0; b < 15; b++) {

if (b < 3) tft.setFreeFont(LABEL1_FONT);
else tft.setFreeFont(LABEL2_FONT);

if (key.justReleased()) key.drawButton(); // draw normal

if (key.justPressed()) {
key.drawButton(true); // draw invert

// if a numberpad button, append the relevant # to the numberBuffer
if (b >= 3) {
if (numberIndex < NUM_LEN) {
numberBuffer[numberIndex] = keyLabel[0];
numberIndex++;
numberBuffer[numberIndex] = 0; // zero terminate
}
status(""); // Clear the old status
}

// Del button, so delete last char
if (b == 1) {
numberBuffer[numberIndex] = 0;
if (numberIndex > 0) {
numberIndex--;
numberBuffer[numberIndex] = 0;//' ';
}
status(""); // Clear the old status
}

if (b == 2) {
status("Sent value to serial port");
Serial.println(numberBuffer);
}
// we dont really check that the text field makes sense
// just try to call
if (b == 0) {
status("Value cleared");
numberIndex = 0; // Reset index to 0
numberBuffer[numberIndex] = 0; // Place null in buffer
}

// Update the number display field
tft.setTextDatum(TL_DATUM); // Use top left corner as text coord datum
tft.setFreeFont(&FreeSans18pt7b); // Choose a nicefont that fits box
tft.setTextColor(DISP_TCOLOR); // Set the font colour

// Draw the string, the value returned is the width in pixels
int xwidth = tft.drawString(numberBuffer, DISP_X + 4, DISP_Y + 12);

// Now cover up the rest of the line up by drawing a black rectangle. No flicker this way
// but it will not work with italic or oblique fonts due to character overlap.
tft.fillRect(DISP_X + 4 + xwidth, DISP_Y + 1, DISP_W - xwidth - 5, DISP_H - 2, TFT_BLACK);

delay(10); // UI debouncing
}
}
}

//------------------------------------------------------------------------------------------

void drawKeypad()
{
// Draw the keys
for (uint8_t row = 0; row < 5; row++) {
for (uint8_t col = 0; col < 3; col++) {
uint8_t b = col + row * 3;

if (b < 3) tft.setFreeFont(LABEL1_FONT);
else tft.setFreeFont(LABEL2_FONT);

key.initButton(&tft, KEY_X + col * (KEY_W + KEY_SPACING_X),
KEY_Y + row * (KEY_H + KEY_SPACING_Y), // x, y, w, h, outline, fill, text
KEY_W, KEY_H, TFT_WHITE, keyColor, TFT_WHITE,
keyLabel, KEY_TEXTSIZE);
key.drawButton();
}
}
}

//------------------------------------------------------------------------------------------
void touch_calibrate(){


diskSize = PROG_FLASH_SIZE;


// checks that the LittFS program has started with the disk size specified
if (!myfs.begin(diskSize)) {
Serial.printf("Error starting %s\n", "PROGRAM FLASH DISK");
while (1) {
// Error, so don't do anything more - stay stuck here
}
}
Serial.println("LittleFS initialized.");
//-------------------------------------------------------------
uint16_t calData[5];
uint8_t calDataOK = 0;

/*
// check file system exists
if (!myfs.begin()) {
Serial.println("Formating file system");
myfs.format();
myfs.begin();
}
*/

// check if calibration file exists and size is correct
if (myfs.exists(CALIBRATION_FILE)) {
if (REPEAT_CAL)
{
// Delete if we want to re-calibrate
myfs.remove(CALIBRATION_FILE);
}
else
{
File f = myfs.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 = myfs.open(CALIBRATION_FILE, "w");
if (f) {
f.write((const unsigned char *)calData, 14);
f.close();
}
}
}


// Print something in the mini status bar
void status(const char *msg) {
tft.setTextPadding(240);
//tft.setCursor(STATUS_X, STATUS_Y);
tft.setTextColor(TFT_WHITE, TFT_DARKGREY);
tft.setTextFont(0);
tft.setTextDatum(TC_DATUM);
tft.setTextSize(1);
tft.drawString(msg, STATUS_X, STATUS_Y);
}


I've made a little adaptation with the "paul stoffregen littlefs library" for the calibration file, because it was written for SPIFFS.

Tell me what you think :D
 
i'm going to an other surprise,the TOUCH_CS pin don't need to be wired

I correct the right pinouts of the touch,the comment pinouts was for ESP32

The TFT_MISO is not wired at all for the display.

Maybe someone can explain me why i don't need TOUCH_CS for the touch :confused:
But i don't mind,it's working great.

Here the working setup corrected:


---------------------The TFT_e_SPI setup:-----------------------------


#define ILI9488_DRIVER



#define TFT_MISO 12//not wired
#define TFT_MOSI 11
#define TFT_SCLK 13
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 16


#define TOUCH_CLK 13
#define TOUCH_CS 8 //(not wired but needs to have a declared number pin for the sketch)
#define TOUCH_DIN 11
#define TOUCH_DO 12




#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts


#define SMOOTH_FONT



#define SPI_FREQUENCY 20000000

#define SPI_READ_FREQUENCY 20000000


#define SPI_TOUCH_FREQUENCY 2500000
 
Back
Top