This commit is contained in:
Haroldo M Murata 2022-01-01 20:13:41 +00:00 committed by GitHub
commit cd1e8d1f71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 568 additions and 3 deletions

View File

@ -0,0 +1,103 @@
// Change the width and height if required (defined in portrait mode)
// or use the constructor to over-ride defaults
// Based ON: ILI9225_Defines.h for ST7781 / SPFD5408 (MCUFRIEND UNO/Mega Display Shield)
// https://www.crystalfontz.com/controllers/Sitronix/ST7781/
// https://www.rhydolabz.com/documents/SPFD5408A.pdf
#define WRITE_COMMAND_16 // Change TFT_eSPI::writecommand(); to use tft_Write_16(c);
#define TFT_WIDTH 240
#define TFT_HEIGHT 320
// Generic commands used by TFT_eSPI.cpp
#define TFT_NOP 0x00
#define TFT_SWRST 0x00 // NO Software Reset ?
#define TFT_CASET 0
#define TFT_PASET 0
#define TFT_CASET1 ST7781_HORIZONTAL_WINDOW_ADDR1
#define TFT_CASET2 ST7781_HORIZONTAL_WINDOW_ADDR2
#define TFT_PASET1 ST7781_VERTICAL_WINDOW_ADDR1
#define TFT_PASET2 ST7781_VERTICAL_WINDOW_ADDR2
#define TFT_RAM_ADDR1 ST7781_RAM_ADDR_SET1
#define TFT_RAM_ADDR2 ST7781_RAM_ADDR_SET2
#define TFT_RAMWR ST7781_RAM_DATA_REG
#define TFT_MAD_BGR 0x10
#define TFT_MAD_RGB 0x00
#ifdef TFT_RGB_ORDER
#if (TFT_RGB_ORDER == 1)
#define TFT_MAD_COLOR_ORDER TFT_MAD_RGB
#else
#define TFT_MAD_COLOR_ORDER TFT_MAD_BGR
#endif
#else
#define TFT_MAD_COLOR_ORDER TFT_MAD_BGR
#endif
// Not used
#define TFT_INVOFF 0x00
#define TFT_INVON 0x00
#define TFT_RAMRD 0x00
#define TFT_IDXRD 0x00
/* ST7781 Registers */
#define ST7781_DRIVER_OUTPUT_CTRL 0x01 // Driver Output Control
#define ST7781_LCD_AC_DRIVING_CTRL 0x02 // LCD AC Driving Control
#define ST7781_ENTRY_MODE 0x03 // Entry Mode
#define ST7781_RESIZE_CTRL 0x04 // Resize Control
#define ST7781_DISP_CTRL1 0x07 // Display Control 1
#define ST7781_DISP_CTRL2 0x08 // Display Control 2
#define ST7781_DISP_CTRL3 0x09 // Display Control 3
#define ST7781_DISP_CTRL4 0x0A // Display Control 4
#define ST7781_FRAME_MAKER_POS 0x0D // Frame Maker Position
#define ST7781_POWER_CTRL1 0x10 // Power Control 1
#define ST7781_POWER_CTRL2 0x11 // Power Control 2
#define ST7781_POWER_CTRL3 0x12 // Power Control 3
#define ST7781_POWER_CTRL4 0x13 // Power Control 4
#define ST7781_RAM_ADDR_SET1 0x20 // Horizontal GRAM Address Set
#define ST7781_RAM_ADDR_SET2 0x21 // Vertical GRAM Address Set
#define ST7781_RAM_DATA_REG 0x22 // Read/Write to RAM Data Register
#define ST7781_VCOMH_CTRL 0x29 // VCOMH Control
#define ST7781_FRAME_COLOR_CTRL 0x2B // Frame Rate and Color Control
#define ST7781_GAMMA_CTRL1 0x30 // Gamma Control 1
#define ST7781_GAMMA_CTRL2 0x31 // Gamma Control 2
#define ST7781_GAMMA_CTRL3 0x32 // Gamma Control 3
#define ST7781_GAMMA_CTRL4 0x35 // Gamma Control 4
#define ST7781_GAMMA_CTRL5 0x36 // Gamma Control 5
#define ST7781_GAMMA_CTRL6 0x37 // Gamma Control 6
#define ST7781_GAMMA_CTRL7 0x38 // Gamma Control 7
#define ST7781_GAMMA_CTRL8 0x39 // Gamma Control 8
#define ST7781_GAMMA_CTRL9 0x3C // Gamma Control 9
#define ST7781_GAMMA_CTRL10 0x3D // Gamma Control 10
#define ST7781_HORIZONTAL_WINDOW_ADDR1 0x50 // Horizontal Address Start Position
#define ST7781_HORIZONTAL_WINDOW_ADDR2 0x51 // Horizontal Address End Position
#define ST7781_VERTICAL_WINDOW_ADDR1 0x52 // Vertical Address Start Position
#define ST7781_VERTICAL_WINDOW_ADDR2 0x53 // Vertical Address End Position
#define ST7781_GATE_SCAN_CTRL1 0x60 // Gate Scan Control 1
#define ST7781_GATE_SCAN_CTRL2 0x61 // Gate Scan Control 2
#define ST7781_PARTIAL_POS_IMG1 0x80 // Partial Image 1 Display Position
#define ST7781_PARTIAL_START_ADDR_IMG1 0x81 // Partial Image 1 Start Address
#define ST7781_PARTIAL_END_ADDR_IMG1 0x82 // Partial Image 1 End Address
#define ST7781_PARTIAL_POS_IMG2 0x83 // Partial Image 2 Display Position
#define ST7781_PARTIAL_START_ADDR_IMG2 0x84 // Partial Image 2 Start Address
#define ST7781_PARTIAL_END_ADDR_IMG2 0x85 // Partial Image 2 End Address
#define ST7781_PANEL_IFACE_CTRL1 0x90 // Panel Interface Control 1
#define ST7781_PANEL_IFACE_CTRL2 0x92 // Panel Interface Control 2
#define ST7781_EEPROM_ID_CODE 0xD2 // EEPROM ID Code
#define ST7781_EEPROM_CTRL_STATUS 0xD9 // EEPROM Control Status
#define ST7781_EEPROM_WRITE_COMMAND 0xDF // EEPROM Wite Command
#define ST7781_EEPROM_ENABLE 0xFA // EEPROM Enable
#define ST7781_EEPROM_VCOM_OFFSET 0xFE // EEPROM VCOM Offset
#define ST7781_FA_FE_ENABLE 0xFF // FAh/FEh Enable
// Delay between some initialisation commands
//#define TFT_INIT_DELAY 0x00 // Not used unless commandlist invoked
#define TFT_INIT_DELAY 0x00

46
TFT_Drivers/ST7781_Init.h Normal file
View File

@ -0,0 +1,46 @@
//
// This is the command sequence that initialises the ST7781 / SPFD5408 driver
// References:
// - https://github.com/compihu/SWIFT-Shield
// - https://github.com/prenticedavid/MCUFRIEND_kbv
// SUPPORT_7781 / ST7781_regValues_CPT24
//
// This want full 16 bit command, so writecommand() is changed with define WRITE_COMMAND_16
{
writecommand(ST7781_DRIVER_OUTPUT_CTRL); writedata(0x01);writedata(0x00); // Driver Output Control Register (R01h)
writecommand(ST7781_LCD_AC_DRIVING_CTRL); writedata(0x07);writedata(0x00); // LCD Driving Waveform Control (R02h)
writecommand(ST7781_ENTRY_MODE); writedata(0x10);writedata(0x30); // Entry Mode (R03h)
writecommand(ST7781_DISP_CTRL2); writedata(0x03);writedata(0x02); // Porch
writecommand(ST7781_DISP_CTRL3); writedata(0x00);writedata(0x00); // Scan
writecommand(ST7781_DISP_CTRL4); writedata(0x00);writedata(0x08); // Fmark Off
writecommand(ST7781_POWER_CTRL1); writedata(0x00);writedata(0x08); // Power Control 1 (R10h)
writecommand(ST7781_POWER_CTRL2); writedata(0x00);writedata(0x05); // Power Control 2 (R11h)
writecommand(ST7781_POWER_CTRL3); writedata(0x00);writedata(0x00); // Power Control 3 (R12h)
writecommand(ST7781_POWER_CTRL4); writedata(0x00);writedata(0x00); // Power Control 4 (R13h)
delay(100);
writecommand(ST7781_POWER_CTRL1); writedata(0x12);writedata(0xB0); // Power Control 1 SAP=1, BT=2, APE=1, AP=3
delay(50);
writecommand(ST7781_POWER_CTRL2); writedata(0x00);writedata(0x07); // Power Control 2 VC=7
delay(50);
writecommand(ST7781_POWER_CTRL3); writedata(0x00);writedata(0x8C); // Power Control 3 VCIRE=1, VRH=12
writecommand(ST7781_POWER_CTRL4); writedata(0x17);writedata(0x00); // Power Control 4 VDV=23
writecommand(ST7781_VCOMH_CTRL); writedata(0x00);writedata(0x20); // NVM read data 2 VCM=32
delay(50);
writecommand(ST7781_GAMMA_CTRL1); writedata(0x00);writedata(0x00); // Gamma Control 1 App Note CPT 2.4
writecommand(ST7781_GAMMA_CTRL2); writedata(0x01);writedata(0x06); // Gamma Control 2
writecommand(ST7781_GAMMA_CTRL3); writedata(0x01);writedata(0x01); // Gamma Control 3
writecommand(ST7781_GAMMA_CTRL4); writedata(0x01);writedata(0x06); // Gamma Control 4
writecommand(ST7781_GAMMA_CTRL5); writedata(0x02);writedata(0x03); // Gamma Control 5
writecommand(ST7781_GAMMA_CTRL6); writedata(0x00);writedata(0x00); // Gamma Control 6
writecommand(ST7781_GAMMA_CTRL7); writedata(0x07);writedata(0x07); // Gamma Control 7
writecommand(ST7781_GAMMA_CTRL8); writedata(0x02);writedata(0x04); // Gamma Control 8
writecommand(ST7781_GAMMA_CTRL9); writedata(0x01);writedata(0x06); // Gamma Control 9
writecommand(ST7781_GAMMA_CTRL10); writedata(0x01);writedata(0x03); // Gamma Control 10
writecommand(ST7781_GATE_SCAN_CTRL1); writedata(0xA7);writedata(0x00); // Driver Output Control (R60h) .kbv was 0xa700
writecommand(ST7781_GATE_SCAN_CTRL2); writedata(0x00);writedata(0x01); // Driver Output Control (R61h)
writecommand(ST7781_PANEL_IFACE_CTRL1); writedata(0x00);writedata(0x30); // Panel Interface Control 1 (R90h)
// Display On
writecommand(ST7781_DISP_CTRL1); writedata(0x01);writedata(0x33); // Display Control (R07h)
delay(50);
}

View File

@ -0,0 +1,48 @@
// This is the command sequence that rotates the ST7781 driver coordinate frame
// Based on ILI9225_Rotation.h and MCUFRIEND_kbv = MCUFRIEND_kbv::setRotation()
rotation = m % 4; // Limit the range of values to 0-3
switch (rotation) {
case 0:
writecommand(ST7781_GATE_SCAN_CTRL1);
writedata(0xA7);writedata(0x00);
writecommand(ST7781_DRIVER_OUTPUT_CTRL);
writedata(0x01);writedata(0x00);
writecommand(ST7781_ENTRY_MODE);
writedata(TFT_MAD_COLOR_ORDER);writedata(0x30);
_width = _init_width;
_height = _init_height;
break;
case 1:
writecommand(ST7781_GATE_SCAN_CTRL1);
writedata(0xA7);writedata(0x00);
writecommand(ST7781_DRIVER_OUTPUT_CTRL);
writedata(0x00);writedata(0x00);
writecommand(ST7781_ENTRY_MODE);
writedata(TFT_MAD_COLOR_ORDER);writedata(0x38);
_width = _init_height;
_height = _init_width;
break;
case 2:
writecommand(ST7781_GATE_SCAN_CTRL1);
writedata(0x27);writedata(0x00);
writecommand(ST7781_DRIVER_OUTPUT_CTRL);
writedata(0x00);writedata(0x00);
writecommand(ST7781_ENTRY_MODE);
writedata(TFT_MAD_COLOR_ORDER);writedata(0x30);
_width = _init_width;
_height = _init_height;
break;
case 3:
writecommand(ST7781_GATE_SCAN_CTRL1);
writedata(0x27);writedata(0x00);
writecommand(ST7781_DRIVER_OUTPUT_CTRL);
writedata(0x01);writedata(0x00);
writecommand(ST7781_ENTRY_MODE);
writedata(TFT_MAD_COLOR_ORDER);writedata(0x38);
_width = _init_height;
_height = _init_width;
break;
}

View File

@ -658,6 +658,9 @@ void TFT_eSPI::init(uint8_t tc)
#elif defined (ILI9225_DRIVER)
#include "TFT_Drivers/ILI9225_Init.h"
#elif defined (ST7781_DRIVER)
#include "TFT_Drivers/ST7781_Init.h"
#endif
#ifdef TFT_INVERSION_ON
@ -746,6 +749,9 @@ void TFT_eSPI::setRotation(uint8_t m)
#elif defined (ILI9225_DRIVER)
#include "TFT_Drivers/ILI9225_Rotation.h"
#elif defined (ST7781_DRIVER)
#include "TFT_Drivers/ST7781_Rotation.h"
#endif
delayMicroseconds(10);
@ -816,7 +822,11 @@ void TFT_eSPI::writecommand(uint8_t c)
DC_C;
#if defined(WRITE_COMMAND_16)
tft_Write_16(c);
#else
tft_Write_8(c);
#endif
DC_D;
@ -945,6 +955,10 @@ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0)
// Dummy read to throw away don't care value
readByte();
#endif
// Some drives need throw 16 bits
#if defined (ST7781_DRIVER)
readByte();
#endif
// Fetch the 16 bit BRG pixel
//uint16_t rgb = (readByte() << 8) | readByte();
@ -971,7 +985,7 @@ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0)
// Set masked pins D0- D7 to output
busDir(dir_mask, OUTPUT);
#ifdef ILI9486_DRIVER
#if defined(ILI9486_DRIVER) | defined(ST7781_DRIVER)
return bgr;
#else
// Swap Red and Blue (could check MADCTL setting to see if this is needed)
@ -1105,13 +1119,17 @@ void TFT_eSPI::readRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *da
#else // ILI9481 reads as 16 bits
// Dummy read to throw away don't care value
readByte();
// Some drives need throw 16 bits
#if defined (ST7781_DRIVER)
readByte();
#endif
// Fetch the 16 bit BRG pixels
while (dh--) {
int32_t lw = dw;
uint16_t* line = data;
while (lw--) {
#ifdef ILI9486_DRIVER
#if defined (ILI9486_DRIVER) | defined (ST7781_DRIVER)
// Read the RGB 16 bit colour
*line++ = readByte() | (readByte() << 8);
#else
@ -3066,6 +3084,32 @@ void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
// write to RAM
DC_C; tft_Write_8(TFT_RAMWR);
DC_D;
#elif defined (ST7781_DRIVER) // Like ILI9225_DRIVER, but 16 bits
if (rotation & 0x01) { swap_coord(x0, y0); swap_coord(x1, y1); }
addr_row = 0xFFFF;
addr_col = 0xFFFF;
DC_C; tft_Write_16(TFT_CASET1);
DC_D; tft_Write_16(x0);
DC_C; tft_Write_16(TFT_CASET2);
DC_D; tft_Write_16(x1);
DC_C; tft_Write_16(TFT_PASET1);
DC_D; tft_Write_16(y0);
DC_C; tft_Write_16(TFT_PASET2);
DC_D; tft_Write_16(y1);
DC_C; tft_Write_16(TFT_RAM_ADDR1);
DC_D; tft_Write_16(x0);
DC_C; tft_Write_16(TFT_RAM_ADDR2);
DC_D; tft_Write_16(y0);
// write to RAM
DC_C; tft_Write_16(TFT_RAMWR);
DC_D;
#elif defined (SSD1351_DRIVER)
if (rotation & 1) {
swap_coord(x0, y0);
@ -3207,6 +3251,32 @@ void TFT_eSPI::readAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h)
while (spi_is_readable(SPI_X)) (void)spi_get_hw(SPI_X)->dr;
spi_get_hw(SPI_X)->icr = SPI_SSPICR_RORIC_BITS;
#elif defined (ST7781_DRIVER)
// Is Like setWindow()
if (rotation & 0x01) { swap_coord(xs, ys); swap_coord(xe, ye); }
// Horizontal Range
DC_C; tft_Write_16(TFT_CASET1);
DC_D; tft_Write_16(xs);
DC_C; tft_Write_16(TFT_CASET2);
DC_D; tft_Write_16(xe);
// Vertical Range
DC_C; tft_Write_16(TFT_PASET1);
DC_D; tft_Write_16(ys);
DC_C; tft_Write_16(TFT_PASET2);
DC_D; tft_Write_16(ye);
// Start Address Pointer
DC_C; tft_Write_16(TFT_RAM_ADDR1);
DC_D; tft_Write_16(xs);
DC_C; tft_Write_16(TFT_RAM_ADDR2);
DC_D; tft_Write_16(ys);
// write to RAM
DC_C; tft_Write_16(TFT_RAMWR);
DC_D;
#else
// Column addr set
DC_C; tft_Write_8(TFT_CASET);
@ -3281,6 +3351,34 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
DC_D; tft_Write_16N(color);
#endif
#elif defined (ST7781_DRIVER) // Like ILI9225_DRIVER, but commands 16 Bits
if (rotation & 0x01) { swap_coord(x, y); }
// Set window to full screen to optimise sequential pixel rendering
if (addr_row != TFT_DRIVER) {
addr_row = TFT_DRIVER; // addr_row used for flag
DC_C; tft_Write_16(TFT_CASET1);
DC_D; tft_Write_16(0);
DC_C; tft_Write_16(TFT_CASET2);
DC_D; tft_Write_16(TFT_WIDTH - 1);
DC_C; tft_Write_16(TFT_PASET1);
DC_D; tft_Write_16(0);
DC_C; tft_Write_16(TFT_PASET2);
DC_D; tft_Write_16(TFT_HEIGHT - 1);
}
// Define pixel coordinate
DC_C; tft_Write_16(TFT_RAM_ADDR1);
DC_D; tft_Write_16(x);
DC_C; tft_Write_16(TFT_RAM_ADDR2);
DC_D; tft_Write_16(y);
// write to RAM
DC_C; tft_Write_16(TFT_RAMWR);
DC_D; tft_Write_16(color);
// Temporary solution is to include the RP2040 optimised code here
#elif (defined (ARDUINO_ARCH_RP2040) || defined (ARDUINO_ARCH_MBED)) && !defined(TFT_PARALLEL_8_BIT)

View File

@ -67,6 +67,7 @@
//#include <User_Setups/Setup35_ILI9341_STM32_Port_Bus.h> // Setup for STM32 port A parallel display
//#include <User_Setups/Setup36_RPi_touch_ST7796.h> // Setup file configured for ESP32 and RPi ST7796 TFT with touch
//#include <User_Setups/Setup37_ST7781.h> // Setup for ST7781 parallel display
//#include <User_Setups/Setup43_ST7735.h> // Setup file configured for my ST7735S 80x160
//#include <User_Setups/Setup44_TTGO_CameraPlus.h> // Setup file for ESP32 and TTGO T-CameraPlus ST7789 SPI bus TFT 240x240
@ -209,6 +210,9 @@
#elif defined (ILI9225_DRIVER)
#include "TFT_Drivers/ILI9225_Defines.h"
#define TFT_DRIVER 0x9225
#elif defined (ST7781_DRIVER)
#include "TFT_Drivers/ST7781_Defines.h"
#define TFT_DRIVER 0x7781
// <<<<<<<<<<<<<<<<<<<<<<<< ADD NEW DRIVER HERE
// XYZZY_init.h and XYZZY_rotation.h must also be added in TFT_eSPI.cpp
#elif defined (XYZZY_DRIVER)

View File

@ -0,0 +1,37 @@
// Setup for ESP32 and ST7781/SPFD5408 240 x 320 TFT
// See SetupX_Template.h for all options available
#define ST7781_DRIVER
#define TFT_PARALLEL_8_BIT // MCUFRIEND Shields is Parallel
// ESP32 pins used for the parallel interface TFT
#define TFT_CS 27 // Chip select control pin
#define TFT_DC 14 // Data Command control pin - must use a pin in the range 0-31
#define TFT_RST 26 // Reset pin
#define TFT_WR 12 // Write strobe control pin - must use a pin in the range 0-31
#define TFT_RD 13
#define TFT_D0 16 // Must use pins in the range 0-31 for the data bus
#define TFT_D1 4 // so a single register write sets/clears all bits
#define TFT_D2 23
#define TFT_D3 22
#define TFT_D4 21
#define TFT_D5 19
#define TFT_D6 18
#define TFT_D7 17
#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_FREQUENCY 27000000 // Actually sets it to 26.67MHz = 80/3

View File

@ -0,0 +1,229 @@
/*
Common Paint Example
Is adapted to work with Resistive touch from TFT 2.4" MCUFRIEND Shield
with chipset ST7781 / SPFD5408. This uses shared pins to touch analogic
values.
Tested with ESP32-Dev Board.
Need connect pin SD_SCK and set in PIN_SD_SCK
Need download Adafruit Resistive Touch Library: Adafruit_TouchScreen
On different boards maybe need adjust isValidPressure()
Make sure all the display driver and pin connections are correct by
editing the User_Setup.h file in the TFT_eSPI library folder.
#########################################################################
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
#########################################################################
*/
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>
#include <TouchScreen.h> // Adafruit_TouchScreen
// If User_Setup.h is OK, just need setup this option.
// On Display, Touch Screen shares PIN with SD Card
// Just select one free pin, this example use GPIO 32 on ESP32
#define PIN_SD_SCK 32
#define YP TFT_WR // On Uno is pin A1, just use User_Setup.h
#define XM TFT_DC // On Uno is pin A2, just use User_Setup.h
#define YM TFT_D7 // On Uno is pin D7, just use User_Setup.h
#define XP TFT_D6 // On Uno is pin D6, just use User_Setup.h
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
TSPoint p;
TFT_eSPI tft = TFT_eSPI();
#define BOXSIZE 40
#define PENRADIUS 3
int oldcolor, currentcolor;
int calibration = 0;
int16_t calibMinX = 0;
int16_t calibMinY = 0;
int16_t calibMaxX = 0;
int16_t calibMaxY = 0;
int16_t userX = 0;
int16_t userY = 0;
void setup(void) {
Serial.begin(115200);
Serial.println(F("Paint Time!"));
//
uint16_t identifier = tft.readcommand16(0x00, 2); // 16 Bits
Serial.print(F("LCD driver chip: "));
Serial.println(identifier, HEX);
//
Serial.print("Screen Width: "); Serial.println(tft.width());
Serial.print("Screen Height: "); Serial.println(tft.height());
//
pinMode(PIN_SD_SCK, OUTPUT);
tft.begin();
tft.fillScreen(TFT_BLACK);
}
void loop() {
if (calibration < 30) {
doCalibration();
return;
}
//
if (isValidPressure()) {
// Serial.print("X = "); Serial.print(p.x);
// Serial.print("\tY = "); Serial.print(p.y);
// Serial.print("\tPressure = "); Serial.println(p.z);
// Calculate correct user touch
userX = map(p.x, calibMinX, calibMaxX, 0, tft.width());
userY = map(p.y, calibMinY, calibMaxY, 0, tft.height());
// Fix limits
if (userX < 0) userX = 0;
if (userY < 0) userY = 0;
if (userX > tft.width()) userX = tft.width();
if (userY > tft.height()) userY = tft.height();
// Serial.print("User X: "); Serial.print(userX);
// Serial.print("\tUser Y: "); Serial.println(userY);
if (userY > (tft.height()-5)) {
// Serial.println("Erase");
// press the bottom of the screen to erase
tft.fillRect(0, BOXSIZE, tft.width(), tft.height()-BOXSIZE, TFT_BLACK);
}
// Select colors
if (userY < BOXSIZE) {
oldcolor = currentcolor;
if (userX < BOXSIZE) {
currentcolor = TFT_RED;
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, TFT_WHITE);
} else if (userX < BOXSIZE*2) {
currentcolor = TFT_YELLOW;
tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, TFT_WHITE);
} else if (userX < BOXSIZE*3) {
currentcolor = TFT_GREEN;
tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, TFT_WHITE);
} else if (userX < BOXSIZE*4) {
currentcolor = TFT_CYAN;
tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, TFT_WHITE);
} else if (userX < BOXSIZE*5) {
currentcolor = TFT_BLUE;
tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, TFT_WHITE);
} else if (userX < BOXSIZE*6) {
currentcolor = TFT_MAGENTA;
tft.drawRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, TFT_WHITE);
}
if (oldcolor != currentcolor) {
if (oldcolor == TFT_RED) tft.fillRect(0, 0, BOXSIZE, BOXSIZE, TFT_RED);
if (oldcolor == TFT_YELLOW) tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, TFT_YELLOW);
if (oldcolor == TFT_GREEN) tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, TFT_GREEN);
if (oldcolor == TFT_CYAN) tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, TFT_CYAN);
if (oldcolor == TFT_BLUE) tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, TFT_BLUE);
if (oldcolor == TFT_MAGENTA) tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, TFT_MAGENTA);
}
}
if (((userY-PENRADIUS) > BOXSIZE) && ((userY+PENRADIUS) < tft.height())) {
tft.fillCircle(userX, userY, PENRADIUS, currentcolor);
}
}
}
void drawnPalette() {
tft.fillRect(0 , 0, BOXSIZE, BOXSIZE, TFT_RED);
tft.fillRect(BOXSIZE , 0, BOXSIZE, BOXSIZE, TFT_YELLOW);
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, TFT_GREEN);
tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, TFT_CYAN);
tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, TFT_BLUE);
tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, TFT_MAGENTA);
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, TFT_WHITE);
currentcolor = TFT_RED;
}
void readTouchPoint() {
// Switch SD CLK to read touch data
digitalWrite(PIN_SD_SCK, HIGH);
p = ts.getPoint(); // read to global
digitalWrite(PIN_SD_SCK, LOW);
// if sharing pins, you'll need to fix the directions of the touchscreen pins
//pinMode(XP, OUTPUT);
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
//pinMode(YM, OUTPUT);
}
bool isValidPressure()
{
readTouchPoint();
// I using ESP 32, and reading on Z is 0 (zero) no touch (normally),
// and Adafruit library return negative values or positive..
//if (p.z > 10 && p.z < 1000) { // Original
if (p.z > 1 || p.z < -1) {
return true;
}
return false;
}
// Simple calibration steps
void doCalibration() {
if (calibration == 0) {
// Draw 0,0 circle
tft.fillCircle(10, 10, 10, TFT_WHITE);
tft.setCursor(5, 30);
tft.setTextColor(TFT_WHITE);
tft.println("1: TOUCH ON CIRCLE TO CALIBRATE");
calibration = 1;
return;
}
if (calibration == 1) {
if (isValidPressure()) {
calibMinX = p.x;
calibMinY = p.y;
//Serial.print("Z:"); Serial.print(p.z);
Serial.print("[minX:");
Serial.print(calibMinX);
Serial.print("][minY:");
Serial.print(calibMinY);
Serial.println("]");
calibration = 2;
tft.fillScreen(TFT_BLACK);
}
return;
}
if (calibration == 2) {
// Draw 0,0 circle
tft.fillCircle(tft.width() - 10, tft.height() - 10, 10, TFT_WHITE);
tft.setCursor(5, 30);
tft.setTextColor(TFT_WHITE);
tft.println("2: TOUCH ON CIRCLE TO CALIBRATE");
calibration = 3;
delay(3000);// Wait to not get multiple touch on last location, users will press a lot the second point ;P
return;
}
if (calibration == 3) {
if (isValidPressure()) {
calibMaxX = p.x;
calibMaxY = p.y;
Serial.print("[maxX:");
Serial.print(calibMaxX);
Serial.print("][maxY:");
Serial.print(calibMaxY);
Serial.println("]");
Serial.println("Calibration Ended.");
calibration = 33; // end
tft.fillScreen(TFT_BLACK);
drawnPalette();
}
return;
}
}