Added support for RPi TFT

16 bit serial based ILI9486 supported
This commit is contained in:
Bodmer
2017-03-24 23:23:35 +00:00
parent 20c9086853
commit 4f8029b096
29 changed files with 5624 additions and 31 deletions

View File

@@ -0,0 +1,57 @@
// Change the width and height if required (defined in portrait mode)
// or use the constructor to over-ride defaults
#define TFT_WIDTH 320
#define TFT_HEIGHT 480
// Color definitions for backwards compatibility with old sketches
// use colour definitions like TFT_BLACK to make sketches more portable
#define ILI9486_BLACK 0x0000 /* 0, 0, 0 */
#define ILI9486_NAVY 0x000F /* 0, 0, 128 */
#define ILI9486_DARKGREEN 0x03E0 /* 0, 128, 0 */
#define ILI9486_DARKCYAN 0x03EF /* 0, 128, 128 */
#define ILI9486_MAROON 0x7800 /* 128, 0, 0 */
#define ILI9486_PURPLE 0x780F /* 128, 0, 128 */
#define ILI9486_OLIVE 0x7BE0 /* 128, 128, 0 */
#define ILI9486_LIGHTGREY 0xC618 /* 192, 192, 192 */
#define ILI9486_DARKGREY 0x7BEF /* 128, 128, 128 */
#define ILI9486_BLUE 0x001F /* 0, 0, 255 */
#define ILI9486_GREEN 0x07E0 /* 0, 255, 0 */
#define ILI9486_CYAN 0x07FF /* 0, 255, 255 */
#define ILI9486_RED 0xF800 /* 255, 0, 0 */
#define ILI9486_MAGENTA 0xF81F /* 255, 0, 255 */
#define ILI9486_YELLOW 0xFFE0 /* 255, 255, 0 */
#define ILI9486_WHITE 0xFFFF /* 255, 255, 255 */
#define ILI9486_ORANGE 0xFD20 /* 255, 165, 0 */
#define ILI9486_GREENYELLOW 0xAFE5 /* 173, 255, 47 */
#define ILI9486_PINK 0xF81F
// Delay between some initialisation commands
#define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked
// Generic commands used by TFT_eSPI.cpp
#define TFT_NOP 0x00
#define TFT_SWRST 0x01
#define TFT_CASET 0x2A
#define TFT_PASET 0x2B
#define TFT_RAMWR 0x2C
#define TFT_RAMRD 0x2E
#define TFT_IDXRD 0x00 // ILI9341 only, indexed control register read
#define TFT_MADCTL 0x36
#define TFT_MAD_MY 0x80
#define TFT_MAD_MX 0x40
#define TFT_MAD_MV 0x20
#define TFT_MAD_ML 0x10
#define TFT_MAD_BGR 0x08
#define TFT_MAD_MH 0x04
#define TFT_MAD_SS 0x02
#define TFT_MAD_GS 0x01
#define TFT_MAD_RGB 0x00
#define TFT_INVOFF 0x20
#define TFT_INVON 0x21

View File

@@ -0,0 +1,70 @@
// This is the command sequence that initialises the ILI9481 driver
//
// This setup information uses simple 8 bit SPI writecommand() and writedata() functions
//
// See ST7735_Setup.h file for an alternative format
{
// From https://github.com/notro/fbtft/blob/master/fb_ili9486.c
//writecommand(0x01); // SW reset
//delay(120);
writecommand(0x11); // Sleep out, also SW reset
delay(120);
writecommand(0x3A);
writedata(0x55);
writecommand(0xC2);
writedata(0x44);
writecommand(0xC5);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writecommand(0xE0);
writedata(0x0F);
writedata(0x1F);
writedata(0x1C);
writedata(0x0C);
writedata(0x0F);
writedata(0x08);
writedata(0x48);
writedata(0x98);
writedata(0x37);
writedata(0x0A);
writedata(0x13);
writedata(0x04);
writedata(0x11);
writedata(0x0D);
writedata(0x00);
writecommand(0xE1);
writedata(0x0F);
writedata(0x32);
writedata(0x2E);
writedata(0x0B);
writedata(0x0D);
writedata(0x05);
writedata(0x47);
writedata(0x75);
writedata(0x37);
writedata(0x06);
writedata(0x10);
writedata(0x03);
writedata(0x24);
writedata(0x20);
writedata(0x00);
writecommand(0x20); // display inversion OFF
writecommand(0x36);
writedata(0x0A);
writecommand(0x29); // display on
delay(150);
}

View File

@@ -0,0 +1,47 @@
// This is the command sequence that rotates the ILI9486 driver coordinate frame
writecommand(TFT_MADCTL);
rotation = m % 8;
switch (rotation) {
case 0: // Portrait
writedata(TFT_MAD_BGR | TFT_MAD_MX);
_width = TFT_WIDTH;
_height = TFT_HEIGHT;
break;
case 1: // Landscape (Portrait + 90)
writedata(TFT_MAD_BGR | TFT_MAD_MV);
_width = TFT_HEIGHT;
_height = TFT_WIDTH;
break;
case 2: // Inverter portrait
writedata( TFT_MAD_BGR | TFT_MAD_MY);
_width = TFT_WIDTH;
_height = TFT_HEIGHT;
break;
case 3: // Inverted landscape
writedata(TFT_MAD_BGR | TFT_MAD_MV | TFT_MAD_MX | TFT_MAD_MY);
_width = TFT_HEIGHT;
_height = TFT_WIDTH;
break;
case 4: // Portrait
writedata(TFT_MAD_BGR | TFT_MAD_MX | TFT_MAD_MY);
_width = TFT_WIDTH;
_height = TFT_HEIGHT;
break;
case 5: // Landscape (Portrait + 90)
writedata(TFT_MAD_BGR | TFT_MAD_MV | TFT_MAD_MX);
_width = TFT_HEIGHT;
_height = TFT_WIDTH;
break;
case 6: // Inverter portrait
writedata( TFT_MAD_BGR);
_width = TFT_WIDTH;
_height = TFT_HEIGHT;
break;
case 7: // Inverted landscape
writedata(TFT_MAD_BGR | TFT_MAD_MV | TFT_MAD_MY);
_width = TFT_HEIGHT;
_height = TFT_WIDTH;
break;
}

988
TFT_Drivers/XXXXXXX_init.h Normal file
View File

@@ -0,0 +1,988 @@
// This is the command sequence that initialises the ILI9481 driver
//
// This setup information uses simple 8 bit SPI writecommand() and writedata() functions
//
// See ST7735_Setup.h file for an alternative format
{
#if defined (TINYLCD)
//ILI9486 wave share 3.5 A B is ILI9340?
writecommand(0x01);
writedata(0x00);
delay(50);
writecommand(0x28);
writedata(0x00);
//writecommand(0xB0); // Power Control 1
//writedata(0x00);
//writecommand(0x11); // Sleep OUT
//delay(50);
/*
writecommand(0xC5); // VCOM Control
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0x00);
//writedata(0x48); was 00 48
*/
/*
writecommand(0xF2); // ?????
writedata(0x1C);
writedata(0xA3);
writedata(0x32);
writedata(0x02);
writedata(0xb2);
writedata(0x12);
writedata(0xFF);
writedata(0x12);
writedata(0x00);
writecommand(0xF1); // ?????
writedata(0x36);
writedata(0xA4);
writecommand(0xF8); // ?????
writedata(0x21);
writedata(0x04);
writecommand(0xF9); // ?????
writedata(0x00);
writedata(0x08);
*/
writecommand(0xC0); // Power Control 1
writedata(0x0d);
writedata(0x0d);
writecommand(0xC1); // Power Control 2
writedata(0x43);
writedata(0x00);
writecommand(0xC2); // Power Control 3
writedata(0x00); // was 0x44
writecommand(0xC5); // VCOM Control
writedata(0x00);
writedata(0x48);
writecommand(0xB6); // Display Function Control
writedata(0x00);
writedata(0x22); // 0x42 = Rotate display 180 deg.
writedata(0x3B);
writecommand(0xE0); // PGAMCTRL (Positive Gamma Control)
writedata(0x0f);
writedata(0x24);
writedata(0x1c);
writedata(0x0a);
writedata(0x0f);
writedata(0x08);
writedata(0x43);
writedata(0x88);
writedata(0x32);
writedata(0x0f);
writedata(0x10);
writedata(0x06);
writedata(0x0f);
writedata(0x07);
writedata(0x00);
writecommand(0xE1); // NGAMCTRL (Negative Gamma Control)
writedata(0x0F);
writedata(0x38);
writedata(0x30);
writedata(0x09);
writedata(0x0f);
writedata(0x0f);
writedata(0x4e);
writedata(0x77);
writedata(0x3c);
writedata(0x07);
writedata(0x10);
writedata(0x05);
writedata(0x23);
writedata(0x1b);
writedata(0x00);
/*
writecommand(0xE2); // NGAMCTRL (Negative Gamma Control)
writedata(0x0F);
writedata(0x38);
writedata(0x30);
writedata(0x09);
writedata(0x0f);
writedata(0x0f);
writedata(0x4e);
writedata(0x77);
writedata(0x3c);
writedata(0x07);
writedata(0x10);
writedata(0x05);
writedata(0x23);
writedata(0x1b);
writedata(0x00);
*/
writecommand(0x20); // Display Inversion OFF, 0x21 = ON
writecommand(0x3A); // Interface Pixel Format
writedata(0x55);
writecommand(0x36); // Memory Access Control
writedata(0x0A);
writecommand(0x11); // Sleep OUT
delay(50);
writecommand(0x29); // Display ON
delay(25);
#elif defined ILI9486
// from https://developer.mbed.org/teams/GraphicsDisplay/code/UniGraphic/file/12ba0ecc2c1f/Inits/ILI9486.cpp
/*
writecommand(0xF1);
writedata(0x36);
writedata(0x04);
writedata(0x00);
writedata(0x3C);
writedata(0x0F);
writedata(0x8F);
writecommand(0xF2);
writedata(0x18);
writedata(0xA3);
writedata(0x12);
writedata(0x02);
writedata(0xb2);
writedata(0x12);
writedata(0xFF);
writedata(0x10);
writedata(0x00);
writecommand(0xF8);
writedata(0x21);
writedata(0x04);
writecommand(0xF9);
writedata(0x00);
writedata(0x08);
*/
writecommand(0xC0);
writedata(0x0f); //13
writedata(0x0f); //10
writecommand(0xC1);
writedata(0x42); //43
writecommand(0xC2);
writedata(0x22);
writecommand(0xC5);
writedata(0x01); //00
writedata(0x29); //4D
writedata(0x80);
writecommand(0xB6);
writedata(0x00);
writedata(0x02); //42
writedata(0x3b);
writecommand(0xB1);
writedata(0xB0); //C0
writedata(0x11);
writecommand(0xB4);
writedata(0x02); //01
writecommand(0xE0);
writedata(0x0F);
writedata(0x18);
writedata(0x15);
writedata(0x09);
writedata(0x0B);
writedata(0x04);
writedata(0x49);
writedata(0x64);
writedata(0x3D);
writedata(0x08);
writedata(0x15);
writedata(0x06);
writedata(0x12);
writedata(0x07);
writedata(0x00);
writecommand(0xE1);
writedata(0x0F);
writedata(0x38);
writedata(0x35);
writedata(0x0a);
writedata(0x0c);
writedata(0x03);
writedata(0x4A);
writedata(0x42);
writedata(0x36);
writedata(0x04);
writedata(0x0F);
writedata(0x03);
writedata(0x1F);
writedata(0x1B);
writedata(0x00);
writecommand(0x20); // display inversion OFF
writecommand(0x36); // MEMORY_ACCESS_CONTROL (orientation stuff)
writedata(0x48);
writecommand(0x3A); // COLMOD_PIXEL_FORMAT_SET
writedata(0x55); // 16 bit pixel
writecommand(0x13); // Nomal Displaymode
writecommand(0x11); // sleep out
delay(150);
writecommand(0x29); // display on
delay(150);
#elif defined (ILI9486_2)
// From https://github.com/notro/fbtft/blob/master/fb_ili9486.c
//writecommand(0x01); // SW reset
//delay(120);
writecommand(0x11); // Sleep out, also SW reset
delay(120);
writecommand(0x3A);
writedata(0x55);
writecommand(0xC2);
writedata(0x44);
writecommand(0xC5);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writecommand(0xE0);
writedata(0x0F);
writedata(0x1F);
writedata(0x1C);
writedata(0x0C);
writedata(0x0F);
writedata(0x08);
writedata(0x48);
writedata(0x98);
writedata(0x37);
writedata(0x0A);
writedata(0x13);
writedata(0x04);
writedata(0x11);
writedata(0x0D);
writedata(0x00);
writecommand(0xE1);
writedata(0x0F);
writedata(0x32);
writedata(0x2E);
writedata(0x0B);
writedata(0x0D);
writedata(0x05);
writedata(0x47);
writedata(0x75);
writedata(0x37);
writedata(0x06);
writedata(0x10);
writedata(0x03);
writedata(0x24);
writedata(0x20);
writedata(0x00);
writecommand(0x20); // display inversion OFF
writecommand(0x36);
writedata(0x0A);
writecommand(0x29); // display on
delay(150);
#elif defined (R61581)
// R61581:
writecommand(0xB0);
writedata(0x1E);
writecommand(0xB0);
writedata(0x00);
writecommand(0xB3);
writedata(0x02);
writedata(0x00);
writedata(0x00);
writedata(0x10);
writecommand(0xB4);
writedata(0x00);//0X10
// writecommand(0xB9); //PWM Settings for Brightness Control
// writedata(0x01);// Disabled by default.
// writedata(0xFF); //0xFF = Max brightness
// writedata(0xFF);
// writedata(0x18);
writecommand(0xC0);
writedata(0x03);
writedata(0x3B);//
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x00);//NW
writedata(0x43);
writecommand(0xC1);
writedata(0x08);
writedata(0x15);//CLOCK
writedata(0x08);
writedata(0x08);
writecommand(0xC4);
writedata(0x15);
writedata(0x03);
writedata(0x03);
writedata(0x01);
writecommand(0xC6);
writedata(0x02);
writecommand(0xC8);
writedata(0x0c);
writedata(0x05);
writedata(0x0A);//0X12
writedata(0x6B);//0x7D
writedata(0x04);
writedata(0x06);//0x08
writedata(0x15);//0x0A
writedata(0x10);
writedata(0x00);
writedata(0x60);//0x23
writecommand(0x36);
writedata(0x0A);
writecommand(0x0C);
writedata(0x55);
writecommand(0x3A);
writedata(0x55);
writecommand(0x38);
writecommand(0xD0);
writedata(0x07);
writedata(0x07);//VCI1
writedata(0x14);//VRH 0x1D
writedata(0xA2);//BT 0x06
writecommand(0xD1);
writedata(0x03);
writedata(0x5A);//VCM 0x5A
writedata(0x10);//VDV
writecommand(0xD2);
writedata(0x03);
writedata(0x04);//0x24
writedata(0x04);
writecommand(0x11);
delay(150);
writecommand(0x2A);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0xDF);//320
writecommand(0x2B);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x3F);//480
delay(100);
writecommand(0x29);
delay(30);
writecommand(0x2C);
delay(30);
#elif defined (HX8357B)
//Serial.println("linux HX8357B");
// seqpower
writecommand(HX8357B_SETPOWER);
writedata(0x44);
writedata(0x41);
writedata(0x06);
// seq_vcom
writecommand(HX8357B_SETVCOM);
writedata(0x40);
writedata(0x10);
// seq_power_normal
writecommand(HX8357B_SETPWRNORMAL);
writedata(0x05);
writedata(0x12);
// seq_panel_driving
writecommand(HX8357B_SET_PANEL_DRIVING);
writedata(0x14);
writedata(0x3b);
writedata(0x00);
writedata(0x02);
writedata(0x11);
// seq_display_frame
writecommand(HX8357B_SETDISPLAYFRAME);
writedata(0x0c); // 6.8mhz
// seq_panel_related
writecommand(HX8357B_SETPANELRELATED);
writedata(0x01); // BGR
// seq_undefined1
writecommand(0xEA);
writedata(0x03);
writedata(0x00);
writedata(0x00);
// undef2
writecommand(0xEB);
writedata(0x40);
writedata(0x54);
writedata(0x26);
writedata(0xdb);
// seq_gamma
writecommand(HX8357B_SETGAMMA); // 0xC8
writedata(0x00);
writedata(0x15);
writedata(0x00);
writedata(0x22);
writedata(0x00);
writedata(0x08);
writedata(0x77);
writedata(0x26);
writedata(0x66);
writedata(0x22);
writedata(0x04);
writedata(0x00);
// seq_addr mode
writecommand(HX8357_MADCTL);
writedata(0xC0);
// pixel format
writecommand(HX8357_COLMOD);
writedata(0x55);
// set up whole address box
// paddr
writecommand(HX8357_PASET);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0xDF);
// caddr
writecommand(HX8357_CASET);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x3F);
// display mode
writecommand(HX8357B_SETDISPMODE);
writedata(0x00); // CPU (DBI) and internal oscillation ??
// exit sleep
writecommand(HX8357_SLPOUT);
delay(120);
// main screen turn on
writecommand(HX8357_DISPON);
delay(10);
#elif defined (HX8257D)
writecommand(HX8357_SWRESET);
delay(10);
// setextc
writecommand(HX8357D_SETC);
writedata(0xFF);
writedata(0x83);
writedata(0x57);
delay(300);
// setRGB which also enables SDO
writecommand(HX8357_SETRGB);
writedata(0x80); //enable SDO pin!
// writedata(0x00); //disable SDO pin!
writedata(0x0);
writedata(0x06);
writedata(0x06);
writecommand(HX8357D_SETCOM);
writedata(0x25); // -1.52V
writecommand(HX8357_SETOSC);
writedata(0x68); // Normal mode 70Hz, Idle mode 55 Hz
writecommand(HX8357_SETPANEL); //Set Panel
writedata(0x05); // BGR, Gate direction swapped
writecommand(HX8357_SETPWR1);
writedata(0x00); // Not deep standby
writedata(0x15); //BT
writedata(0x1C); //VSPR
writedata(0x1C); //VSNR
writedata(0x83); //AP
writedata(0xAA); //FS
writecommand(HX8357D_SETSTBA);
writedata(0x50); //OPON normal
writedata(0x50); //OPON idle
writedata(0x01); //STBA
writedata(0x3C); //STBA
writedata(0x1E); //STBA
writedata(0x08); //GEN
writecommand(HX8357D_SETCYC);
writedata(0x02); //NW 0x02
writedata(0x40); //RTN
writedata(0x00); //DIV
writedata(0x2A); //DUM
writedata(0x2A); //DUM
writedata(0x0D); //GDON
writedata(0x78); //GDOFF
writecommand(HX8357D_SETGAMMA);
writedata(0x02);
writedata(0x0A);
writedata(0x11);
writedata(0x1d);
writedata(0x23);
writedata(0x35);
writedata(0x41);
writedata(0x4b);
writedata(0x4b);
writedata(0x42);
writedata(0x3A);
writedata(0x27);
writedata(0x1B);
writedata(0x08);
writedata(0x09);
writedata(0x03);
writedata(0x02);
writedata(0x0A);
writedata(0x11);
writedata(0x1d);
writedata(0x23);
writedata(0x35);
writedata(0x41);
writedata(0x4b);
writedata(0x4b);
writedata(0x42);
writedata(0x3A);
writedata(0x27);
writedata(0x1B);
writedata(0x08);
writedata(0x09);
writedata(0x03);
writedata(0x00);
writedata(0x01);
writecommand(HX8357_COLMOD);
writedata(0x55); // 16 bit
writecommand(HX8357_MADCTL);
writedata(0xC0);
writecommand(HX8357_TEON); // TE off
writedata(0x00);
writecommand(HX8357_TEARLINE); // tear line
writedata(0x00);
writedata(0x02);
writecommand(HX8357_SLPOUT); //Exit Sleep
delay(150);
writecommand(HX8357_DISPON); // display on
delay(50);
#elif defined(WAVESHARE32B)
// Waveshare32b
writecommand(0xCB);
writedata(0x39);
writedata(0x2C);
writedata(0x00);
writedata(0x34);
writedata(0x02);
writecommand(0xCF);
writedata(0x00);
writedata(0xC1);
writedata(0x30);
writecommand(0xE8);
writedata(0x85);
writedata(0x00);
writedata(0x78);
writecommand(0xEA);
writedata(0x00);
writedata(0x00);
writecommand(0xED);
writedata(0x64);
writedata(0x03);
writedata(0x12);
writedata(0x81);
writecommand(0xF7);
writedata(0x20);
writecommand(0xC0);
writedata(0x23);
writecommand(0xC1);
writedata(0x10);
writecommand(0xC5);
writedata(0x3E);
writedata(0x28);
writecommand(0xC7);
writedata(0x86);
writecommand(0x36);
writedata(0x28);
writecommand(0x3A);
writedata(0x55);
writecommand(0xB1);
writedata(0x00);
writedata(0x18);
writecommand(0xB6);
writedata(0x08);
writedata(0x82);
writedata(0x27);
writecommand(0xF2);
writedata(0x00);
writecommand(0x26);
writedata(0x01);
writecommand(0xE0);
writedata(0x0F);
writedata(0x31);
writedata(0x2B);
writedata(0x0C);
writedata(0x0E);
writedata(0x08);
writedata(0x4E);
writedata(0xF1);
writedata(0x37);
writedata(0x07);
writedata(0x10);
writedata(0x03);
writedata(0x0E);
writedata(0x09);
writedata(0x00);
writecommand(0xE1);
writedata(0x00);
writedata(0x0E);
writedata(0x14);
writedata(0x03);
writedata(0x11);
writedata(0x07);
writedata(0x31);
writedata(0xC1);
writedata(0x48);
writedata(0x08);
writedata(0x0F);
writedata(0x0C);
writedata(0x31);
writedata(0x36);
writedata(0x0F);
writecommand(0x11);
delay(120);
writecommand(0x29);
//writecommand(0x2C);
delay(25);
#elif defined (TINYLCD2)
// Configure TINYLCD display
writecommand(0x11);
delay(20);
writecommand(0xB0);
writedata(0x80);
writecommand(0xC0);
writedata(0x0A);
writedata(0x0A);
writecommand(0xC1);
writedata(0x45);
writedata(0x07);
writecommand(0xC2);
writedata(0x33);
writecommand(0xC5);
writedata(0x00);
writedata(0x42);
writedata(0x80);
writecommand(0xB1);
writedata(0xD0);
writedata(0x11);
writecommand(0xB4);
writedata(0x02);
writecommand(0xB6);
writedata(0x00);
writedata(0x22);
writedata(0x3B);
writecommand(0xB7);
writedata(0x07);
writecommand(0x36);
writedata(0x58);
writecommand(0xF0);
writedata(0x36);
writedata(0xA5);
writedata(0xD3);
writecommand(0xE5);
writedata(0x80);
writecommand(0xE5);
writedata(0x01);
writecommand(0xB3);
writedata(0x00);
writecommand(0xE5);
writedata(0x00);
writecommand(0xF0);
writedata(0x36);
writedata(0xA5);
writedata(0x53);
writecommand(0xE0);
writedata(0x00);
writedata(0x35);
writedata(0x33);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writedata(0x35);
writedata(0x33);
writedata(0x00);
writedata(0x00);
writedata(0x00);
writecommand(0x3A);
writedata(0x55);
delay(120);
writecommand(0x29);
delay(25);
// End of TINYLCD display configuration
#elif defined (HX8357C)
// HX8357-C display initialisation
writecommand(0xB9); // Enable extension command
writedata(0xFF);
writedata(0x83);
writedata(0x57);
delay(50);
writecommand(0xB6); //Set VCOM voltage
writedata(0x2C); //0x52 for HSD 3.0"
writecommand(0x11); // Sleep off
delay(200);
writecommand(0x35); // Tearing effect on
writedata(0x00); // Added parameter
writecommand(0x3A); // Interface pixel format
writedata(0x55); // 16 bits per pixel
//writecommand(0xCC); // Set panel characteristic
//writedata(0x09); // S960>S1, G1>G480, R-G-B, normally black
//writecommand(0xB3); // RGB interface
//writedata(0x43);
//writedata(0x00);
//writedata(0x06);
//writedata(0x06);
writecommand(0xB1); // Power control
writedata(0x00);
writedata(0x15);
writedata(0x0D);
writedata(0x0D);
writedata(0x83);
writedata(0x48);
writecommand(0xC0); // Does this do anything?
writedata(0x24);
writedata(0x24);
writedata(0x01);
writedata(0x3C);
writedata(0xC8);
writedata(0x08);
writecommand(0xB4); // Display cycle
writedata(0x02);
writedata(0x40);
writedata(0x00);
writedata(0x2A);
writedata(0x2A);
writedata(0x0D);
writedata(0x4F);
writecommand(0xE0); // Gamma curve
writedata(0x00);
writedata(0x15);
writedata(0x1D);
writedata(0x2A);
writedata(0x31);
writedata(0x42);
writedata(0x4C);
writedata(0x53);
writedata(0x45);
writedata(0x40);
writedata(0x3B);
writedata(0x32);
writedata(0x2E);
writedata(0x28);
writedata(0x24);
writedata(0x03);
writedata(0x00);
writedata(0x15);
writedata(0x1D);
writedata(0x2A);
writedata(0x31);
writedata(0x42);
writedata(0x4C);
writedata(0x53);
writedata(0x45);
writedata(0x40);
writedata(0x3B);
writedata(0x32);
writedata(0x2E);
writedata(0x28);
writedata(0x24);
writedata(0x03);
writedata(0x00);
writedata(0x01);
writecommand(0x36); // MADCTL Memory access control
writedata(0x48);
delay(20);
writecommand(0x21); //Display inversion on
delay(20);
writecommand(0x29); // Display on
delay(120);
#elif defined (ILI9481) // Must be an ILI9481
// Configure ILI9481 display
writecommand(0x11);
delay(20);
writecommand(0xD0);
writedata(0x07);
writedata(0x42);
writedata(0x18);
writecommand(0xD1);
writedata(0x00);
writedata(0x07);
writedata(0x10);
writecommand(0xD2);
writedata(0x01);
writedata(0x02);
writecommand(0xC0);
writedata(0x10);
writedata(0x3B);
writedata(0x00);
writedata(0x02);
writedata(0x11);
writecommand(0xC5);
writedata(0x03);
writecommand(0xC8);
writedata(0x00);
writedata(0x32);
writedata(0x36);
writedata(0x45);
writedata(0x06);
writedata(0x16);
writedata(0x37);
writedata(0x75);
writedata(0x77);
writedata(0x54);
writedata(0x0C);
writedata(0x00);
writecommand(0x36);
writedata(0x0A);
writecommand(0x3A);
writedata(0x55);
writecommand(0x2A);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0x3F);
writecommand(0x2B);
writedata(0x00);
writedata(0x00);
writedata(0x01);
writedata(0xDF);
delay(120);
writecommand(0x29);
delay(25);
// End of ILI9481 display configuration
#endif
}

View File

@@ -14,6 +14,7 @@
size.
Created by Bodmer 2/12/16
Bodmer: Added RPi 16 bit display support
****************************************************/
#include "TFT_eSPI.h"
@@ -25,6 +26,14 @@
#include "wiring_private.h"
#include <SPI.h>
// If it is a 16bit serial display we must transfer 16 bits every time
#ifdef RPI_ILI9486_DRIVER
#define SEND_16_BITS
#define CMD_BITS 16-1
#else
#define CMD_BITS 8-1
#endif
// If the SPI library has transaction support, these functions
// establish settings and protect from interference from other
// libraries. Otherwise, they simply do nothing.
@@ -32,7 +41,11 @@
inline void TFT_eSPI::spi_begin(void){
#ifdef SPI_HAS_TRANSACTION
#ifdef SUPPORT_TRANSACTIONS
SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0));
#ifdef SET_SPI_TO_LSB_FIRST
SPI.beginTransaction(SPISettings(SPI_FREQUENCY, LSBFIRST, SPI_MODE0));
#else
SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0));
#endif
#endif
#endif
}
@@ -140,7 +153,11 @@ void TFT_eSPI::init(void)
SPI.begin(); // This will set MISO to input
#ifndef SUPPORT_TRANSACTIONS
SPI.setBitOrder(MSBFIRST);
#ifdef SET_SPI_TO_LSB_FIRST
SPI.setBitOrder(LSBFIRST);
#else
SPI.setBitOrder(MSBFIRST);
#endif
SPI.setDataMode(SPI_MODE0);
SPI.setFrequency(SPI_FREQUENCY);
#endif
@@ -188,6 +205,9 @@ void TFT_eSPI::init(void)
#elif defined (S6D02A1_DRIVER)
#include "TFT_Drivers\S6D02A1_Init.h"
#elif defined (RPI_ILI9486_DRIVER)
#include "TFT_Drivers\RPI_ILI9486_Init.h"
#endif
spi_end();
@@ -217,7 +237,10 @@ void TFT_eSPI::setRotation(uint8_t m)
#elif defined (S6D02A1_DRIVER)
#include "TFT_Drivers\S6D02A1_Rotation.h"
#endif
#elif defined (RPI_ILI9486_DRIVER)
#include "TFT_Drivers\RPI_ILI9486_Rotation.h"
#endif
spi_end();
@@ -280,6 +303,9 @@ void TFT_eSPI::writecommand(uint8_t c)
{
DC_C;
CS_L;
#ifdef SEND_16_BITS
SPI.transfer(0);
#endif
SPI.transfer(c);
CS_H;
DC_D;
@@ -293,6 +319,9 @@ void TFT_eSPI::writecommand(uint8_t c)
void TFT_eSPI::writedata(uint8_t c)
{
CS_L;
#ifdef SEND_16_BITS
SPI.transfer(0);
#endif
SPI.transfer(c);
CS_H;
}
@@ -1201,22 +1230,25 @@ spi_begin();
setAddrWindow(x, y, x+5, y+8);
for (int8_t i = 0; i < 5; i++ ) column[i] = pgm_read_byte(font + (c * 5) + i);
column[5] = 0;
uint32_t spimask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO));
SPI1U1 = spimask | (15 << SPILMOSI) | (15 << SPILMISO);
for (int8_t j = 0; j < 8; j++) {
for (int8_t k = 0; k < 5; k++ ) {
if (column[k] & mask) {
//SPI.transfer(color >> 8);
SPI.write16(color);
SPI1W0 = (color >> 8) | (color << 8);
}
else {
//SPI.transfer(bg >> 8);
SPI.write16(bg);
SPI1W0 = (bg >> 8) | (bg << 8);
}
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
}
mask <<= 1;
//SPI.transfer(bg >> 8);
SPI.write16(bg);
SPI1W0 = (bg >> 8) | (bg << 8);
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
}
CS_H;
}
@@ -1430,7 +1462,7 @@ void TFT_eSPI::setWindow(int16_t x0, int16_t y0, int16_t x1, int16_t y1)
***************************************************************************************/
// Chip select stays low, use setWindow() from sketches
#ifdef ESP8266
#if defined (ESP8266) && !defined (RPI_ILI9486_DRIVER)
inline void TFT_eSPI::setAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye)
{
spi_begin();
@@ -1452,7 +1484,7 @@ inline void TFT_eSPI::setAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t
uint32_t mask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO));
mask = SPI1U1 & mask;
SPI1U1 = mask | (7 << SPILMOSI) | (7 << SPILMISO);
SPI1U1 = mask | (CMD_BITS << SPILMOSI) | (CMD_BITS << SPILMISO);
SPI1W0 = TFT_CASET;
SPI1CMD |= SPIBUSY;
@@ -1484,7 +1516,7 @@ inline void TFT_eSPI::setAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t
// Row addr set
DC_C;
SPI1U1 = mask | (7 << SPILMOSI) | (7 << SPILMISO);
SPI1U1 = mask | (CMD_BITS << SPILMOSI) | (CMD_BITS << SPILMISO);
SPI1W0 = TFT_PASET;
SPI1CMD |= SPIBUSY;
@@ -1501,7 +1533,7 @@ inline void TFT_eSPI::setAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t
// write to RAM
DC_C;
SPI1U1 = mask | (7 << SPILMOSI) | (7 << SPILMISO);
SPI1U1 = mask | (CMD_BITS << SPILMOSI) | (CMD_BITS << SPILMISO);
SPI1W0 = TFT_RAMWR;
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
@@ -1511,6 +1543,114 @@ inline void TFT_eSPI::setAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t
spi_end();
}
#elif defined (ESP8266) && defined (RPI_ILI9486_DRIVER) // This is for the RPi display that needs 16 bits
inline void TFT_eSPI::setAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye)
{
spi_begin();
addr_col = 0xFFFF;
addr_row = 0xFFFF;
// Column addr set
DC_C;
CS_L;
uint32_t mask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO));
mask = SPI1U1 & mask;
SPI1U1 = mask | (CMD_BITS << SPILMOSI) | (CMD_BITS << SPILMISO);
SPI1W0 = TFT_CASET<<8;
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
DC_D;
uint8_t xBin[] = { 0, (uint8_t) (xs>>8), 0, (uint8_t) (xs>>0), 0, (uint8_t) (xe>>8), 0, (uint8_t) (xe>>0), };
SPI.writePattern(&xBin[0], 8, 1);
// Row addr set
DC_C;
SPI1U1 = mask | (CMD_BITS << SPILMOSI) | (CMD_BITS << SPILMISO);
SPI1W0 = TFT_PASET<<8;
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
DC_D;
uint8_t yBin[] = { 0, (uint8_t) (ys>>8), 0, (uint8_t) (ys>>0), 0, (uint8_t) (ye>>8), 0, (uint8_t) (ye>>0), };
SPI.writePattern(&yBin[0], 8, 1);
// write to RAM
DC_C;
SPI1U1 = mask | (CMD_BITS << SPILMOSI) | (CMD_BITS << SPILMISO);
SPI1W0 = TFT_RAMWR<<8;
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
DC_D;
spi_end();
}
#else // This is for the ESP32 where we cannot use low level register access (yet)
#if defined (RPI_ILI9486_DRIVER) // This is for the RPi display that needs 16 bits
inline void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
{
spi_begin();
addr_col = 0xFFFF;
addr_row = 0xFFFF;
#if defined (ST7735_DRIVER) && (defined (ST7735_GREENTAB) || defined (ST7735_GREENTAB2) || defined (ST7735_GREENTAB3))
x0+=colstart;
x1+=colstart;
y0+=rowstart;
y1+=rowstart;
#endif
// Column addr set
DC_C;
CS_L;
SPI.write16(TFT_CASET);
DC_D;
SPI.write16(x0 >> 8); // Not tested on ESP32 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
SPI.write16(x0);
SPI.write16(x1 >> 8);
SPI.write16(x1);
// Row addr set
DC_C;
SPI.write16(TFT_PASET);
DC_D;
SPI.write16(y0 >> 8); // Not tested on ESP32 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
SPI.write16(y0);
SPI.write16(y1 >> 8);
SPI.write16(y1);
// write to RAM
DC_C;
SPI.write16(TFT_RAMWR);
DC_D;
spi_end();
}
#else
inline void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
@@ -1559,8 +1699,8 @@ inline void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t
spi_end();
}
#endif
#endif // end RPI_ILI9486_DRIVER check
#endif // end ESP32 check
/***************************************************************************************
@@ -1590,7 +1730,7 @@ void TFT_eSPI::readAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye)
uint32_t mask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO));
mask = SPI1U1 & mask;
SPI1U1 = mask | (7 << SPILMOSI) | (7 << SPILMISO);
SPI1U1 = mask | (CMD_BITS << SPILMOSI) | (CMD_BITS << SPILMISO);
SPI1W0 = TFT_CASET;
SPI1CMD |= SPIBUSY;
@@ -1607,7 +1747,7 @@ void TFT_eSPI::readAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye)
// Row addr set
DC_C;
SPI1U1 = mask | (7 << SPILMOSI) | (7 << SPILMISO);
SPI1U1 = mask | (CMD_BITS << SPILMOSI) | (CMD_BITS << SPILMISO);
SPI1W0 = TFT_PASET;
SPI1CMD |= SPIBUSY;
@@ -1624,7 +1764,7 @@ void TFT_eSPI::readAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye)
// read from RAM
DC_C;
SPI1U1 = mask | (7 << SPILMOSI) | (7 << SPILMISO);
SPI1U1 = mask | (CMD_BITS << SPILMOSI) | (CMD_BITS << SPILMISO);
SPI1W0 = TFT_RAMRD;
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
@@ -1632,6 +1772,7 @@ void TFT_eSPI::readAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye)
DC_D;
//spi_end();
}
#else
void TFT_eSPI::readAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
@@ -1684,7 +1825,7 @@ void TFT_eSPI::readAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
** Function name: drawPixel
** Description: push a single pixel at an arbitrary position
***************************************************************************************/
#ifdef ESP8266
#if defined (ESP8266)
void TFT_eSPI::drawPixel(uint32_t x, uint32_t y, uint32_t color)
{
// Faster range checking, possible because x and y are unsigned
@@ -1706,19 +1847,24 @@ void TFT_eSPI::drawPixel(uint32_t x, uint32_t y, uint32_t color)
DC_C;
SPI1U1 = mask | (7 << SPILMOSI) | (7 << SPILMISO);
SPI1W0 = TFT_CASET;
SPI1U1 = mask | (CMD_BITS << SPILMOSI) | (CMD_BITS << SPILMISO);
SPI1W0 = TFT_CASET<<(CMD_BITS + 1 - 8);
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
DC_D;
#if defined (RPI_ILI9486_DRIVER) // This is for the RPi display that needs 16 bits per byte
uint8_t cBin[] = { 0, (uint8_t) (x>>8), 0, (uint8_t) (x>>0)};
SPI.writePattern(&cBin[0], 4, 2);
#else
SPI1U1 = mask | (31 << SPILMOSI) | (31 << SPILMISO);
// Load the two coords as a 32 bit value and shift in one go
uint32_t xswap = (x >> 8) | (uint16_t)(x << 8);
SPI1W0 = xswap | (xswap << 16);
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
#endif
addr_col = x;
}
@@ -1728,28 +1874,34 @@ void TFT_eSPI::drawPixel(uint32_t x, uint32_t y, uint32_t color)
DC_C;
SPI1U1 = mask | (7 << SPILMOSI) | (7 << SPILMISO);
SPI1U1 = mask | (CMD_BITS << SPILMOSI) | (CMD_BITS << SPILMISO);
SPI1W0 = TFT_PASET;
SPI1W0 = TFT_PASET<<(CMD_BITS + 1 - 8);
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
DC_D;
#if defined (RPI_ILI9486_DRIVER) // This is for the RPi display that needs 16 bits per byte
uint8_t cBin[] = { 0, (uint8_t) (y>>8), 0, (uint8_t) (y>>0)};
SPI.writePattern(&cBin[0], 4, 2);
#else
SPI1U1 = mask | (31 << SPILMOSI) | (31 << SPILMISO);
// Load the two coords as a 32 bit value and shift in one go
uint32_t yswap = (y >> 8) | (uint16_t)(y << 8);
SPI1W0 = yswap | (yswap << 16);
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
#endif
addr_row = y;
}
DC_C;
SPI1U1 = mask | (7 << SPILMOSI) | (7 << SPILMISO);
SPI1U1 = mask | (CMD_BITS << SPILMOSI) | (CMD_BITS << SPILMISO);
SPI1W0 = TFT_RAMWR;
SPI1W0 = TFT_RAMWR<<(CMD_BITS + 1 - 8);
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
@@ -1768,7 +1920,69 @@ void TFT_eSPI::drawPixel(uint32_t x, uint32_t y, uint32_t color)
#else
void TFT_eSPI::drawPixel(uint32_t x, uint32_t y, uint32_t color)
#if defined (RPI_ILI9486_DRIVER) // This is for the RPi display that needs 16 bits
void TFT_eSPI::drawPixel(uint32_t x, uint32_t y, uint32_t color)
{
// Faster range checking, possible because x and y are unsigned
if ((x >= _width) || (y >= _height)) return;
spi_begin();
CS_L;
// No need to send x if it has not changed (speeds things up)
if (addr_col != x) {
DC_C;
SPI.write16(TFT_CASET<<8);
DC_D;
SPI.write16(x >> 8); // Not tested on ESP32 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
SPI.write16(x);
SPI.write16(x >> 8);
SPI.write16(x);
addr_col = x;
}
// No need to send y if it has not changed (speeds things up)
if (addr_row != y) {
DC_C;
SPI.write16(TFT_PASET<<8);
DC_D;
SPI.write16(y >> 8); // Not tested on ESP32 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
SPI.write16(y);
SPI.write16(y >> 8);
SPI.write16(y);
addr_row = y;
}
DC_C;
SPI.write16(TFT_RAMWR<<8);
DC_D;
SPI.write16((color >> 8) | (color << 8));
CS_H;
spi_end();
}
#else
void TFT_eSPI::drawPixel(uint32_t x, uint32_t y, uint32_t color)
{
// Faster range checking, possible because x and y are unsigned
if ((x >= _width) || (y >= _height)) return;
@@ -1827,7 +2041,7 @@ void TFT_eSPI::drawPixel(uint32_t x, uint32_t y, uint32_t color)
spi_end();
}
#endif
#endif

View File

@@ -18,6 +18,7 @@
//#define ST7735_DRIVER
//#define ILI9163_DRIVER
//#define S6D02A1_DRIVER
//#define RPI_ILI9486_DRIVER // 20MHz maximum SPI
// For ST7735 ONLY, define the type of display, originally this was based on the
// colour of the tab on the screen protector film but this is not always true, so try
@@ -144,8 +145,8 @@
// #define SPI_FREQUENCY 1000000
// #define SPI_FREQUENCY 5000000
// #define SPI_FREQUENCY 10000000
// #define SPI_FREQUENCY 20000000
#define SPI_FREQUENCY 27000000 // Actually sets it to 26.67MHz = 80/3
#define SPI_FREQUENCY 20000000
// #define SPI_FREQUENCY 27000000 // Actually sets it to 26.67MHz = 80/3
// #define SPI_FREQUENCY 40000000 // Maximum to use SPIFFS
// #define SPI_FREQUENCY 80000000

View File

@@ -6,7 +6,7 @@
// The advantage of this hardware configuration method is that the examples provided
// with the library should work with different setups immediately without any other
// changes being needed. It also improves the poratability of users sketches to other
// changes being needed. It also improves the portability of users sketches to other
// hardware configurations and compatible libraries.
//
// Create a shortcut to this file on your desktop to permit quick access for editting.
@@ -45,4 +45,6 @@
#include <TFT_Drivers/ILI9163_Defines.h>
#elif defined (S6D02A1_DRIVER)
#include <TFT_Drivers/S6D02A1_Defines.h>
#elif defined (RPI_ILI9486_DRIVER)
#include <TFT_Drivers/RPI_ILI9486_Defines.h>
#endif

View File

@@ -0,0 +1,150 @@
// USER DEFINED SETTINGS
//
// The User_Setup header that will be called up is defined in User_Setup_Select.h
//
// Set driver type, fonts to be loaded, pins used and SPI control method etc
//
// If this file is editted correctly then all the library example sketches should
// run without the need to make any more changes for a particular hardware setup!
// ##################################################################################
//
// Section 0. Call up the right driver file and any options for it
//
// ##################################################################################
// Only define one driver, the other ones must be commented out
#define RPI_ILI9486_DRIVER
//#define ST7735_DRIVER
// For ST7735 ONLY, define the type of display, originally this was based on the
// colour of the tab on the screen protector film but this is not always true, so try
// out the different options below if the screen does not display graphics correctly,
// e.g. colours wrong, mirror images, or tray pixels at the edges.
// Comment out ALL BUT ONE of these options for a ST7735 display driver, save this
// this User_Setup file, then rebuild and upload the sketch to the board again:
//#define ST7735_INITB
//#define ST7735_GREENTAB
//#define ST7735_GREENTAB2
//#define ST7735_REDTAB
//#define ST7735_BLACKTAB
// ##################################################################################
//
// Section 1. Define the pins that are used to interface with the display here
//
// ##################################################################################
// We must use hardware SPI, a minimum of 3 GPIO pins is needed.
// Typical setup for NodeMCU ESP-12 is :
//
// Display SDO/MISO to NodeMCU pin D6 (or leave disconnected if not reading TFT)
// Display LED to NodeMCU pin VIN (or 5V, see below)
// Display SCK to NodeMCU pin D5
// Display SDI/MOSI to NodeMCU pin D7
// Display DC (or AO)to NodeMCU pin D3
// Display RESET to NodeMCU pin D4 (or RST, see below)
// Display CS to NodeMCU pin D8 (or GND, see below)
// Display GND to NodeMCU pin GND (0V)
// Display VCC to NodeMCU 5V or 3.3V
//
// The TFT RESET pin can be connected to the NodeMCU RST pin or 3.3V to free up a control pin
//
// With some displays such as the ILI9341 the TFT CS pin can be connected to GND if no more
// SPI deivces (e.g. an SD Card) are connected, in this case comment out the #define TFT_CS
// line below so it is NOT defined. Other displays such at the ST7735 require the TFT CS pin
// to be toggled during setup, so in these cases the TFT_CS line must be defined and connected.
//
// The NodeMCU D0 pin can be used for RST
//
// See Section 2. below if DC or CS is connected to D0
//
// Note: only some versions of the NodeMCU provide the USB 5V on the VIN pin
// If 5V is not available at a pin you can use 3.3V but backlight brightness
// will be lower.
// ###### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR SETUP ######
// ModeMCU
#define TFT_CS D8 // Chip select control pin D8
#define TFT_DC D3 // Data Command control pin
#define TFT_RST D4 // Reset pin (could connect to NodeMCU RST, see next line)
//#define TFT_RST -1 // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V
// ESP32 Dev board (planned, not supported yet)
//#define TFT_CS 5 // Chip select control pin
//#define TFT_DC 2 // Data Command control pin
//#define TFT_RST 4 // Reset pin (could connect to Arduino RESET pin)
//#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST
// ##################################################################################
//
// Section 2. Define the way the DC and/or CS lines are driven
//
// ##################################################################################
// Normally the library uses direct register access for the DC and CS lines for speed
// If D0 (GPIO16) is used for CS or DC then a different slower method must be used
// Uncomment one line if D0 is used for DC or CS
// DC on D0 = 6% performance penalty at 40MHz SPI running graphics test
// CS on D0 = 2% performance penalty at 40MHz SPI running graphics test
// #define D0_USED_FOR_DC
// #define D0_USED_FOR_CS
// ##################################################################################
//
// Section 3. Define the fonts that are to be used here
//
// ##################################################################################
// Comment out the #defines below with // to stop that font being loaded
// The ESP8366 had plenty of memory so commenting out fonts is not normally necessary
// If all fonts are loaded the extra FLASH space required is about 17Kbytes...
// To save FLASH space only enable the fonts you need!
#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_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
// ##################################################################################
//
// Section 4. Define the character to be used to detemine the text bounding box for datum changes
//
// ##################################################################################
#define FF_HEIGHT '/' // '/' character used to set free font height above the baseline
#define FF_BOTTOM 'y' // 'y' character used to set free font height below baseline
// ##################################################################################
//
// Section 5. Other options
//
// ##################################################################################
// Define the SPI clock frequency
// With an ILI9341 display 40MHz works OK, 80MHz sometimes fails
// With a ST7735 display more than 27MHz may not work (spurious pixels and lines)
// #define SPI_FREQUENCY 1000000
// #define SPI_FREQUENCY 5000000
// #define SPI_FREQUENCY 10000000
#define SPI_FREQUENCY 20000000
// #define SPI_FREQUENCY 27000000 // Actually sets it to 26.67MHz = 80/3
// #define SPI_FREQUENCY 40000000 // Maximum to use SPIFFS
// #define SPI_FREQUENCY 80000000
// Comment out the following #define if "SPI Transactions" do not need to be
// supported. Tranaction support is required if other SPI devices are connected.
// When commented out the code size will be smaller and sketches will
// run slightly faster, so leave it commented out unless you need it!
// Transaction support is needed to work with SD library but not needed with TFT_SdFat
// #define SUPPORT_TRANSACTIONS

View File

@@ -0,0 +1,165 @@
//The Game of Life, also known simply as Life, is a cellular automaton
//devised by the British mathematician John Horton Conway in 1970.
// https://en.wikipedia.org/wiki/Conway's_Game_of_Life
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
//#define GRIDX 80
//#define GRIDY 60
//#define CELLXY 4
#define GRIDX 160
#define GRIDY 106
#define CELLXY 3
#define GEN_DELAY 0
//Current grid
uint8_t grid[GRIDX][GRIDY];
//The new grid for the next generation
uint8_t newgrid[GRIDX][GRIDY];
//Number of generations
#define NUMGEN 600
uint16_t genCount = 0;
void setup() {
//Set up the display
tft.init();
tft.setRotation(3);
tft.fillScreen(TFT_BLACK);
tft.setTextSize(1);
tft.setTextColor(TFT_WHITE);
tft.setCursor(0, 0);
}
void loop() {
//Display a simple splash screen
tft.fillScreen(TFT_BLACK);
tft.setTextSize(2);
tft.setTextColor(TFT_WHITE);
tft.setCursor(40, 5);
tft.println(F("Arduino"));
tft.setCursor(35, 25);
tft.println(F("Cellular"));
tft.setCursor(35, 45);
tft.println(F("Automata"));
delay(1000);
tft.fillScreen(TFT_BLACK);
initGrid();
genCount = NUMGEN;
drawGrid();
//Compute generations
for (int gen = 0; gen < genCount; gen++)
{
computeCA();
drawGrid();
delay(GEN_DELAY);
for (int16_t x = 1; x < GRIDX-1; x++) {
for (int16_t y = 1; y < GRIDY-1; y++) {
grid[x][y] = newgrid[x][y];
}
}
}
}
//Draws the grid on the display
void drawGrid(void) {
uint16_t color = TFT_WHITE;
for (int16_t x = 1; x < GRIDX - 1; x++) {
for (int16_t y = 1; y < GRIDY - 1; y++) {
if ((grid[x][y]) != (newgrid[x][y])) {
if (newgrid[x][y] == 1) color = 0xFFFF; //random(0xFFFF);
else color = 0;
tft.fillRect(CELLXY * x, CELLXY * y, CELLXY, CELLXY, color);
}
}
}
}
//Initialise Grid
void initGrid(void) {
for (int16_t x = 0; x < GRIDX; x++) {
for (int16_t y = 0; y < GRIDY; y++) {
newgrid[x][y] = 0;
if (x == 0 || x == GRIDX - 1 || y == 0 || y == GRIDY - 1) {
grid[x][y] = 0;
}
else {
if (random(3) == 1)
grid[x][y] = 1;
else
grid[x][y] = 0;
}
}
}
}
//Compute the CA. Basically everything related to CA starts here
void computeCA() {
for (int16_t x = 1; x < GRIDX; x++) {
for (int16_t y = 1; y < GRIDY; y++) {
int neighbors = getNumberOfNeighbors(x, y);
if (grid[x][y] == 1 && (neighbors == 2 || neighbors == 3 ))
{
newgrid[x][y] = 1;
}
else if (grid[x][y] == 1) newgrid[x][y] = 0;
if (grid[x][y] == 0 && (neighbors == 3))
{
newgrid[x][y] = 1;
}
else if (grid[x][y] == 0) newgrid[x][y] = 0;
}
}
}
// Check the Moore neighborhood
int getNumberOfNeighbors(int x, int y) {
return grid[x - 1][y] + grid[x - 1][y - 1] + grid[x][y - 1] + grid[x + 1][y - 1] + grid[x + 1][y] + grid[x + 1][y + 1] + grid[x][y + 1] + grid[x - 1][y + 1];
}
/*
The MIT License (MIT)
Copyright (c) 2016 RuntimeProjects.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

View File

@@ -0,0 +1,348 @@
/*
Example sketch for TFT_eSPI library.
No fonts are needed.
Draws a 3d rotating cube on the TFT screen.
Original code was found at http://forum.freetronics.com/viewtopic.php?f=37&t=5495
*/
#define BLACK 0x0000
#define WHITE 0xFFFF
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
int16_t h;
int16_t w;
int inc = -2;
float xx, xy, xz;
float yx, yy, yz;
float zx, zy, zz;
float fact;
int Xan, Yan;
int Xoff;
int Yoff;
int Zoff;
struct Point3d
{
int x;
int y;
int z;
};
struct Point2d
{
int x;
int y;
};
int LinestoRender; // lines to render.
int OldLinestoRender; // lines to render just in case it changes. this makes sure the old lines all get erased.
struct Line3d
{
Point3d p0;
Point3d p1;
};
struct Line2d
{
Point2d p0;
Point2d p1;
};
Line3d Lines[20];
Line2d Render[20];
Line2d ORender[20];
/***********************************************************************************************************************************/
void setup() {
tft.init();
h = tft.height();
w = tft.width();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
cube();
fact = 180 / 3.14159259; // conversion from degrees to radians.
Xoff = 240; // Position the center of the 3d conversion space into the center of the TFT screen.
Yoff = 160;
Zoff = 550; // Z offset in 3D space (smaller = closer and bigger rendering)
}
/***********************************************************************************************************************************/
void loop() {
// Rotate around x and y axes in 1 degree increments
Xan++;
Yan++;
Yan = Yan % 360;
Xan = Xan % 360; // prevents overflow.
SetVars(); //sets up the global vars to do the 3D conversion.
// Zoom in and out on Z axis within limits
// the cube intersects with the screen for values < 160
Zoff += inc;
if (Zoff > 500) inc = -1; // Switch to zoom in
else if (Zoff < 160) inc = 1; // Switch to zoom out
for (int i = 0; i < LinestoRender ; i++)
{
ORender[i] = Render[i]; // stores the old line segment so we can delete it later.
ProcessLine(&Render[i], Lines[i]); // converts the 3d line segments to 2d.
}
RenderImage(); // go draw it!
delay(14); // Delay to reduce loop rate (reduces flicker caused by aliasing with TFT screen refresh rate)
}
/***********************************************************************************************************************************/
void RenderImage( void)
{
// renders all the lines after erasing the old ones.
// in here is the only code actually interfacing with the OLED. so if you use a different lib, this is where to change it.
for (int i = 0; i < OldLinestoRender; i++ )
{
tft.drawLine(ORender[i].p0.x, ORender[i].p0.y, ORender[i].p1.x, ORender[i].p1.y, BLACK); // erase the old lines.
}
for (int i = 0; i < LinestoRender; i++ )
{
uint16_t color = TFT_BLUE;
if (i < 4) color = TFT_RED;
if (i > 7) color = TFT_GREEN;
tft.drawLine(Render[i].p0.x, Render[i].p0.y, Render[i].p1.x, Render[i].p1.y, color);
}
OldLinestoRender = LinestoRender;
}
/***********************************************************************************************************************************/
// Sets the global vars for the 3d transform. Any points sent through "process" will be transformed using these figures.
// only needs to be called if Xan or Yan are changed.
void SetVars(void)
{
float Xan2, Yan2, Zan2;
float s1, s2, s3, c1, c2, c3;
Xan2 = Xan / fact; // convert degrees to radians.
Yan2 = Yan / fact;
// Zan is assumed to be zero
s1 = sin(Yan2);
s2 = sin(Xan2);
c1 = cos(Yan2);
c2 = cos(Xan2);
xx = c1;
xy = 0;
xz = -s1;
yx = (s1 * s2);
yy = c2;
yz = (c1 * s2);
zx = (s1 * c2);
zy = -s2;
zz = (c1 * c2);
}
/***********************************************************************************************************************************/
// processes x1,y1,z1 and returns rx1,ry1 transformed by the variables set in SetVars()
// fairly heavy on floating point here.
// uses a bunch of global vars. Could be rewritten with a struct but not worth the effort.
void ProcessLine(struct Line2d *ret, struct Line3d vec)
{
float zvt1;
int xv1, yv1, zv1;
float zvt2;
int xv2, yv2, zv2;
int rx1, ry1;
int rx2, ry2;
int x1;
int y1;
int z1;
int x2;
int y2;
int z2;
int Ok;
x1 = vec.p0.x;
y1 = vec.p0.y;
z1 = vec.p0.z;
x2 = vec.p1.x;
y2 = vec.p1.y;
z2 = vec.p1.z;
Ok = 0; // defaults to not OK
xv1 = (x1 * xx) + (y1 * xy) + (z1 * xz);
yv1 = (x1 * yx) + (y1 * yy) + (z1 * yz);
zv1 = (x1 * zx) + (y1 * zy) + (z1 * zz);
zvt1 = zv1 - Zoff;
if ( zvt1 < -5) {
rx1 = 256 * (xv1 / zvt1) + Xoff;
ry1 = 256 * (yv1 / zvt1) + Yoff;
Ok = 1; // ok we are alright for point 1.
}
xv2 = (x2 * xx) + (y2 * xy) + (z2 * xz);
yv2 = (x2 * yx) + (y2 * yy) + (z2 * yz);
zv2 = (x2 * zx) + (y2 * zy) + (z2 * zz);
zvt2 = zv2 - Zoff;
if ( zvt2 < -5) {
rx2 = 256 * (xv2 / zvt2) + Xoff;
ry2 = 256 * (yv2 / zvt2) + Yoff;
} else
{
Ok = 0;
}
if (Ok == 1) {
ret->p0.x = rx1;
ret->p0.y = ry1;
ret->p1.x = rx2;
ret->p1.y = ry2;
}
// The ifs here are checks for out of bounds. needs a bit more code here to "safe" lines that will be way out of whack, so they dont get drawn and cause screen garbage.
}
/***********************************************************************************************************************************/
// line segments to draw a cube. basically p0 to p1. p1 to p2. p2 to p3 so on.
void cube(void)
{
// Front Face.
Lines[0].p0.x = -50;
Lines[0].p0.y = -50;
Lines[0].p0.z = 50;
Lines[0].p1.x = 50;
Lines[0].p1.y = -50;
Lines[0].p1.z = 50;
Lines[1].p0.x = 50;
Lines[1].p0.y = -50;
Lines[1].p0.z = 50;
Lines[1].p1.x = 50;
Lines[1].p1.y = 50;
Lines[1].p1.z = 50;
Lines[2].p0.x = 50;
Lines[2].p0.y = 50;
Lines[2].p0.z = 50;
Lines[2].p1.x = -50;
Lines[2].p1.y = 50;
Lines[2].p1.z = 50;
Lines[3].p0.x = -50;
Lines[3].p0.y = 50;
Lines[3].p0.z = 50;
Lines[3].p1.x = -50;
Lines[3].p1.y = -50;
Lines[3].p1.z = 50;
//back face.
Lines[4].p0.x = -50;
Lines[4].p0.y = -50;
Lines[4].p0.z = -50;
Lines[4].p1.x = 50;
Lines[4].p1.y = -50;
Lines[4].p1.z = -50;
Lines[5].p0.x = 50;
Lines[5].p0.y = -50;
Lines[5].p0.z = -50;
Lines[5].p1.x = 50;
Lines[5].p1.y = 50;
Lines[5].p1.z = -50;
Lines[6].p0.x = 50;
Lines[6].p0.y = 50;
Lines[6].p0.z = -50;
Lines[6].p1.x = -50;
Lines[6].p1.y = 50;
Lines[6].p1.z = -50;
Lines[7].p0.x = -50;
Lines[7].p0.y = 50;
Lines[7].p0.z = -50;
Lines[7].p1.x = -50;
Lines[7].p1.y = -50;
Lines[7].p1.z = -50;
// now the 4 edge lines.
Lines[8].p0.x = -50;
Lines[8].p0.y = -50;
Lines[8].p0.z = 50;
Lines[8].p1.x = -50;
Lines[8].p1.y = -50;
Lines[8].p1.z = -50;
Lines[9].p0.x = 50;
Lines[9].p0.y = -50;
Lines[9].p0.z = 50;
Lines[9].p1.x = 50;
Lines[9].p1.y = -50;
Lines[9].p1.z = -50;
Lines[10].p0.x = -50;
Lines[10].p0.y = 50;
Lines[10].p0.z = 50;
Lines[10].p1.x = -50;
Lines[10].p1.y = 50;
Lines[10].p1.z = -50;
Lines[11].p0.x = 50;
Lines[11].p0.y = 50;
Lines[11].p0.z = 50;
Lines[11].p1.x = 50;
Lines[11].p1.y = 50;
Lines[11].p1.z = -50;
LinestoRender = 12;
OldLinestoRender = LinestoRender;
}

View File

@@ -0,0 +1,42 @@
// We need this header file to use FLASH as storage with PROGMEM directive:
#include <pgmspace.h>
// Icon width and height
const uint16_t alertWidth = 32;
const uint16_t alertHeight = 32;
// The icon file can be created with the "UTFT ImageConverter 565" bitmap to .c file creation utility, more can be pasted in here
const unsigned short alert[1024] PROGMEM={
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0840,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 0, 32 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1080,0xAC66,0xEDE8,0xFE69,0xC4C6,0x2901,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 1, 64 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xBCC6,0xFE68,0xFE68,0xFE6A,0xFE68,0xEDE8,0x18A1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 2, 96 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8344,0xFE48,0xFE8C,0xFFDD,0xFFFF,0xFEF0,0xFE48,0xB466,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 3, 128 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1880,0xEDC7,0xFE48,0xFF99,0xFFBC,0xFF9B,0xFFBD,0xFE6A,0xFE48,0x5A23,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 4, 160 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x9BE5,0xFE28,0xFED0,0xFFBC,0xFF7A,0xFF9A,0xFF9B,0xFF35,0xFE28,0xBCA6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 5, 192 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3962,0xFE28,0xFE28,0xFF9A,0xFF79,0xFF9A,0xFF9B,0xFF9A,0xFFBD,0xFE6B,0xFE28,0x72E3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 6, 224 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xB465,0xFE28,0xFEF2,0xFF7A,0xFF79,0xFF7A,0xFF9A,0xFF7A,0xFF7A,0xFF78,0xFE28,0xDD67,0x0860,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 7, 256 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5A22,0xFE07,0xFE29,0xFF9B,0xFF37,0xFF58,0xFF79,0xFF79,0xFF79,0xFF58,0xFF9B,0xFEAE,0xFE07,0x93A4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 8, 288 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xC4A5,0xFE07,0xFF15,0xFF37,0xFF36,0xAD11,0x2965,0x2965,0xCDF4,0xFF37,0xFF37,0xFF79,0xFE07,0xFE07,0x2901,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 9, 320 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7B03,0xFDE7,0xFE4B,0xFF79,0xFEF4,0xFF15,0xB552,0x2945,0x2945,0xDE55,0xFF16,0xFF15,0xFF58,0xFED1,0xFDE7,0xAC25,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 10, 352 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0840,0xDD26,0xFDE7,0xFF57,0xFED3,0xFED2,0xFEF4,0xBD93,0x2124,0x2124,0xDE75,0xFF14,0xFED3,0xFED3,0xFF7A,0xFE08,0xFDE7,0x49A2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 11, 384 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x9BA4,0xFDC6,0xFE6E,0xFF36,0xFE90,0xFEB1,0xFED3,0xC592,0x2124,0x2124,0xE675,0xFED3,0xFEB2,0xFEB1,0xFEF3,0xFEF3,0xFDC6,0xBC45,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 12, 416 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3141,0xF5C6,0xF5C7,0xFF58,0xFE90,0xFE6F,0xFE8F,0xFEB1,0xCDB2,0x2104,0x2104,0xF6B4,0xFEB1,0xFE90,0xFE8F,0xFE90,0xFF58,0xFE0A,0xF5C6,0x72A3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 13, 448 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xABE4,0xF5A6,0xFEB1,0xFED3,0xFE4E,0xFE6E,0xFE6F,0xFE90,0xD5F2,0x18E3,0x18E3,0xFED4,0xFE90,0xFE6F,0xFE6F,0xFE6E,0xFE91,0xFF36,0xF5A6,0xCCA5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 14, 480 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x5202,0xF5A6,0xF5C7,0xFF58,0xFE4D,0xFE4D,0xFE4D,0xFE4E,0xFE6F,0xDE11,0x18C3,0x18C3,0xFED3,0xFE6F,0xFE6E,0xFE4E,0xFE4D,0xFE4D,0xFF16,0xFE2C,0xF5A6,0x9363,0x0000,0x0000,0x0000,0x0000,0x0000, // row 15, 512 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0xBC44,0xF585,0xFED3,0xFE6F,0xFE2C,0xFE2C,0xFE2D,0xFE4D,0xFE4E,0xE630,0x10A2,0x2104,0xFED1,0xFE4E,0xFE4D,0xFE4D,0xFE2D,0xFE2C,0xFE4D,0xFF37,0xF586,0xF585,0x28E1,0x0000,0x0000,0x0000,0x0000, // row 16, 544 pixels
0x0000,0x0000,0x0000,0x0000,0x7282,0xF565,0xF5EA,0xFF16,0xFE0B,0xFE0B,0xFE0B,0xFE2C,0xFE2C,0xFE4D,0xF670,0x1082,0x2924,0xFEB0,0xFE2D,0xFE2C,0xFE2C,0xFE2C,0xFE0B,0xFE0B,0xFEB2,0xFE6F,0xF565,0xA383,0x0000,0x0000,0x0000,0x0000, // row 17, 576 pixels
0x0000,0x0000,0x0000,0x0840,0xD4C4,0xF565,0xFEF5,0xFE0C,0xFDE9,0xFDEA,0xFE0A,0xFE0B,0xFE0B,0xFE2C,0xFE8F,0x0861,0x2964,0xFE8F,0xFE2C,0xFE0B,0xFE0B,0xFE0B,0xFE0A,0xFDEA,0xFE0B,0xFF37,0xF586,0xF565,0x4181,0x0000,0x0000,0x0000, // row 18, 608 pixels
0x0000,0x0000,0x0000,0x9343,0xF545,0xF60C,0xFED3,0xFDC8,0xFDC8,0xFDC9,0xFDE9,0xFDEA,0xFDEA,0xFE0B,0xFE8E,0x0861,0x3184,0xFE6D,0xFE0B,0xFE0A,0xFDEA,0xFDEA,0xFDE9,0xFDC9,0xFDC9,0xFE4E,0xFEB2,0xF545,0xB3E3,0x0000,0x0000,0x0000, // row 19, 640 pixels
0x0000,0x0000,0x28E0,0xF544,0xF545,0xFF17,0xFDC8,0xFDA7,0xFDA7,0xFDC8,0xFDC8,0xFDC9,0xFDC9,0xFDE9,0xFE6C,0x10A2,0x39C4,0xFE4C,0xFDEA,0xFDE9,0xFDC9,0xFDC9,0xFDC8,0xFDC8,0xFDA7,0xFDA8,0xFF16,0xF588,0xF544,0x6222,0x0000,0x0000, // row 20, 672 pixels
0x0000,0x0000,0xA383,0xF524,0xF64E,0xFE4E,0xFD86,0xFD86,0xFD87,0xFDA7,0xFDA7,0xFDA8,0xFDC8,0xFDC8,0xFE2A,0xA469,0xB4EA,0xFE2A,0xFDC9,0xFDC8,0xFDC8,0xFDA8,0xFDA7,0xFDA7,0xFD87,0xFD86,0xFDEA,0xFED3,0xF524,0xC443,0x0000,0x0000, // row 21, 704 pixels
0x0000,0x51C1,0xF504,0xF546,0xFF16,0xF565,0xFD65,0xFD65,0xFD86,0xFD86,0xFD86,0xFDA7,0xFDA7,0xFDA7,0xFDE8,0xFE6A,0xFE4A,0xFDE8,0xFDA7,0xFDA7,0xFDA7,0xFDA7,0xFD86,0xFD86,0xFD86,0xFD65,0xFD65,0xFEB2,0xF5CA,0xF504,0x8AE2,0x0000, // row 22, 736 pixels
0x0000,0xB3A2,0xED03,0xFE92,0xFDC9,0xF543,0xF544,0xFD44,0xFD65,0xFD65,0xFD65,0xFD86,0xFD86,0xFD86,0xFDA7,0xFDC7,0xFDC7,0xFDA7,0xFD86,0xFD86,0xFD86,0xFD86,0xFD65,0xFD65,0xFD65,0xFD44,0xF544,0xFD86,0xFEF5,0xED03,0xE4C3,0x1880, // row 23, 768 pixels
0x7241,0xECE3,0xF567,0xFED3,0xF523,0xF523,0xF523,0xF543,0xF544,0xF544,0xFD65,0xFD65,0xFD65,0xFD65,0xD4E6,0x39C5,0x39A5,0xD4E6,0xFD86,0xFD65,0xFD65,0xFD65,0xFD65,0xF544,0xF544,0xF543,0xF523,0xF523,0xFE2E,0xF5EC,0xECE3,0x9B42, // row 24, 800 pixels
0xD443,0xECE3,0xFED4,0xF565,0xF502,0xF502,0xF522,0xF523,0xF523,0xF543,0xF544,0xF544,0xF544,0xFD65,0x8B64,0x18C3,0x18C3,0x8344,0xFD85,0xFD44,0xF544,0xF544,0xF544,0xF543,0xF523,0xF523,0xF522,0xF502,0xF523,0xFEF5,0xED04,0xECE3, // row 25, 832 pixels
0xECC3,0xF5AB,0xFE6F,0xF501,0xF4E1,0xF501,0xF502,0xF502,0xF522,0xF522,0xF523,0xF523,0xF523,0xFD84,0xC504,0x20E1,0x18E1,0xC4E4,0xFD84,0xF543,0xF523,0xF523,0xF523,0xF522,0xF522,0xF502,0xF502,0xF501,0xF501,0xFDC9,0xF62F,0xECC3, // row 26, 864 pixels
0xECC2,0xFE92,0xF523,0xF4E0,0xF4E0,0xF4E1,0xF4E1,0xF501,0xF501,0xF502,0xF502,0xF522,0xF522,0xF543,0xFDE3,0xFEA5,0xF6A4,0xFE04,0xF543,0xF522,0xF522,0xF522,0xF502,0xF502,0xF501,0xF501,0xF4E1,0xF4E1,0xF4E0,0xF4E1,0xFED4,0xECC2, // row 27, 896 pixels
0xECA2,0xF5EC,0xF4E0,0xF4C0,0xF4E0,0xF4E0,0xF4E0,0xF4E1,0xF4E1,0xF501,0xF501,0xF501,0xF502,0xF502,0xF542,0xFDA2,0xFDA2,0xF542,0xF502,0xF502,0xF502,0xF501,0xF501,0xF501,0xF4E1,0xF4E1,0xF4E0,0xF4E0,0xF4E0,0xF4C0,0xF5A9,0xECA2, // row 28, 928 pixels
0xECA2,0xECA2,0xECC2,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4E1,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xECC2,0xECC3,0xECA2, // row 29, 960 pixels
0x8AC1,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0x9B01, // row 30, 992 pixels
0x0000,0x1880,0x51A0,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x61E0,0x28E0,0x0000}; // row 31, 1024 pixels

View File

@@ -0,0 +1,41 @@
// We need this header file to use FLASH as storage with PROGMEM directive:
#include <pgmspace.h>
// Icon width and height
const uint16_t closeWidth = 32;
const uint16_t closeHeight = 32;
// The icon file can be created with the "UTFT ImageConverter 565" bitmap to .c file creation utility, more can be pasted in here
const unsigned short close[1024] PROGMEM={
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30C3,0x4124,0x61C7,0x61C7,0x4124,0x30E3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 0, 32 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x48E3,0xA249,0xEB8E,0xFCB2,0xFD14,0xFD75,0xFD96,0xFD34,0xFCF3,0xEBEF,0xA28A,0x4904,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 1, 64 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x58E3,0xC228,0xFC10,0xFD34,0xFE18,0xFE59,0xFE79,0xFE9A,0xFE9A,0xFE9A,0xFE9A,0xFE59,0xFD75,0xFC51,0xC28A,0x5904,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 2, 96 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2041,0x8945,0xF34D,0xFD34,0xFDB6,0xFD75,0xFD55,0xFD55,0xFD96,0xFDD7,0xFDF7,0xFDF7,0xFDB6,0xFDB6,0xFDD7,0xFDF7,0xFD75,0xF38E,0x8965,0x2041,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 3, 128 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x4082,0xE208,0xF410,0xFD34,0xFC92,0xFBEF,0xFBAE,0xFBEF,0xFC71,0xFD14,0xFD75,0xFDB6,0xFD75,0xFD14,0xFC92,0xFC51,0xFC71,0xFCF3,0xFD75,0xFC30,0xEA28,0x40A2,0x0000,0x0000,0x0000,0x0000,0x0000, // row 4, 160 pixels
0x0000,0x0000,0x0000,0x0000,0x3861,0xE1E7,0xF451,0xFC92,0xFB4D,0xFA49,0xFA49,0xFAEB,0xFBAE,0xFC71,0xFD34,0xFDB6,0xFE18,0xFDB6,0xFD34,0xFC71,0xFBAE,0xFB0C,0xFAEB,0xFBAE,0xFCD3,0xFC71,0xE208,0x4082,0x0000,0x0000,0x0000,0x0000, // row 5, 192 pixels
0x0000,0x0000,0x0000,0x1020,0xD986,0xF430,0xFC30,0xFA28,0xF924,0xF965,0xFA8A,0xFB0C,0xFBAE,0xFC51,0xFD14,0xFD75,0xFDB6,0xFD75,0xFD14,0xFC51,0xFC71,0xFBEF,0xFA28,0xF9C7,0xFA8A,0xFC51,0xF430,0xD9A6,0x1020,0x0000,0x0000,0x0000, // row 6, 224 pixels
0x0000,0x0000,0x0000,0x78A2,0xEB6D,0xFC30,0xF9C7,0xF861,0xF8A2,0xFA08,0xFEDB,0xFD55,0xFB4D,0xFC10,0xFC92,0xFD14,0xFD34,0xFD14,0xFC92,0xFCB2,0xFF7D,0xFF7D,0xFB2C,0xF945,0xF8E3,0xF9E7,0xFC30,0xEB8E,0x78C3,0x0000,0x0000,0x0000, // row 7, 256 pixels
0x0000,0x0000,0x3841,0xD9E7,0xF492,0xF208,0xF041,0xF800,0xF945,0xFE9A,0xFFFF,0xFFFF,0xFD75,0xFB8E,0xFC10,0xFC51,0xFC71,0xFC51,0xFCB2,0xFF7D,0xFFFF,0xFFFF,0xFF3C,0xFA8A,0xF882,0xF841,0xFA08,0xFC92,0xDA08,0x3841,0x0000,0x0000, // row 8, 288 pixels
0x0000,0x0000,0x88A2,0xEBCF,0xF2EB,0xF061,0xF000,0xF8E3,0xFE79,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFD75,0xFB4D,0xFBAE,0xFBAE,0xFC71,0xFF7D,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFEFB,0xFA28,0xF800,0xF061,0xF2EB,0xEBEF,0x90C3,0x0000,0x0000, // row 9, 320 pixels
0x0000,0x2820,0xD1C7,0xF410,0xE945,0xE800,0xF000,0xFE9A,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFD34,0xFAEB,0xFBCF,0xFF5D,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFF1C,0xF986,0xF000,0xF145,0xF410,0xD1E7,0x2820,0x0000, // row 10, 352 pixels
0x0000,0x6841,0xDB2C,0xEACB,0xE041,0xE800,0xF000,0xFEFB,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFD14,0xFF1C,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFBCF,0xF082,0xF000,0xE841,0xEACB,0xE34D,0x7061,0x0000, // row 11, 384 pixels
0x0000,0x9861,0xE3CF,0xE186,0xE000,0xE800,0xE800,0xF145,0xFEDB,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFB8E,0xF000,0xF000,0xE800,0xE800,0xE986,0xEBCF,0xA082,0x0000, // row 12, 416 pixels
0x0800,0xB8A2,0xE3AE,0xD8A2,0xD800,0xE000,0xE800,0xE800,0xF145,0xFEFB,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFB8E,0xF000,0xF000,0xE800,0xE800,0xE000,0xE0A2,0xEBAE,0xC0C3,0x0800, // row 13, 448 pixels
0x1800,0xC124,0xE30C,0xD020,0xD800,0xE000,0xE000,0xE800,0xE800,0xF145,0xFEDB,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFB8E,0xF000,0xF000,0xE800,0xE800,0xE000,0xE000,0xD820,0xE30C,0xC124,0x1800, // row 14, 480 pixels
0x2800,0xC165,0xDAAA,0xC800,0xD000,0xD800,0xE000,0xE000,0xE800,0xE800,0xF124,0xFE79,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFB6D,0xF000,0xF000,0xE800,0xE800,0xE000,0xE000,0xD800,0xD000,0xDAAA,0xC165,0x2800, // row 15, 512 pixels
0x2000,0xB924,0xD269,0xC800,0xD000,0xD000,0xD800,0xE000,0xE000,0xE800,0xE924,0xFEFB,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xF36D,0xE800,0xE800,0xE800,0xE000,0xE000,0xD800,0xD000,0xD000,0xDA69,0xC145,0x2800, // row 16, 544 pixels
0x1000,0xB0A2,0xD28A,0xC000,0xC800,0xD000,0xD000,0xD800,0xD800,0xE165,0xFEFB,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xF3AE,0xE000,0xE000,0xD800,0xD800,0xD000,0xD000,0xC800,0xD28A,0xB8C3,0x1000, // row 17, 576 pixels
0x0000,0xA800,0xD2AA,0xB800,0xC000,0xC800,0xC800,0xD000,0xD965,0xFEFB,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xEBAE,0xD800,0xD800,0xD000,0xC800,0xC800,0xC000,0xD2AA,0xB020,0x0000, // row 18, 608 pixels
0x0000,0x8000,0xCA69,0xB841,0xB800,0xC000,0xC800,0xD186,0xFEFB,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xEBCF,0xD000,0xC800,0xC800,0xC000,0xC041,0xCA69,0x8000,0x0000, // row 19, 640 pixels
0x0000,0x4800,0xC1C7,0xB8E3,0xB800,0xB800,0xC000,0xF69A,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xEBEF,0xFE79,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xE410,0xC841,0xC000,0xB800,0xC0E3,0xC1C7,0x4800,0x0000, // row 20, 672 pixels
0x0000,0x1000,0xB061,0xC1E7,0xB000,0xB000,0xB800,0xD269,0xFFBE,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xE38E,0xD000,0xD965,0xF69A,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xDB0C,0xC020,0xB800,0xB000,0xC1E7,0xB061,0x1000,0x0000, // row 21, 704 pixels
0x0000,0x0000,0x6000,0xB9C7,0xB061,0xB000,0xB000,0xB800,0xCA49,0xFF9E,0xFFFF,0xFFFF,0xFFFF,0xE38E,0xC800,0xC800,0xC800,0xD186,0xF69A,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xDB0C,0xB800,0xB800,0xB000,0xB061,0xC1C7,0x6000,0x0000,0x0000, // row 22, 736 pixels
0x0000,0x0000,0x1800,0xB041,0xB986,0xA800,0xA800,0xB000,0xB000,0xCA49,0xFF7D,0xFFFF,0xDB8E,0xC000,0xC000,0xC000,0xC000,0xC000,0xC986,0xF6DB,0xFFFF,0xFFFF,0xD30C,0xB800,0xB000,0xB000,0xA800,0xB986,0xB041,0x1800,0x0000,0x0000, // row 23, 768 pixels
0x0000,0x0000,0x0000,0x5800,0xB0E3,0xA8C3,0xA800,0xA800,0xA800,0xB000,0xCACB,0xD38E,0xB000,0xB800,0xB800,0xB800,0xB800,0xB800,0xB800,0xC145,0xF6DB,0xD34D,0xB000,0xB000,0xA800,0xA800,0xB0C3,0xB0E3,0x5800,0x0000,0x0000,0x0000, // row 24, 800 pixels
0x0000,0x0000,0x0000,0x0000,0x6000,0xB124,0xA882,0xA000,0xA800,0xA800,0xA800,0xA800,0xB000,0xB000,0xB000,0xB000,0xB000,0xB000,0xB000,0xB000,0xB000,0xA800,0xA800,0xA800,0xA800,0xA882,0xB124,0x6000,0x0000,0x0000,0x0000,0x0000, // row 25, 832 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0xB104,0xA882,0xA000,0xA000,0xA000,0xA800,0xA800,0xA800,0xA800,0xA800,0xA800,0xA800,0xA800,0xA800,0xA800,0xA800,0xA000,0xA000,0xA882,0xB104,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 26, 864 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0xB0A2,0xA8C3,0xA020,0xA000,0xA000,0xA000,0xA000,0xA000,0xA000,0xA000,0xA000,0xA000,0xA000,0xA000,0xA000,0xA020,0xA8C3,0xB0A2,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 27, 896 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4800,0xA800,0xB0C3,0xA0A2,0x9800,0x9800,0x9800,0x9800,0xA000,0xA000,0xA000,0x9800,0x9800,0x9800,0xA082,0xB0E3,0xA800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 28, 928 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5800,0xA800,0xB0A2,0xA8E3,0xA0A2,0xA041,0x9800,0x9800,0xA041,0xA0A2,0xA8E3,0xB0A2,0xA800,0x5800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 29, 960 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x6000,0x8800,0xA000,0xA800,0xA800,0xA000,0x8800,0x6000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 30, 992 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}; // row 31, 1024 pixels

View File

@@ -0,0 +1,113 @@
// Code partly derived from ILI9341_due library example
// Draws the 3 icons across the middle of the screen and pauses.
// Then draws 300 icons at random locations, clears screen and repeats
//
// This demonstrates drawing icons from FLASH
// Icons are stored in tabs, e.g. Alert.h etc
// more than one icon can be in a header file.
/*
This sketch demonstrates loading images from arrays stored in program (FLASH) memory.
Works with TFT_eSPI library here:
https://github.com/Bodmer/TFT_eSPI
This sketch does not use/need any fonts at all...
Arrays containing FLASH images can be created with UTFT library tool:
(libraries\UTFT\Tools\ImageConverter565.exe)
Convert to .c format then copy into a new tab
The number and size of icons is limited by available FLASH memory. The icon array will
use width x height x 2 bytes of FLASH, i.e. 32 x 32 icon uses ~2048 bytes
*/
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library with default width and height
// Include the header files that contain the icons
#include "alert.h"
#include "Close.h"
#include "Info.h"
long count = 0; // Loop count
void setup()
{
Serial.begin(115200);
tft.begin();
tft.setRotation(1); // landscape
tft.fillScreen(TFT_BLACK);
// Draw the icons
drawIcon(info, (tft.width() - infoWidth)/2 - 50, (tft.height() - infoHeight)/2, infoWidth, infoHeight);
drawIcon(alert, (tft.width() - alertWidth)/2, (tft.height() - alertHeight)/2, alertWidth, alertHeight);
drawIcon(close, (tft.width() - closeWidth)/2 + 50, (tft.height() - closeHeight)/2, closeWidth, closeHeight);
// Pause here to admire the icons!
delay(4000);
}
void loop()
{
// Loop filling and clearing screen
drawIcon(info, random(tft.width() - infoWidth), random(tft.height() - infoHeight), infoWidth, infoHeight);
drawIcon(alert, random(tft.width() - alertWidth), random(tft.height() - alertHeight), alertWidth, alertHeight);
drawIcon(close, random(tft.width() - closeWidth), random(tft.height() - closeHeight), alertWidth, closeHeight);
// Clear screen after 100 x 3 = 300 icons drawn
if (100 == count++) {
count = 1;
tft.setRotation(2 * random(2)); // Rotate randomly to clear display left>right or right>left to reduce monotony!
tft.fillScreen(TFT_BLACK);
tft.setRotation(1);
Serial.println(millis());
}
}
//====================================================================================
// This is the function to draw the icon stored as an array in program memory (FLASH)
//====================================================================================
// To speed up rendering we use a 64 pixel buffer
#define BUFF_SIZE 64
// Draw array "icon" of defined width and height at coordinate x,y
// Maximum icon size is 255x255 pixels to avoid integer overflow
void drawIcon(const unsigned short* icon, int16_t x, int16_t y, int8_t width, int8_t height) {
uint16_t pix_buffer[BUFF_SIZE]; // Pixel buffer (16 bits per pixel)
// Set up a window the right size to stream pixels into
tft.setWindow(x, y, x + width - 1, y + height - 1);
// Work out the number whole buffers to send
uint16_t nb = ((uint16_t)height * width) / BUFF_SIZE;
// Fill and send "nb" buffers to TFT
for (int i = 0; i < nb; i++) {
for (int j = 0; j < BUFF_SIZE; j++) {
pix_buffer[j] = pgm_read_word(&icon[i * BUFF_SIZE + j]);
}
tft.pushColors(pix_buffer, BUFF_SIZE);
}
// Work out number of pixels not yet sent
uint16_t np = ((uint16_t)height * width) % BUFF_SIZE;
// Send any partial buffer left over
if (np) {
for (int i = 0; i < np; i++) pix_buffer[i] = pgm_read_word(&icon[nb * BUFF_SIZE + i]);
tft.pushColors(pix_buffer, np);
}
}

View File

@@ -0,0 +1,41 @@
// We need this header file to use FLASH as storage with PROGMEM directive:
#include <pgmspace.h>
// Icon width and height
const uint16_t infoWidth = 32;
const uint16_t infoHeight = 32;
// The icon file can be created with the "UTFT ImageConverter 565" bitmap to .c file creation utility, more can be pasted in here
const unsigned short info[1024] PROGMEM={
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 0, 32 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0861,0x4A69,0x8C71,0xA514,0xBDF7,0xBDF7,0xA514,0x8C71,0x4A69,0x0861,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 1, 64 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x39E7,0x9CF3,0xEF7D,0xF79E,0xFFDF,0xFFDF,0xFFDF,0xFFDF,0xFFDF,0xFFDF,0xF79E,0xEF7D,0x9CF3,0x39E7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 2, 96 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2965,0x9492,0xF79E,0xFFDF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFDF,0xF79E,0x9492,0x2965,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 3, 128 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x630C,0xEF7D,0xFFDF,0xFFFF,0xFFFF,0xFFFF,0xD75F,0xB6BF,0x9E5F,0x963F,0x963F,0x9E5F,0xB6BF,0xD75F,0xFFFF,0xFFFF,0xFFFF,0xFFDF,0xEF7D,0x630C,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 4, 160 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x73AE,0xEF7D,0xFFDF,0xFFFF,0xFFDF,0xBEDF,0x7DBF,0x7DBF,0x7DDF,0x7DDF,0x7DDF,0x7DDF,0x7DDF,0x7DBF,0x759F,0x7DBE,0xBEBF,0xFFDF,0xFFFF,0xFFDF,0xEF7D,0x73AE,0x0000,0x0000,0x0000,0x0000,0x0000, // row 5, 192 pixels
0x0000,0x0000,0x0000,0x0000,0x630C,0xEF7D,0xFFFF,0xFFFF,0xE77F,0x7DBE,0x759E,0x759F,0x7DBF,0x7DDF,0x7DDF,0x85FF,0x7DDF,0x7DDF,0x7DBF,0x759F,0x759E,0x6D7E,0x7DBE,0xDF7F,0xFFFF,0xFFFF,0xEF7D,0x630C,0x0000,0x0000,0x0000,0x0000, // row 6, 224 pixels
0x0000,0x0000,0x0000,0x31A6,0xEF5D,0xFFDF,0xFFFF,0xCF1E,0x6D7E,0x6D7E,0x759E,0x759F,0x7DBF,0x7DDF,0x8E1F,0xBEDF,0xC6FF,0x8DFF,0x75BF,0x759F,0x759E,0x6D7E,0x655E,0x655D,0xCF1E,0xFFFF,0xFFDF,0xEF5D,0x31A6,0x0000,0x0000,0x0000, // row 7, 256 pixels
0x0000,0x0000,0x0000,0x94B2,0xF7BE,0xFFFF,0xDF5E,0x655D,0x655D,0x6D7E,0x6D7E,0x759E,0x75BF,0x759F,0xEFBF,0xFFFF,0xFFFF,0xEFBF,0x759F,0x759E,0x6D7E,0x6D7E,0x655D,0x653D,0x653D,0xDF5E,0xFFFF,0xF7BE,0x94B2,0x0000,0x0000,0x0000, // row 8, 288 pixels
0x0000,0x0000,0x4228,0xEF7D,0xFFFF,0xF7BF,0x6D5D,0x653D,0x655D,0x6D5E,0x6D7E,0x759E,0x759E,0x85DF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x8DFE,0x6D7E,0x6D7E,0x6D5E,0x655D,0x653D,0x5D1D,0x6D5D,0xF7BF,0xFFFF,0xEF7D,0x4228,0x0000,0x0000, // row 9, 320 pixels
0x0000,0x0000,0xA534,0xFFDF,0xFFDF,0xA65D,0x5D1D,0x5D1D,0x653D,0x655E,0x6D7E,0x6D7E,0x6D7E,0x651E,0xE77F,0xFFFF,0xFFFF,0xF7BF,0x5CFE,0x6D7E,0x6D7E,0x655E,0x653D,0x5D1D,0x5D1D,0x54FC,0xA65D,0xFFDF,0xFFDF,0xA534,0x0000,0x0000, // row 10, 352 pixels
0x0000,0x18E3,0xEF5D,0xFFFF,0xEF9E,0x5CFC,0x54FC,0x5D1D,0x5D3D,0x653D,0x655E,0x6D7E,0x6D7E,0x653E,0x6D3E,0xB67E,0xBEBE,0x755E,0x5D1E,0x6D5E,0x655E,0x653D,0x5D3D,0x5D1D,0x54FC,0x54DC,0x54FC,0xEF9E,0xFFFF,0xEF5D,0x18E3,0x0000, // row 11, 384 pixels
0x0000,0x630C,0xEF7D,0xFFDF,0xB69D,0x54DC,0x54FC,0x5CFC,0x5D1D,0x653D,0x653D,0x655E,0x6D5E,0x655E,0x5CFE,0x4C9D,0x4C7D,0x54DD,0x653E,0x655E,0x653D,0x653D,0x5D1D,0x5CFC,0x54FC,0x54DC,0x4CBC,0xB69D,0xFFDF,0xEF7D,0x630C,0x0000, // row 12, 416 pixels
0x0000,0x94B2,0xF7BE,0xFFDF,0x85BC,0x4CBC,0x54DC,0x54FC,0x5CFD,0x5D1D,0x5D3D,0x653D,0x655D,0x653D,0x85DE,0xC6FE,0xC6FE,0x85BE,0x653D,0x653D,0x5D3D,0x5D1D,0x5CFD,0x54FC,0x54DC,0x4CBC,0x4CBB,0x85BC,0xFFDF,0xF7BE,0x94B2,0x0000, // row 13, 448 pixels
0x0000,0xB5B6,0xFFDF,0xF7BE,0x651C,0x4CBB,0x4CBC,0x54DC,0x54FC,0x5CFC,0x5D1D,0x5D1D,0x653D,0x5D1D,0xE77E,0xFFDF,0xFFDF,0xEF9E,0x5CFD,0x5D1D,0x5D1D,0x5CFC,0x54FC,0x54DC,0x4CBC,0x4CBB,0x449B,0x651B,0xF7BE,0xFFDF,0xB5B6,0x0000, // row 14, 480 pixels
0x0000,0xC638,0xFFDF,0xF7BE,0x54DB,0x449B,0x4CBB,0x4CBC,0x54DC,0x54FC,0x54FC,0x5D1D,0x5D1D,0x7D7D,0xF7BE,0xF7BE,0xF7BE,0xF7BE,0x7D7D,0x5CFD,0x54FC,0x54FC,0x54DC,0x4CBC,0x4CBB,0x449B,0x447B,0x54BB,0xF7BE,0xFFDF,0xC638,0x0000, // row 15, 512 pixels
0x0000,0xC638,0xFFDF,0xF79E,0x4CBB,0x449B,0x449B,0x4CBB,0x4CBC,0x54DC,0x54DC,0x54FC,0x54DC,0x753C,0xF7BE,0xF7BE,0xF7BE,0xF7BE,0x753C,0x54DC,0x54DC,0x54DC,0x4CBC,0x4CBB,0x449B,0x449B,0x3C7B,0x4C9B,0xF79E,0xFFDF,0xC638,0x0000, // row 16, 544 pixels
0x0000,0xB5B6,0xFFDF,0xF7BE,0x5CFB,0x3C7B,0x447B,0x449B,0x4CBB,0x4CBC,0x4CBC,0x4CDC,0x4CBC,0x6D1C,0xF7BE,0xF7BE,0xF7BE,0xF7BE,0x6CFC,0x4CBC,0x4CBC,0x4CBC,0x4CBB,0x449B,0x447B,0x3C7B,0x3C5A,0x54DB,0xF7BE,0xFFDF,0xB5B6,0x0000, // row 17, 576 pixels
0x0000,0x94B2,0xF7BE,0xF7BE,0x755B,0x3C5A,0x3C7B,0x447B,0x449B,0x449B,0x4CBB,0x4CBB,0x4C9B,0x6CFB,0xF79E,0xF79E,0xF79E,0xF79E,0x64FB,0x449B,0x4CBB,0x449B,0x449B,0x447B,0x3C7B,0x3C5A,0x3C5A,0x753B,0xF7BE,0xF7BE,0x9CD3,0x0000, // row 18, 608 pixels
0x0000,0x6B4D,0xEF7D,0xF7BE,0xA61C,0x3C5A,0x3C5A,0x3C7B,0x447B,0x447B,0x449B,0x449B,0x447B,0x64DB,0xF79E,0xF79E,0xF79E,0xF79E,0x64DB,0x447B,0x449B,0x447B,0x447B,0x3C7B,0x3C5A,0x3C5A,0x343A,0xA61C,0xF7BE,0xEF7D,0x6B4D,0x0000, // row 19, 640 pixels
0x0000,0x2124,0xE71C,0xFFDF,0xDF3D,0x3C5A,0x343A,0x3C5A,0x3C5A,0x3C7B,0x3C7B,0x447B,0x3C5B,0x64BA,0xF79E,0xF79E,0xF79E,0xF79E,0x64BA,0x3C5B,0x3C7B,0x3C7B,0x3C5A,0x3C5A,0x343A,0x343A,0x343A,0xDF3D,0xFFDF,0xE71C,0x2124,0x0000, // row 20, 672 pixels
0x0000,0x0000,0xAD75,0xF7BE,0xF79E,0x859B,0x343A,0x343A,0x345A,0x3C5A,0x3C5A,0x3C5A,0x3C5A,0x5C9A,0xEF7D,0xEF7D,0xEF7D,0xEF7D,0x5C9A,0x3C3A,0x3C5A,0x3C5A,0x345A,0x343A,0x343A,0x341A,0x859B,0xF79E,0xF7BE,0xAD75,0x0000,0x0000, // row 21, 704 pixels
0x0000,0x0000,0x528A,0xE71C,0xFFDF,0xDF3D,0x3C5A,0x343A,0x343A,0x343A,0x343A,0x3C5A,0x343A,0x4C5A,0xEF7D,0xEF7D,0xEF7D,0xEF7D,0x4C59,0x343A,0x343A,0x343A,0x343A,0x343A,0x341A,0x3C5A,0xDF3D,0xFFDF,0xE71C,0x528A,0x0000,0x0000, // row 22, 736 pixels
0x0000,0x0000,0x0000,0x9CD3,0xF79E,0xF7BE,0xBE7C,0x3419,0x341A,0x341A,0x343A,0x343A,0x341A,0x2B99,0xC69C,0xEF7D,0xEF7D,0xD6DC,0x2398,0x341A,0x343A,0x341A,0x341A,0x2C19,0x2C19,0xBE7C,0xF7BE,0xF79E,0x9CD3,0x0000,0x0000,0x0000, // row 23, 768 pixels
0x0000,0x0000,0x0000,0x39E7,0xDEDB,0xFFDF,0xF79E,0x9DFB,0x2C19,0x2C19,0x2C1A,0x341A,0x341A,0x2BB9,0x2B57,0x6459,0x74B9,0x2337,0x2BB9,0x341A,0x2C1A,0x2C19,0x2C19,0x2C19,0x9DFB,0xF79E,0xFFDF,0xDEDB,0x39E7,0x0000,0x0000,0x0000, // row 24, 800 pixels
0x0000,0x0000,0x0000,0x0000,0x632C,0xDEFB,0xFFDF,0xEF7D,0xB65C,0x3C39,0x2BF9,0x2C19,0x2C19,0x2BF9,0x2398,0x1B58,0x1B37,0x2398,0x2BF9,0x2C19,0x2BF9,0x2BF9,0x3439,0xB65C,0xEF7D,0xFFDF,0xDEFB,0x632C,0x0000,0x0000,0x0000,0x0000, // row 25, 832 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x73AE,0xDEFB,0xF7BE,0xF79E,0xDF1C,0x7D5A,0x2BF9,0x2BF9,0x2BF9,0x2BF9,0x23D9,0x23D9,0x2BF9,0x2BF9,0x2BF9,0x2BF9,0x7D5A,0xDF1C,0xF79E,0xF7BE,0xDEFB,0x73AE,0x0000,0x0000,0x0000,0x0000,0x0000, // row 26, 864 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x632C,0xDEDB,0xF79E,0xFFDF,0xEF7D,0xD6FC,0x9DFB,0x5CDA,0x4C9A,0x3419,0x3419,0x4C9A,0x5CDA,0x9DFB,0xD6FC,0xEF7D,0xFFDF,0xF79E,0xDEDB,0x632C,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 27, 896 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4208,0x94B2,0xDEFB,0xF7BE,0xFFDF,0xF7BE,0xF79E,0xEF7D,0xEF5D,0xEF5D,0xEF7D,0xF79E,0xF7BE,0xFFDF,0xF7BE,0xDEFB,0x94B2,0x4208,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 28, 928 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x528A,0xA534,0xDEDB,0xE73C,0xF79E,0xF7BE,0xF7BE,0xF7BE,0xF7BE,0xF79E,0xE73C,0xDEDB,0xA534,0x528A,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 29, 960 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x18C3,0x5AEB,0x8C71,0xAD55,0xBDD7,0xBDD7,0xAD55,0x8C71,0x5AEB,0x18C3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 30, 992 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}; // row 31, 1024 pixels

View File

@@ -0,0 +1,289 @@
/*
This example draws fonts (as used by the Adafruit_GFX library) onto the
screen. These fonts are called the GFX Free Fonts (GFXFF) in this library.
Other True Type fonts could be converted using the utility within the
"fontconvert" folder inside the library. This converted has also been
copied from the Adafruit_GFX library.
Since these fonts are a recent addition Adafruit do not have a tutorial
available yet on how to use the utility. Linux users will no doubt
figure it out! In the meantime there are 48 font files to use in sizes
from 9 point to 24 point, and in normal, bold, and italic or oblique
styles.
This example sketch uses both the print class and drawString() functions
to plot text to the screen.
Make sure LOAD_GFXFF is defined in the User_Setup.h file within the
TFT_eSPI library folder.
#########################################################################
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
#########################################################################
*/
#include "Free_Fonts.h" // Include the header file attached to this sketch
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library with default width and height
unsigned long drawTime = 0;
void setup(void) {
tft.begin();
tft.setRotation(1);
}
void loop() {
int xpos = 0;
int ypos = 40;
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Select different fonts to draw on screen using the print class
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
tft.fillScreen(TFT_NAVY); // Clear screen to navy background
header("Draw free fonts using print class");
// For comaptibility with Adafruit_GFX library the text background is not plotted when using the print class
// even if we specify it.
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
tft.setCursor(xpos, ypos); // Set cursor near top left corner of screen
tft.setTextFont(GLCD); // Select the orginal small GLCD font by using NULL or GLCD
tft.println(); // Move cursor down a line
tft.print("Original GLCD font"); // Print the font name onto the TFT screen
tft.println();
tft.println();
tft.setFreeFont(FSB9); // Select Free Serif 9 point font, could use:
// tft.setFreeFont(&FreeSerif9pt7b);
tft.println(); // Free fonts plot with the baseline (imaginary line the letter A would sit on)
// as the datum, so we must move the cursor down a line from the 0,0 position
tft.print("Serif Bold 9pt"); // Print the font name onto the TFT screen
tft.setFreeFont(FSB12); // Select Free Serif 12 point font
tft.println(); // Move cursor down a line
tft.print("Serif Bold 12pt"); // Print the font name onto the TFT screen
tft.setFreeFont(FSB18); // Select Free Serif 12 point font
tft.println(); // Move cursor down a line
tft.print("Serif Bold 18pt"); // Print the font name onto the TFT screen
tft.setFreeFont(FSB24); // Select Free Serif 24 point font
tft.println(); // Move cursor down a line
tft.print("Serif Bold 24pt"); // Print the font name onto the TFT screen
delay(4000);
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Now use drawString() so we can set background colours and the datum
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
tft.fillScreen(TFT_BLACK);
header("Draw with background using drawString()");
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextDatum(TC_DATUM); // Centre text on x,y position
xpos = tft.width() / 2; // Half the screen width
ypos = 50;
tft.setFreeFont(FSB9); // Select the font
tft.drawString("Serif Bold 9pt", xpos, ypos, GFXFF); // Draw the text string in the selected GFX free font
ypos += tft.fontHeight(GFXFF); // Get the font height and move ypos down
tft.setFreeFont(FSB12);
tft.drawString("Serif Bold 12pt", xpos, ypos, GFXFF);
ypos += tft.fontHeight(GFXFF);
tft.setFreeFont(FSB18);
tft.drawString("Serif Bold 18pt", xpos, ypos, GFXFF);
ypos += tft.fontHeight(GFXFF);
tft.setFreeFont(FSB24);
tft.drawString("Serif Bold 24pt", xpos, ypos, GFXFF);
ypos += tft.fontHeight(GFXFF);
// Set text padding to 120 pixels wide area to over-write old values on screen
tft.setTextPadding(120);
for (int i = 0; i <= 20; i++) {
tft.drawFloat(i / 10.0, 1, xpos, ypos, GFXFF);
delay (200);
}
delay(4000);
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Same again but with colours that show bounding boxes
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
tft.fillScreen(TFT_DARKGREY);
header("Show background filled bounding boxes");
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
tft.setTextDatum(TC_DATUM); // Centre text on x,y position
xpos = tft.width() / 2; // Half the screen width
ypos = 50;
tft.setFreeFont(FSB9); // Select the font
tft.drawString("Serif Bold 9pt", xpos, ypos, GFXFF); // Draw the text string in the selected GFX free font
ypos += tft.fontHeight(GFXFF); // Get the font height and move ypos down
tft.setFreeFont(FSB12);
tft.drawString("Serif Bold 12pt", xpos, ypos, GFXFF);
ypos += tft.fontHeight(GFXFF);
tft.setFreeFont(FSB18);
tft.drawString("Serif Bold 18pt", xpos, ypos, GFXFF);
ypos += tft.fontHeight(GFXFF);
tft.setFreeFont(FSBI24);
tft.drawString("Serif Bold Italic 24pt", xpos, ypos, GFXFF);
ypos += tft.fontHeight(GFXFF);
// Set text padding to 120 pixels wide area to over-write old values on screen
tft.setTextPadding(120);
for (int i = 0; i <= 20; i++) {
tft.drawFloat(i / 10.0, 1, xpos, ypos, GFXFF);
delay (200);
}
delay(4000);
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Now show setting the 12 datum positions works with free fonts
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Numbers, floats and strings can be drawn relative to a datum
tft.fillScreen(TFT_BLACK);
header("Draw text relative to a datum");
tft.setTextColor(TFT_DARKGREY, TFT_BLACK);
tft.setFreeFont(FSS9);
tft.setTextDatum(TL_DATUM);
tft.drawString("[Top left}", 20, 60, GFXFF);
drawDatum(20,60);
tft.setTextDatum(TC_DATUM);
tft.drawString("[Top centre]", 240, 60, GFXFF);
drawDatum(240,60);
tft.setTextDatum(TR_DATUM);
tft.drawString("[Top right]", 460, 60, GFXFF);
drawDatum(460,60);
tft.setTextDatum(ML_DATUM);
tft.drawString("[Middle left]", 20, 140, GFXFF);
drawDatum(20,140);
tft.setTextDatum(MC_DATUM);
tft.drawString("[Middle centre]", 240, 140, GFXFF);
drawDatum(240,140);
tft.setTextDatum(MR_DATUM);
tft.drawString("[Middle right]", 460, 140, GFXFF);
drawDatum(460,140);
tft.setTextDatum(BL_DATUM);
tft.drawString("[Bottom Left]", 20, 220, GFXFF);
drawDatum(20,220);
tft.setTextDatum(BC_DATUM);
tft.drawString("[Bottom centre]", 240, 220, GFXFF);
drawDatum(240,220);
tft.setTextDatum(BR_DATUM);
tft.drawString("[Bottom right]", 460, 220, GFXFF);
drawDatum(460,220);
tft.setTextDatum(L_BASELINE);
tft.drawString("[Left baseline]", 20, 300, GFXFF);
drawDatum(20,300);
tft.setTextDatum(C_BASELINE);
tft.drawString("[Centre baseline]", 240, 300, GFXFF);
drawDatum(240,300);
tft.setTextDatum(R_BASELINE);
tft.drawString("[Right baseline]", 460, 300, GFXFF);
drawDatum(460,300);
//while(1);
delay(8000);
}
// Print the header for a display screen
void header(const char *string)
{
tft.setTextSize(1);
tft.setTextColor(TFT_MAGENTA, TFT_BLUE);
tft.fillRect(0, 0, 480, 30, TFT_BLUE);
tft.setTextDatum(TC_DATUM);
tft.drawString(string, 239, 2, 4); // Font 4 for fast drawing with background
}
// Draw a + mark centred on x,y
void drawDatum(int x, int y)
{
tft.drawLine(x - 5, y, x + 5, y, TFT_GREEN);
tft.drawLine(x, y - 5, x, y + 5, TFT_GREEN);
}
// There follows a crude way of flagging that this example sketch needs fonts which
// have not been enbabled in the User_Setup.h file inside the TFT_HX8357 library.
//
// These lines produce errors during compile time if settings in User_Setup are not correct
//
// The error will be "does not name a type" but ignore this and read the text between ''
// it will indicate which font or feature needs to be enabled
//
// Either delete all the following lines if you do not want warnings, or change the lines
// to suit your sketch modifications.
#ifndef LOAD_GLCD
//ERROR_Please_enable_LOAD_GLCD_in_User_Setup
#endif
#ifndef LOAD_FONT2
//ERROR_Please_enable_LOAD_FONT2_in_User_Setup!
#endif
#ifndef LOAD_FONT4
//ERROR_Please_enable_LOAD_FONT4_in_User_Setup!
#endif
#ifndef LOAD_FONT6
//ERROR_Please_enable_LOAD_FONT6_in_User_Setup!
#endif
#ifndef LOAD_FONT7
//ERROR_Please_enable_LOAD_FONT7_in_User_Setup!
#endif
#ifndef LOAD_FONT8
//ERROR_Please_enable_LOAD_FONT8_in_User_Setup!
#endif
#ifndef LOAD_GFXFF
ERROR_Please_enable_LOAD_GFXFF_in_User_Setup!
#endif

View File

@@ -0,0 +1,378 @@
// Attach this header file to your sketch to use the GFX Free Fonts. You can write
// sketches without it, but it makes referencing them easier.
// This calls up ALL the fonts but they only get loaded if you actually
// use them in your sketch.
//
// No changes are needed to this header file unless new fonts are added to the
// library "Fonts/GFXFF" folder.
//
// To save a lot of typing long names, each font can easily be referenced in the
// sketch in three ways, either with:
//
// 1. Font file name with the & in front such as &FreeSansBoldOblique24pt7b
// an example being:
//
// tft.setFreeFont(&FreeSansBoldOblique24pt7b);
//
// 2. FF# where # is a number determined by looking at the list below
// an example being:
//
// tft.setFreeFont(FF32);
//
// 3. An abbreviation of the file name. Look at the list below to see
// the abbreviations used, for example:
//
// tft.setFreeFont(FSSBO24)
//
// Where the letters mean:
// F = Free font
// M = Mono
// SS = Sans Serif (double S to distinguish is form serif fonts)
// S = Serif
// B = Bold
// O = Oblique (letter O not zero)
// I = Italic
// # = point size, either 9, 12, 18 or 24
//
// Setting the font to NULL will select the GLCD font:
//
// tft.setFreeFont(NULL); // Set font to GLCD
#define LOAD_GFXFF
#ifdef LOAD_GFXFF // Only include the fonts if LOAD_GFXFF is defined in User_Setup.h
// Use these when printing or drawing text in GLCD and high rendering speed fonts
// Call up the font using tft.setTextFont()
#define GFXFF 1
#define GLCD 0
#define FONT2 2
#define FONT4 4
#define FONT6 6
#define FONT7 7
#define FONT8 8
// Use the following when calling tft.setFreeFont()
//
// Reserved for GLCD font // FF0
//
#define TT1 &TomThumb
#define FM9 &FreeMono9pt7b
#define FM12 &FreeMono12pt7b
#define FM18 &FreeMono18pt7b
#define FM24 &FreeMono24pt7b
#define FMB9 &FreeMonoBold9pt7b
#define FMB12 &FreeMonoBold12pt7b
#define FMB18 &FreeMonoBold18pt7b
#define FMB24 &FreeMonoBold24pt7b
#define FMO9 &FreeMonoOblique9pt7b
#define FMO12 &FreeMonoOblique12pt7b
#define FMO18 &FreeMonoOblique18pt7b
#define FMO24 &FreeMonoOblique24pt7b
#define FMBO9 &FreeMonoBoldOblique9pt7b
#define FMBO12 &FreeMonoBoldOblique12pt7b
#define FMBO18 &FreeMonoBoldOblique18pt7b
#define FMBO24 &FreeMonoBoldOblique24pt7b
#define FSS9 &FreeSans9pt7b
#define FSS12 &FreeSans12pt7b
#define FSS18 &FreeSans18pt7b
#define FSS24 &FreeSans24pt7b
#define FSSB9 &FreeSansBold9pt7b
#define FSSB12 &FreeSansBold12pt7b
#define FSSB18 &FreeSansBold18pt7b
#define FSSB24 &FreeSansBold24pt7b
#define FSSO9 &FreeSansOblique9pt7b
#define FSSO12 &FreeSansOblique12pt7b
#define FSSO18 &FreeSansOblique18pt7b
#define FSSO24 &FreeSansOblique24pt7b
#define FSSBO9 &FreeSansBoldOblique9pt7b
#define FSSBO12 &FreeSansBoldOblique12pt7b
#define FSSBO18 &FreeSansBoldOblique18pt7b
#define FSSBO24 &FreeSansBoldOblique24pt7b
#define FS9 &FreeSerif9pt7b
#define FS12 &FreeSerif12pt7b
#define FS18 &FreeSerif18pt7b
#define FS24 &FreeSerif24pt7b
#define FSI9 &FreeSerifItalic9pt7b
#define FSI12 &FreeSerifItalic12pt7b
#define FSI19 &FreeSerifItalic18pt7b
#define FSI24 &FreeSerifItalic24pt7b
#define FSB9 &FreeSerifBold9pt7b
#define FSB12 &FreeSerifBold12pt7b
#define FSB18 &FreeSerifBold18pt7b
#define FSB24 &FreeSerifBold24pt7b
#define FSBI9 &FreeSerifBoldItalic9pt7b
#define FSBI12 &FreeSerifBoldItalic12pt7b
#define FSBI18 &FreeSerifBoldItalic18pt7b
#define FSBI24 &FreeSerifBoldItalic24pt7b
#define FF0 NULL //ff0 reserved for GLCD
#define FF1 &FreeMono9pt7b
#define FF2 &FreeMono12pt7b
#define FF3 &FreeMono18pt7b
#define FF4 &FreeMono24pt7b
#define FF5 &FreeMonoBold9pt7b
#define FF6 &FreeMonoBold12pt7b
#define FF7 &FreeMonoBold18pt7b
#define FF8 &FreeMonoBold24pt7b
#define FF9 &FreeMonoOblique9pt7b
#define FF10 &FreeMonoOblique12pt7b
#define FF11 &FreeMonoOblique18pt7b
#define FF12 &FreeMonoOblique24pt7b
#define FF13 &FreeMonoBoldOblique9pt7b
#define FF14 &FreeMonoBoldOblique12pt7b
#define FF15 &FreeMonoBoldOblique18pt7b
#define FF16 &FreeMonoBoldOblique24pt7b
#define FF17 &FreeSans9pt7b
#define FF18 &FreeSans12pt7b
#define FF19 &FreeSans18pt7b
#define FF20 &FreeSans24pt7b
#define FF21 &FreeSansBold9pt7b
#define FF22 &FreeSansBold12pt7b
#define FF23 &FreeSansBold18pt7b
#define FF24 &FreeSansBold24pt7b
#define FF25 &FreeSansOblique9pt7b
#define FF26 &FreeSansOblique12pt7b
#define FF27 &FreeSansOblique18pt7b
#define FF28 &FreeSansOblique24pt7b
#define FF29 &FreeSansBoldOblique9pt7b
#define FF30 &FreeSansBoldOblique12pt7b
#define FF31 &FreeSansBoldOblique18pt7b
#define FF32 &FreeSansBoldOblique24pt7b
#define FF33 &FreeSerif9pt7b
#define FF34 &FreeSerif12pt7b
#define FF35 &FreeSerif18pt7b
#define FF36 &FreeSerif24pt7b
#define FF37 &FreeSerifItalic9pt7b
#define FF38 &FreeSerifItalic12pt7b
#define FF39 &FreeSerifItalic18pt7b
#define FF40 &FreeSerifItalic24pt7b
#define FF41 &FreeSerifBold9pt7b
#define FF42 &FreeSerifBold12pt7b
#define FF43 &FreeSerifBold18pt7b
#define FF44 &FreeSerifBold24pt7b
#define FF45 &FreeSerifBoldItalic9pt7b
#define FF46 &FreeSerifBoldItalic12pt7b
#define FF47 &FreeSerifBoldItalic18pt7b
#define FF48 &FreeSerifBoldItalic24pt7b
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Now we define "s"tring versions for easy printing of the font name so:
// tft.println(sFF5);
// will print
// Mono bold 9
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define sFF0 "GLCD"
#define sTT1 "Tom Thumb"
#define sFF1 "Mono 9"
#define sFF2 "Mono 12"
#define sFF3 "Mono 18"
#define sFF4 "Mono 24"
#define sFF5 "Mono bold 9"
#define sFF6 "Mono bold 12"
#define sFF7 "Mono bold 18"
#define sFF8 "Mono bold 24"
#define sFF9 "Mono oblique 9"
#define sFF10 "Mono oblique 12"
#define sFF11 "Mono oblique 18"
#define sFF12 "Mono oblique 24"
#define sFF13 "Mono bold oblique 9"
#define sFF14 "Mono bold oblique 12"
#define sFF15 "Mono bold oblique 18"
#define sFF16 "Mono bold oblique 24" // Full text line is too big for 480 pixel wide screen
#define sFF17 "Sans 9"
#define sFF18 "Sans 12"
#define sFF19 "Sans 18"
#define sFF20 "Sans 24"
#define sFF21 "Sans bold 9"
#define sFF22 "Sans bold 12"
#define sFF23 "Sans bold 18"
#define sFF24 "Sans bold 24"
#define sFF25 "Sans oblique 9"
#define sFF26 "Sans oblique 12"
#define sFF27 "Sans oblique 18"
#define sFF28 "Sans oblique 24"
#define sFF29 "Sans bold oblique 9"
#define sFF30 "Sans bold oblique 12"
#define sFF31 "Sans bold oblique 18"
#define sFF32 "Sans bold oblique 24"
#define sFF33 "Serif 9"
#define sFF34 "Serif 12"
#define sFF35 "Serif 18"
#define sFF36 "Serif 24"
#define sFF37 "Serif italic 9"
#define sFF38 "Serif italic 12"
#define sFF39 "Serif italic 18"
#define sFF40 "Serif italic 24"
#define sFF41 "Serif bold 9"
#define sFF42 "Serif bold 12"
#define sFF43 "Serif bold 18"
#define sFF44 "Serif bold 24"
#define sFF45 "Serif bold italic 9"
#define sFF46 "Serif bold italic 12"
#define sFF47 "Serif bold italic 18"
#define sFF48 "Serif bold italic 24"
#else // LOAD_GFXFF not defined so setup defaults to prevent error messages
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Free fonts are not loaded in User_Setup.h so we must define all as font 1
// to prevent compile error messages
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define GFXFF 1
#define GLCD 1
#define FONT2 2
#define FONT4 4
#define FONT6 6
#define FONT7 7
#define FONT8 8
#define FF0 1
#define FF1 1
#define FF2 1
#define FF3 1
#define FF4 1
#define FF5 1
#define FF6 1
#define FF7 1
#define FF8 1
#define FF9 1
#define FF10 1
#define FF11 1
#define FF12 1
#define FF13 1
#define FF14 1
#define FF15 1
#define FF16 1
#define FF17 1
#define FF18 1
#define FF19 1
#define FF20 1
#define FF21 1
#define FF22 1
#define FF23 1
#define FF24 1
#define FF25 1
#define FF26 1
#define FF27 1
#define FF28 1
#define FF29 1
#define FF30 1
#define FF31 1
#define FF32 1
#define FF33 1
#define FF34 1
#define FF35 1
#define FF36 1
#define FF37 1
#define FF38 1
#define FF39 1
#define FF40 1
#define FF41 1
#define FF42 1
#define FF43 1
#define FF44 1
#define FF45 1
#define FF46 1
#define FF47 1
#define FF48 1
#define FM9 1
#define FM12 1
#define FM18 1
#define FM24 1
#define FMB9 1
#define FMB12 1
#define FMB18 1
#define FMB24 1
#define FMO9 1
#define FMO12 1
#define FMO18 1
#define FMO24 1
#define FMBO9 1
#define FMBO12 1
#define FMBO18 1
#define FMBO24 1
#define FSS9 1
#define FSS12 1
#define FSS18 1
#define FSS24 1
#define FSSB9 1
#define FSSB12 1
#define FSSB18 1
#define FSSB24 1
#define FSSO9 1
#define FSSO12 1
#define FSSO18 1
#define FSSO24 1
#define FSSBO9 1
#define FSSBO12 1
#define FSSBO18 1
#define FSSBO24 1
#define FS9 1
#define FS12 1
#define FS18 1
#define FS24 1
#define FSI9 1
#define FSI12 1
#define FSI19 1
#define FSI24 1
#define FSB9 1
#define FSB12 1
#define FSB18 1
#define FSB24 1
#define FSBI9 1
#define FSBI12 1
#define FSBI18 1
#define FSBI24 1
#endif // LOAD_GFXFF

View File

@@ -0,0 +1,328 @@
/*
This program provides cartesian type graph function
Revisions
rev date author description
1 12-24-2015 kasprzak initial creation
Updated by Bodmer to be an example for the library here:
https://github.com/Bodmer/TFT_eSPI
*/
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library with default width and height
#define LTBLUE 0xB6DF
#define LTTEAL 0xBF5F
#define LTGREEN 0xBFF7
#define LTCYAN 0xC7FF
#define LTRED 0xFD34
#define LTMAGENTA 0xFD5F
#define LTYELLOW 0xFFF8
#define LTORANGE 0xFE73
#define LTPINK 0xFDDF
#define LTPURPLE 0xCCFF
#define LTGREY 0xE71C
#define BLUE 0x001F
#define TEAL 0x0438
#define GREEN 0x07E0
#define CYAN 0x07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define ORANGE 0xFC00
#define PINK 0xF81F
#define PURPLE 0x8010
#define GREY 0xC618
#define WHITE 0xFFFF
#define BLACK 0x0000
#define DKBLUE 0x000D
#define DKTEAL 0x020C
#define DKGREEN 0x03E0
#define DKCYAN 0x03EF
#define DKRED 0x6000
#define DKMAGENTA 0x8008
#define DKYELLOW 0x8400
#define DKORANGE 0x8200
#define DKPINK 0x9009
#define DKPURPLE 0x4010
#define DKGREY 0x4A49
// these are the only external variables used by the graph function
// it's a flag to draw the coordinate system only on the first call to the Graph() function
// and will mimize flicker
// also create some variables to store the old x and y, if you draw 2 graphs on the same display
// you will need to store ox and oy per each display
boolean display1 = true;
boolean update1 = true;
double ox = -999, oy = -999; // Force them to be off screen
/*
function to draw a cartesian coordinate system and plot whatever data you want
just pass x and y and the graph will be drawn
huge arguement list
&d name of your display object
x = x data point
y = y datapont
gx = x graph location (lower left)
gy = y graph location (lower left)
w = width of graph
h = height of graph
xlo = lower bound of x axis
xhi = upper bound of x asis
xinc = division of x axis (distance not count)
ylo = lower bound of y axis
yhi = upper bound of y asis
yinc = division of y axis (distance not count)
title = title of graph
xlabel = x asis label
ylabel = y asis label
&redraw = flag to redraw graph on first call only
color = plotted trace colour
*/
void Graph(TFT_eSPI &tft, double x, double y, byte dp,
double gx, double gy, double w, double h,
double xlo, double xhi, double xinc,
double ylo, double yhi, double yinc,
char *title, char *xlabel, char *ylabel,
boolean &redraw, unsigned int color) {
double ydiv, xdiv;
double i;
double temp;
int rot, newrot;
// gcolor = graph grid colors
// acolor = axes line colors
// pcolor = color of your plotted data
// tcolor = text color
// bcolor = background color
unsigned int gcolor = DKBLUE;
unsigned int acolor = RED;
unsigned int pcolor = color;
unsigned int tcolor = WHITE;
unsigned int bcolor = BLACK;
if (redraw == true) {
redraw = false;
// initialize old x and old y in order to draw the first point of the graph
// but save the transformed value
// note my transform funcition is the same as the map function, except the map uses long and we need doubles
//ox = (x - xlo) * ( w) / (xhi - xlo) + gx;
//oy = (y - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
tft.setTextDatum(MR_DATUM);
// draw y scale
for ( i = ylo; i <= yhi; i += yinc) {
// compute the transform
temp = (i - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
if (i == 0) {
tft.drawLine(gx, temp, gx + w, temp, acolor);
tft.setTextColor(acolor, bcolor);
tft.drawString(xlabel, (int)(gx + w) , (int)temp, 2);
}
else {
tft.drawLine(gx, temp, gx + w, temp, gcolor);
}
// draw the axis labels
tft.setTextColor(tcolor, bcolor);
// precision is default Arduino--this could really use some format control
tft.drawFloat(i, dp, gx - 4, temp, 1);
}
// draw x scale
for (i = xlo; i <= xhi; i += xinc) {
// compute the transform
temp = (i - xlo) * ( w) / (xhi - xlo) + gx;
if (i == 0) {
tft.drawLine(temp, gy, temp, gy - h, acolor);
tft.setTextColor(acolor, bcolor);
tft.setTextDatum(BC_DATUM);
tft.drawString(ylabel, (int)temp, (int)(gy - h - 8) , 2);
}
else {
tft.drawLine(temp, gy, temp, gy - h, gcolor);
}
// draw the axis labels
tft.setTextColor(tcolor, bcolor);
tft.setTextDatum(TC_DATUM);
// precision is default Arduino--this could really use some format control
tft.drawFloat(i, dp, temp, gy + 7, 1);
}
//now draw the graph labels
tft.setTextColor(tcolor, bcolor);
tft.drawString(title, (int)(gx + w / 2) , (int)(gy - h - 30), 4);
}
// the coordinates are now drawn, plot the data
// the entire plotting code are these few lines...
// recall that ox and oy are initialized above
//x = (x - xlo) * ( w) / (xhi - xlo) + gx;
//y = (y - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
//tft.drawLine(ox, oy, x, y, pcolor);
// it's up to you but drawing 2 more lines to give the graph some thickness
//tft.drawLine(ox, oy + 1, x, y + 1, pcolor);
//tft.drawLine(ox, oy - 1, x, y - 1, pcolor);
//ox = x;
//oy = y;
}
void Trace(TFT_eSPI &tft, double x, double y, byte dp,
double gx, double gy,
double w, double h,
double xlo, double xhi, double xinc,
double ylo, double yhi, double yinc,
char *title, char *xlabel, char *ylabel,
boolean &update1, unsigned int color)
{
double ydiv, xdiv;
double i;
double temp;
int rot, newrot;
//unsigned int gcolor = DKBLUE; // gcolor = graph grid color
unsigned int acolor = RED; // acolor = main axes and label color
unsigned int pcolor = color; // pcolor = color of your plotted data
unsigned int tcolor = WHITE; // tcolor = text color
unsigned int bcolor = BLACK; // bcolor = background color
// initialize old x and old y in order to draw the first point of the graph
// but save the transformed value
// note my transform funcition is the same as the map function, except the map uses long and we need doubles
if (update1) {
update1 = false;
ox = (x - xlo) * ( w) / (xhi - xlo) + gx;
oy = (y - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
if ((ox < gx) || (ox > gx+w)) {update1 = true; return;}
if ((oy < gy-h) || (oy > gy)) {update1 = true; return;}
tft.setTextDatum(MR_DATUM);
// draw y scale
for ( i = ylo; i <= yhi; i += yinc) {
// compute the transform
temp = (i - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
if (i == 0) {
tft.setTextColor(acolor, bcolor);
tft.drawString(xlabel, (int)(gx + w) , (int)temp, 2);
}
// draw the axis labels
tft.setTextColor(tcolor, bcolor);
// precision is default Arduino--this could really use some format control
tft.drawFloat(i, dp, gx - 4, temp, 1);
}
// draw x scale
for (i = xlo; i <= xhi; i += xinc) {
// compute the transform
temp = (i - xlo) * ( w) / (xhi - xlo) + gx;
if (i == 0) {
tft.setTextColor(acolor, bcolor);
tft.setTextDatum(BC_DATUM);
tft.drawString(ylabel, (int)temp, (int)(gy - h - 8) , 2);
}
// draw the axis labels
tft.setTextColor(tcolor, bcolor);
tft.setTextDatum(TC_DATUM);
// precision is default Arduino--this could really use some format control
tft.drawFloat(i, dp, temp, gy + 7, 1);
}
//now draw the graph labels
tft.setTextColor(tcolor, bcolor);
tft.drawString(title, (int)(gx + w / 2) , (int)(gy - h - 30), 4);
}
// the coordinates are now drawn, plot the data
// the entire plotting code are these few lines...
// recall that ox and oy are initialized above
x = (x - xlo) * ( w) / (xhi - xlo) + gx;
y = (y - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
if ((x < gx) || (x > gx+w)) {update1 = true; return;}
if ((y < gy-h) || (y > gy)) {update1 = true; return;}
tft.drawLine(ox, oy, x, y, pcolor);
// it's up to you but drawing 2 more lines to give the graph some thickness
//tft.drawLine(ox, oy + 1, x, y + 1, pcolor);
//tft.drawLine(ox, oy - 1, x, y - 1, pcolor);
ox = x;
oy = y;
}
/*
End of graphing function
*/
void setup() {
double x, y;
tft.begin();
tft.fillScreen(BLACK);
tft.setRotation(1);
Graph(tft, x, y, 1, 60, 290, 390, 260, 0, 6.5, 1, -1, 1, .25, "", "", "", display1, YELLOW);
//delay(1000);
update1 = true;
for (x = 0; x <= 6.3; x += .1) {
y = sin(x);
Trace(tft, x, y, 1, 60, 290, 390, 260, 0, 6.5, 1, -1, 1, .25, "Sin(x)", "x", "fn(x)", update1, YELLOW);
}
delay(2000);
update1 = true;
for (x = 0; x <= 6.3; x += .1) {
y = cos(x);
Trace(tft, x, y, 1, 60, 290, 390, 260, 0, 6.5, 1, -1, 1, .25, "Sin(x) + Cos(x)", " x", "fn(x)", update1, TFT_PINK);
}
delay(2000);
update1 = true;
for (x = 0; x <= 6.3; x += .02) {
y = tan(x);
Trace(tft, x, y, 1, 60, 290, 390, 260, 0, 6.5, 1, -1, 1, .25, "Sin(x) + Cos(x) + Tan(x)", " x", "fn(x)", update1, CYAN);
}
}
void loop(void) {
}

View File

@@ -0,0 +1,151 @@
/*
Font draw speed and flicker test, draws all numbers 0-999 in each font
Average time in milliseconds to draw each character is shown in red
A total of 2890 characters are drawn in each font then the time per
character printed on screen
#########################################################################
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
#########################################################################
*/
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
unsigned long drawTime = 0;
void setup(void) {
tft.begin();
tft.setRotation(1);
}
void loop() {
int xpos;
//Measure time to clear screen
//drawTime = millis();
tft.fillScreen(TFT_BLACK);
//drawTime = millis() - drawTime;
tft.setTextColor(TFT_WHITE, TFT_BLACK);
//tft.drawNumber(drawTime, 10, 100, 4);
//delay(1000);
drawTime = millis();
// Print all numbers from 0 to 999 in font 1 and calculate character draw time
for (int i = 0; i < 1000; i++) {
yield(); tft.drawNumber(i, 100, 80, 1);
}
drawTime = millis() - drawTime;
tft.setTextColor(TFT_RED, TFT_BLACK);
xpos = 50;
xpos += tft.drawFloat(drawTime / 2890.0, 3, xpos, 180, 4);
tft.drawString("ms per character", xpos, 180, 4);
if (drawTime < 100) tft.drawString("Font 1 not loaded!", 50, 210, 4);
delay(4000);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
drawTime = millis();
// Print all numbers from 0 to 999 in font 2 and calculate character draw time
for (int i = 0; i < 1000; i++) {
yield(); tft.drawNumber(i, 100, 80, 2);
}
drawTime = millis() - drawTime;
tft.setTextColor(TFT_RED, TFT_BLACK);
xpos = 50;
xpos += tft.drawFloat(drawTime / 2890.0, 3, xpos, 180, 4);
tft.drawString("ms per character", xpos, 180, 4);
if (drawTime < 200) tft.drawString("Font 2 not loaded!", 50, 210, 4);
delay(4000);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
drawTime = millis();
// Print all numbers from 0 to 999 in font 4 and calculate character draw time
for (int i = 0; i < 1000; i++) {
yield(); tft.drawNumber(i, 100, 80, 4);
}
drawTime = millis() - drawTime;
tft.setTextColor(TFT_RED, TFT_BLACK);
xpos = 50;
xpos += tft.drawFloat(drawTime / 2890.0, 3, xpos, 180, 4);
tft.drawString("ms per character", xpos, 180, 4);
if (drawTime < 200) tft.drawString("Font 4 not loaded!", 50, 210, 4);
delay(4000);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
drawTime = millis();
// Print all numbers from 0 to 999 in font 6 and calculate character draw time
for (int i = 0; i < 1000; i++) {
yield(); tft.drawNumber(i, 100, 80, 6);
}
drawTime = millis() - drawTime;
tft.setTextColor(TFT_RED, TFT_BLACK);
xpos = 50;
xpos += tft.drawFloat(drawTime / 2890.0, 3, xpos, 180, 4);
tft.drawString("ms per character", xpos, 180, 4);
if (drawTime < 200) tft.drawString("Font 6 not loaded!", 50, 210, 4);
delay(4000);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
drawTime = millis();
// Print all numbers from 0 to 999 in font 7 and calculate character draw time
for (int i = 0; i < 1000; i++) {
yield(); tft.drawNumber(i, 100, 80, 7);
}
drawTime = millis() - drawTime;
tft.setTextColor(TFT_RED, TFT_BLACK);
xpos = 50;
xpos += tft.drawFloat(drawTime / 2890.0, 3, xpos, 180, 4);
tft.drawString("ms per character", xpos, 180, 4);
if (drawTime < 200) tft.drawString("Font 7 not loaded!", 50, 210, 4);
delay(4000);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
drawTime = millis();
// Print all numbers from 0 to 999 in font 8 and calculate character draw time
for (int i = 0; i < 1000; i++) {
yield(); tft.drawNumber(i, 100, 80, 8);
}
drawTime = millis() - drawTime;
tft.setTextColor(TFT_RED, TFT_BLACK);
xpos = 50;
xpos += tft.drawFloat(drawTime / 2890.0, 3, xpos, 180, 4);
tft.drawString("ms per character", xpos, 180, 4);
if (drawTime < 200) tft.drawString("Font 8 not loaded!", 50, 210, 4);
delay(4000);
}

View File

@@ -0,0 +1,51 @@
/*
Ellipse drawing example
This sketch does not use any fonts.
*/
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
void setup(void) {
tft.init();
tft.setRotation(1);
}
void loop() {
tft.fillScreen(TFT_BLACK);
// Draw some random circles
for (int i = 0; i < 40; i++)
{
int rx = random(60);
int ry = random(60);
int x = rx + random(480 - rx - rx);
int y = ry + random(320 - ry - ry);
tft.fillEllipse(x, y, rx, ry, random(0xFFFF));
}
delay(2000);
tft.fillScreen(TFT_BLACK);
for (int i = 0; i < 40; i++)
{
int rx = random(60);
int ry = random(60);
int x = rx + random(480 - rx - rx);
int y = ry + random(320 - ry - ry);
tft.drawEllipse(x, y, rx, ry, random(0xFFFF));
}
delay(2000);
}

View File

@@ -0,0 +1,214 @@
/*
An example analogue meter using a HX8357 TFT LCD screen
Needs Font 2 (also Font 4 if using large scale label)
Make sure all the required fonts are loaded by editting the
User_Setup.h file in the TFT_HX8357_Due library folder.
#########################################################################
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
###### TO SELECT THE FONTS AND PINS YOU USE, SEE ABOVE ######
#########################################################################
Updated by Bodmer for variable meter size
*/
// Define meter size as multiplier of 240 pixels wide 1.0 and 1.3333 work OK
#define M_SIZE 1.3333
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
#define TFT_GREY 0x5AEB
float ltx = 0; // Saved x coord of bottom of needle
uint16_t osx = M_SIZE*120, osy = M_SIZE*120; // Saved x & y coords
uint32_t updateTime = 0; // time for next update
int old_analog = -999; // Value last displayed
int value[6] = {0, 0, 0, 0, 0, 0};
int old_value[6] = { -1, -1, -1, -1, -1, -1};
int d = 0;
void setup(void) {
tft.init();
tft.setRotation(1);
Serial.begin(57600); // For debug
tft.fillScreen(TFT_BLACK);
analogMeter(); // Draw analogue meter
updateTime = millis(); // Next update time
}
void loop() {
if (updateTime <= millis()) {
updateTime = millis() + 35; // Update emter every 35 milliseconds
// Create a Sine wave for testing
d += 4; if (d >= 360) d = 0;
value[0] = 50 + 50 * sin((d + 0) * 0.0174532925);
plotNeedle(value[0], 0); // It takes between 2 and 12ms to replot the needle with zero delay
}
}
// #########################################################################
// Draw the analogue meter on the screen
// #########################################################################
void analogMeter()
{
// Meter outline
tft.fillRect(0, 0, M_SIZE*239, M_SIZE*126, TFT_GREY);
tft.fillRect(5, 3, M_SIZE*230, M_SIZE*119, TFT_WHITE);
tft.setTextColor(TFT_BLACK); // Text colour
// Draw ticks every 5 degrees from -50 to +50 degrees (100 deg. FSD swing)
for (int i = -50; i < 51; i += 5) {
// Long scale tick length
int tl = 15;
// Coodinates of tick to draw
float sx = cos((i - 90) * 0.0174532925);
float sy = sin((i - 90) * 0.0174532925);
uint16_t x0 = sx * (M_SIZE*100 + tl) + M_SIZE*120;
uint16_t y0 = sy * (M_SIZE*100 + tl) + M_SIZE*140;
uint16_t x1 = sx * M_SIZE*100 + M_SIZE*120;
uint16_t y1 = sy * M_SIZE*100 + M_SIZE*140;
// Coordinates of next tick for zone fill
float sx2 = cos((i + 5 - 90) * 0.0174532925);
float sy2 = sin((i + 5 - 90) * 0.0174532925);
int x2 = sx2 * (M_SIZE*100 + tl) + M_SIZE*120;
int y2 = sy2 * (M_SIZE*100 + tl) + M_SIZE*140;
int x3 = sx2 * M_SIZE*100 + M_SIZE*120;
int y3 = sy2 * M_SIZE*100 + M_SIZE*140;
// Yellow zone limits
//if (i >= -50 && i < 0) {
// tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_YELLOW);
// tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_YELLOW);
//}
// Green zone limits
if (i >= 0 && i < 25) {
tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_GREEN);
tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_GREEN);
}
// Orange zone limits
if (i >= 25 && i < 50) {
tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_ORANGE);
tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_ORANGE);
}
// Short scale tick length
if (i % 25 != 0) tl = 8;
// Recalculate coords incase tick lenght changed
x0 = sx * (M_SIZE*100 + tl) + M_SIZE*120;
y0 = sy * (M_SIZE*100 + tl) + M_SIZE*140;
x1 = sx * M_SIZE*100 + M_SIZE*120;
y1 = sy * M_SIZE*100 + M_SIZE*140;
// Draw tick
tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
// Check if labels should be drawn, with position tweaks
if (i % 25 == 0) {
// Calculate label positions
x0 = sx * (M_SIZE*100 + tl + 10) + M_SIZE*120;
y0 = sy * (M_SIZE*100 + tl + 10) + M_SIZE*140;
switch (i / 25) {
case -2: tft.drawCentreString("0", x0, y0 - 12, 2); break;
case -1: tft.drawCentreString("25", x0, y0 - 9, 2); break;
case 0: tft.drawCentreString("50", x0, y0 - 7, 2); break;
case 1: tft.drawCentreString("75", x0, y0 - 9, 2); break;
case 2: tft.drawCentreString("100", x0, y0 - 12, 2); break;
}
}
// Now draw the arc of the scale
sx = cos((i + 5 - 90) * 0.0174532925);
sy = sin((i + 5 - 90) * 0.0174532925);
x0 = sx * M_SIZE*100 + M_SIZE*120;
y0 = sy * M_SIZE*100 + M_SIZE*140;
// Draw scale arc, don't draw the last part
if (i < 50) tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
}
tft.drawString("%RH", M_SIZE*(5 + 230 - 40), M_SIZE*(119 - 20), 2); // Units at bottom right
tft.drawCentreString("%RH", M_SIZE*120, M_SIZE*70, 4); // Comment out to avoid font 4
tft.drawRect(5, 3, M_SIZE*230, M_SIZE*119, TFT_BLACK); // Draw bezel line
plotNeedle(0, 0); // Put meter needle at 0
}
// #########################################################################
// Update needle position
// This function is blocking while needle moves, time depends on ms_delay
// 10ms minimises needle flicker if text is drawn within needle sweep area
// Smaller values OK if text not in sweep area, zero for instant movement but
// does not look realistic... (note: 100 increments for full scale deflection)
// #########################################################################
void plotNeedle(int value, byte ms_delay)
{
tft.setTextColor(TFT_BLACK, TFT_WHITE);
char buf[8]; dtostrf(value, 4, 0, buf);
tft.drawRightString(buf, M_SIZE*40, M_SIZE*(119 - 20), 2);
if (value < -10) value = -10; // Limit value to emulate needle end stops
if (value > 110) value = 110;
// Move the needle until new value reached
while (!(value == old_analog)) {
if (old_analog < value) old_analog++;
else old_analog--;
if (ms_delay == 0) old_analog = value; // Update immediately if delay is 0
float sdeg = map(old_analog, -10, 110, -150, -30); // Map value to angle
// Calcualte tip of needle coords
float sx = cos(sdeg * 0.0174532925);
float sy = sin(sdeg * 0.0174532925);
// Calculate x delta of needle start (does not start at pivot point)
float tx = tan((sdeg + 90) * 0.0174532925);
// Erase old needle image
tft.drawLine(M_SIZE*(120 + 20 * ltx - 1), M_SIZE*(140 - 20), osx - 1, osy, TFT_WHITE);
tft.drawLine(M_SIZE*(120 + 20 * ltx), M_SIZE*(140 - 20), osx, osy, TFT_WHITE);
tft.drawLine(M_SIZE*(120 + 20 * ltx + 1), M_SIZE*(140 - 20), osx + 1, osy, TFT_WHITE);
// Re-plot text under needle
tft.setTextColor(TFT_BLACK);
tft.drawCentreString("%RH", M_SIZE*120, M_SIZE*70, 4); // // Comment out to avoid font 4
// Store new needle end coords for next erase
ltx = tx;
osx = M_SIZE*(sx * 98 + 120);
osy = M_SIZE*(sy * 98 + 140);
// Draw the needle in the new postion, magenta makes needle a bit bolder
// draws 3 lines to thicken needle
tft.drawLine(M_SIZE*(120 + 20 * ltx - 1), M_SIZE*(140 - 20), osx - 1, osy, TFT_RED);
tft.drawLine(M_SIZE*(120 + 20 * ltx), M_SIZE*(140 - 20), osx, osy, TFT_MAGENTA);
tft.drawLine(M_SIZE*(120 + 20 * ltx + 1), M_SIZE*(140 - 20), osx + 1, osy, TFT_RED);
// Slow needle down slightly as it approaches new postion
if (abs(old_analog - value) < 10) ms_delay += ms_delay / 5;
// Wait before next update
delay(ms_delay);
}
}

View File

@@ -0,0 +1,299 @@
/*
Example animated analogue meters using a TFT LCD screen
Originanally written for a 320 x 240 display, so only occupies half
of a 480 x 320 display.
Needs Font 2 (also Font 4 if using large centered scale label)
#########################################################################
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
#########################################################################
*/
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
#define TFT_GREY 0x5AEB
float ltx = 0; // Saved x coord of bottom of needle
uint16_t osx = 120, osy = 120; // Saved x & y coords
uint32_t updateTime = 0; // time for next update
int old_analog = -999; // Value last displayed
int old_digital = -999; // Value last displayed
int value[6] = {0, 0, 0, 0, 0, 0};
int old_value[6] = { -1, -1, -1, -1, -1, -1};
int d = 0;
void setup(void) {
tft.init();
tft.setRotation(1);
Serial.begin(57600); // For debug
tft.fillScreen(TFT_BLACK);
analogMeter(); // Draw analogue meter
// Draw 6 linear meters
byte d = 40;
plotLinear("A0", 0, 160);
plotLinear("A1", 1 * d, 160);
plotLinear("A2", 2 * d, 160);
plotLinear("A3", 3 * d, 160);
plotLinear("A4", 4 * d, 160);
plotLinear("A5", 5 * d, 160);
updateTime = millis(); // Next update time
}
void loop() {
if (updateTime <= millis()) {
updateTime = millis() + 25; // Delay to limit speed of update
d += 4; if (d >= 360) d = 0;
//value[0] = map(analogRead(A0), 0, 1023, 0, 100); // Test with value form Analogue 0
//value[1] = map(analogRead(A1), 0, 1023, 0, 100); // Test with value form Analogue 1
//value[2] = map(analogRead(A2), 0, 1023, 0, 100); // Test with value form Analogue 2
//value[3] = map(analogRead(A3), 0, 1023, 0, 100); // Test with value form Analogue 3
//value[4] = map(analogRead(A4), 0, 1023, 0, 100); // Test with value form Analogue 4
//value[5] = map(analogRead(A5), 0, 1023, 0, 100); // Test with value form Analogue 5
// Create a Sine wave for testing
value[0] = 50 + 50 * sin((d + 0) * 0.0174532925);
value[1] = 50 + 50 * sin((d + 60) * 0.0174532925);
value[2] = 50 + 50 * sin((d + 120) * 0.0174532925);
value[3] = 50 + 50 * sin((d + 180) * 0.0174532925);
value[4] = 50 + 50 * sin((d + 240) * 0.0174532925);
value[5] = 50 + 50 * sin((d + 300) * 0.0174532925);
//unsigned long t = millis();
plotPointer(); // It takes aout 3.5ms to plot each gauge for a 1 pixel move, 21ms for 6 gauges
plotNeedle(value[0], 0); // It takes between 2 and 12ms to replot the needle with zero delay
//Serial.println(millis()-t); // Print time taken for meter update
}
}
// #########################################################################
// Draw the analogue meter on the screen
// #########################################################################
void analogMeter()
{
// Meter outline
tft.fillRect(0, 0, 239, 126, TFT_GREY);
tft.fillRect(5, 3, 230, 119, TFT_WHITE);
tft.setTextColor(TFT_BLACK); // Text colour
// Draw ticks every 5 degrees from -50 to +50 degrees (100 deg. FSD swing)
for (int i = -50; i < 51; i += 5) {
// Long scale tick length
int tl = 15;
// Coodinates of tick to draw
float sx = cos((i - 90) * 0.0174532925);
float sy = sin((i - 90) * 0.0174532925);
uint16_t x0 = sx * (100 + tl) + 120;
uint16_t y0 = sy * (100 + tl) + 140;
uint16_t x1 = sx * 100 + 120;
uint16_t y1 = sy * 100 + 140;
// Coordinates of next tick for zone fill
float sx2 = cos((i + 5 - 90) * 0.0174532925);
float sy2 = sin((i + 5 - 90) * 0.0174532925);
int x2 = sx2 * (100 + tl) + 120;
int y2 = sy2 * (100 + tl) + 140;
int x3 = sx2 * 100 + 120;
int y3 = sy2 * 100 + 140;
// Yellow zone limits
//if (i >= -50 && i < 0) {
// tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_YELLOW);
// tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_YELLOW);
//}
// Green zone limits
if (i >= 0 && i < 25) {
tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_GREEN);
tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_GREEN);
}
// Orange zone limits
if (i >= 25 && i < 50) {
tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_ORANGE);
tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_ORANGE);
}
// Short scale tick length
if (i % 25 != 0) tl = 8;
// Recalculate coords incase tick lenght changed
x0 = sx * (100 + tl) + 120;
y0 = sy * (100 + tl) + 140;
x1 = sx * 100 + 120;
y1 = sy * 100 + 140;
// Draw tick
tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
// Check if labels should be drawn, with position tweaks
if (i % 25 == 0) {
// Calculate label positions
x0 = sx * (100 + tl + 10) + 120;
y0 = sy * (100 + tl + 10) + 140;
switch (i / 25) {
case -2: tft.drawCentreString("0", x0, y0 - 12, 2); break;
case -1: tft.drawCentreString("25", x0, y0 - 9, 2); break;
case 0: tft.drawCentreString("50", x0, y0 - 6, 2); break;
case 1: tft.drawCentreString("75", x0, y0 - 9, 2); break;
case 2: tft.drawCentreString("100", x0, y0 - 12, 2); break;
}
}
// Now draw the arc of the scale
sx = cos((i + 5 - 90) * 0.0174532925);
sy = sin((i + 5 - 90) * 0.0174532925);
x0 = sx * 100 + 120;
y0 = sy * 100 + 140;
// Draw scale arc, don't draw the last part
if (i < 50) tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
}
tft.drawString("%RH", 5 + 230 - 40, 119 - 20, 2); // Units at bottom right
tft.drawCentreString("%RH", 120, 70, 4); // Comment out to avoid font 4
tft.drawRect(5, 3, 230, 119, TFT_BLACK); // Draw bezel line
plotNeedle(0, 0); // Put meter needle at 0
}
// #########################################################################
// Update needle position
// This function is blocking while needle moves, time depends on ms_delay
// 10ms minimises needle flicker if text is drawn within needle sweep area
// Smaller values OK if text not in sweep area, zero for instant movement but
// does not look realistic... (note: 100 increments for full scale deflection)
// #########################################################################
void plotNeedle(int value, byte ms_delay)
{
tft.setTextColor(TFT_BLACK, TFT_WHITE);
char buf[8]; dtostrf(value, 4, 0, buf);
tft.drawRightString(buf, 40, 119 - 20, 2);
if (value < -10) value = -10; // Limit value to emulate needle end stops
if (value > 110) value = 110;
// Move the needle util new value reached
while (!(value == old_analog)) {
if (old_analog < value) old_analog++;
else old_analog--;
if (ms_delay == 0) old_analog = value; // Update immediately id delay is 0
float sdeg = map(old_analog, -10, 110, -150, -30); // Map value to angle
// Calcualte tip of needle coords
float sx = cos(sdeg * 0.0174532925);
float sy = sin(sdeg * 0.0174532925);
// Calculate x delta of needle start (does not start at pivot point)
float tx = tan((sdeg + 90) * 0.0174532925);
// Erase old needle image
tft.drawLine(120 + 20 * ltx - 1, 140 - 20, osx - 1, osy, TFT_WHITE);
tft.drawLine(120 + 20 * ltx, 140 - 20, osx, osy, TFT_WHITE);
tft.drawLine(120 + 20 * ltx + 1, 140 - 20, osx + 1, osy, TFT_WHITE);
// Re-plot text under needle
tft.setTextColor(TFT_BLACK);
tft.drawCentreString("%RH", 120, 70, 4); // // Comment out to avoid font 4
// Store new needle end coords for next erase
ltx = tx;
osx = sx * 98 + 120;
osy = sy * 98 + 140;
// Draw the needle in the new postion, magenta makes needle a bit bolder
// draws 3 lines to thicken needle
tft.drawLine(120 + 20 * ltx - 1, 140 - 20, osx - 1, osy, TFT_RED);
tft.drawLine(120 + 20 * ltx, 140 - 20, osx, osy, TFT_MAGENTA);
tft.drawLine(120 + 20 * ltx + 1, 140 - 20, osx + 1, osy, TFT_RED);
// Slow needle down slightly as it approaches new postion
if (abs(old_analog - value) < 10) ms_delay += ms_delay / 5;
// Wait before next update
delay(ms_delay);
}
}
// #########################################################################
// Draw a linear meter on the screen
// #########################################################################
void plotLinear(char *label, int x, int y)
{
int w = 36;
tft.drawRect(x, y, w, 155, TFT_GREY);
tft.fillRect(x+2, y + 19, w-3, 155 - 38, TFT_WHITE);
tft.setTextColor(TFT_CYAN, TFT_BLACK);
tft.drawCentreString(label, x + w / 2, y + 2, 2);
for (int i = 0; i < 110; i += 10)
{
tft.drawFastHLine(x + 20, y + 27 + i, 6, TFT_BLACK);
}
for (int i = 0; i < 110; i += 50)
{
tft.drawFastHLine(x + 20, y + 27 + i, 9, TFT_BLACK);
}
tft.fillTriangle(x+3, y + 127, x+3+16, y+127, x + 3, y + 127 - 5, TFT_RED);
tft.fillTriangle(x+3, y + 127, x+3+16, y+127, x + 3, y + 127 + 5, TFT_RED);
tft.drawCentreString("---", x + w / 2, y + 155 - 18, 2);
}
// #########################################################################
// Adjust 6 linear meter pointer positions
// #########################################################################
void plotPointer(void)
{
int dy = 187;
byte pw = 16;
tft.setTextColor(TFT_GREEN, TFT_BLACK);
// Move the 6 pointers one pixel towards new value
for (int i = 0; i < 6; i++)
{
char buf[8]; dtostrf(value[i], 4, 0, buf);
tft.drawRightString(buf, i * 40 + 36 - 5, 187 - 27 + 155 - 18, 2);
int dx = 3 + 40 * i;
if (value[i] < 0) value[i] = 0; // Limit value to emulate needle end stops
if (value[i] > 100) value[i] = 100;
while (!(value[i] == old_value[i])) {
dy = 187 + 100 - old_value[i];
if (old_value[i] > value[i])
{
tft.drawLine(dx, dy - 5, dx + pw, dy, TFT_WHITE);
old_value[i]--;
tft.drawLine(dx, dy + 6, dx + pw, dy + 1, TFT_RED);
}
else
{
tft.drawLine(dx, dy + 5, dx + pw, dy, TFT_WHITE);
old_value[i]++;
tft.drawLine(dx, dy - 6, dx + pw, dy - 1, TFT_RED);
}
}
}
}

View File

@@ -0,0 +1,208 @@
/*
Example to show how text padding and setting the datum works.
Drawing a numbers at a location can leave the remains of previous numbers.
for example drawing 999 then 17 may display as:
179 for left datum
or
917 for right datum.
By setting the correct text padding width and setting a background colour then
the plotted numbers will overprint old values. The padding width must be set
to be large enough to cover the old text.
This sketch shows drawing numbers and text both with and without padding.
Unpadded text and numbers plot in red.
Padded text and numbers plot in green.
Padding works with all plotting datums set by setTextDatum()
The height of the padded area is set automatically by the font used.
#########################################################################
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
#########################################################################
*/
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
unsigned long drawTime = 0;
void setup(void) {
tft.begin();
tft.setRotation(1);
}
void loop() {
int x = 240;
int y = 60;
byte decimal_places = 1;
byte font = 8;
tft.fillScreen(TFT_BLACK);
header("Right datum padding demo");
tft.setTextColor(TFT_RED, TFT_BLUE);
tft.setTextDatum(TR_DATUM); // Top Right is datum, so decimal point stays in same place
// any datum could be used
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// The value on screen will be wrong as not all digits are over-printed
tft.setTextPadding(0); // Setting to zero switches off padding
// Print all numbers from 49.9 to 0.0 in font 8 to show the problem
for (int i = 199; i >= 0; i--) {
yield(); tft.drawFloat(i/10.0, decimal_places, x, y, font);
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Now set padding width to be 3 digits plus decimal point wide in font 8
// Padding height is set automatically, all numeric digits are the same width
// in fonts 1 to 8. The value on screen will now be correct as all digits are over-printed
int padding = tft.textWidth("99.9", font); // get the width of the text in pixels
tft.setTextColor(TFT_GREEN, TFT_BLUE);
tft.setTextPadding(padding);
for (int i = 199; i >= 0; i--) {
yield(); tft.drawFloat(i/10.0, decimal_places, x, y + 140, font); // Use 1 decimal place
}
delay(5000);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Now use integers
// The value on screen will be wrong as not all digits are over-printed
tft.fillScreen(TFT_BLACK);
header("Left datum padding demo");
tft.setTextColor(TFT_RED, TFT_BLUE);
tft.setTextDatum(TL_DATUM); // Top Left is datum
// any datum could be used
tft.setTextPadding(0); // Setting to zero switches off padding
// Print all numbers from 49.9 to 0.0 in font 8 to show the problem
for (int i = 199; i >= 0; i--) {
yield(); tft.drawNumber(i, x, y, font);
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Now set padding width to be 3 digits wide in font 8
// Padding height is set automatically, all numeric digits are the same width
// in fonts 1 to 8
// The value on screen will now be correct as all digits are over-printed
padding = tft.textWidth("999", font); // get the width of the text in pixels
tft.setTextColor(TFT_GREEN, TFT_BLUE);
tft.setTextPadding(padding);
for (int i = 199; i >= 0; i--) {
yield(); tft.drawNumber(i, x, y + 140, font); // Use 1 decimal place
}
delay(5000);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Now use integers with a centred datum
// The value on screen will be wrong as not all digits are over-printed
tft.fillScreen(TFT_BLACK);
header("Centre datum padding demo");
tft.setTextColor(TFT_RED, TFT_BLUE);
tft.setTextDatum(TC_DATUM); // Top Centre is datum
// any datum could be used
tft.setTextPadding(0); // Setting to zero switches off padding
// Print all numbers from 49.9 to 0.0 in font 8 to show the problem
for (int i = 199; i >= 0; i--) {
yield(); tft.drawNumber(i, x, y, font);
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Now set padding width to be 3 digits wide in font 8
// Padding height is set automatically, all numeric digits are the same width
// in fonts 1 to 8
// The value on screen will now be correct as all digits are over-printed
padding = tft.textWidth("999", font); // get the width of the text in pixels
tft.setTextColor(TFT_GREEN, TFT_BLUE);
tft.setTextPadding(padding);
for (int i = 199; i >= 0; i--) {
yield(); tft.drawNumber(i, x, y + 140, font); // Use 1 decimal place
}
delay(5000);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Now use text over-printing by setting the padding value
// Previous text is not wiped by a shorter string
tft.fillScreen(TFT_LIGHTGREY);
header("Centred datum text padding demo");
tft.setTextSize(2); // Any text size muliplier will work
tft.setTextColor(TFT_RED, TFT_BLUE);
tft.setTextDatum(TC_DATUM); // Top Centre is datum
// any datum could be used
tft.setTextPadding(0); // Setting to zero switches off padding
tft.drawString("Quick brown", x, y, 4);
delay(2000);
tft.drawString("fox", x, y, 4);
delay(2000);
// Now set padding width to longest string
// Previous text will automatically be wiped by a shorter string!
font = 4;
padding = tft.textWidth("Quick brown", font); // get the width of the widest text in pixels
// could set this to any number up to screen width
tft.setTextPadding(padding);
tft.setTextColor(TFT_GREEN, TFT_BLUE);
tft.drawString("Quick brown", x, y+80, font);
delay(2000);
tft.drawString("fox", x, y+80, font);
delay(5000);
}
// Print the header for a display screen
void header(const char *string)
{
tft.setTextSize(1);
tft.setTextColor(TFT_MAGENTA, TFT_BLACK);
tft.setTextDatum(TC_DATUM);
tft.drawString(string, 240, 10, 4);
}

View File

@@ -0,0 +1,77 @@
/*
Test the tft.print() viz the libraries embedded write() function
This sketch used font 2, 4, 7
Make sure all the required fonts are loaded by editting 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 <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
#define TFT_GREY 0x5AEB // New colour
void setup(void) {
tft.init();
tft.setRotation(2);
}
void loop() {
// Fill screen with random colour so we can see the effect of printing with and without
// a background colour defined
tft.fillScreen(random(0xFFFF));
// Set "cursor" at top left corner of display (0,0) and select font 2
// (cursor will move to next line automatically during printing with 'tft.println'
// or stay on the line is there is room for the text with tft.print)
tft.setCursor(0, 0, 2);
// Set the font colour to be white with a black background, set text size multiplier to 1
tft.setTextColor(TFT_WHITE,TFT_BLACK); tft.setTextSize(1);
// We can now plot text on screen using the "print" class
tft.println("Hello World!");
// Set the font colour to be yellow with no background, set to font 7
tft.setTextColor(TFT_YELLOW); tft.setTextFont(7);
tft.println(1234.56);
// Set the font colour to be red with black background, set to font 4
tft.setTextColor(TFT_RED,TFT_BLACK); tft.setTextFont(4);
tft.println((long)3735928559, HEX); // Should print DEADBEEF
// Set the font colour to be green with black background, set to font 4
tft.setTextColor(TFT_GREEN,TFT_BLACK);
tft.setTextFont(4);
tft.println("Groop");
tft.println("I implore thee,");
// Change to font 2
tft.setTextFont(2);
tft.println(F("my foonting turlingdromes.")); // Can store strings in FLASH to save RAM
tft.println("And hooptiously drangle me");
tft.println("with crinkly bindlewurdles,");
// This next line is deliberately made too long for the display width to test
// automatic text wrapping onto the next line
tft.println("Or I will rend thee in the gobberwarts with my blurglecruncheon, see if I don't!");
// Test some print formatting functions
float fnumber = 123.45;
// Set the font colour to be blue with no background, set to font 4
tft.setTextColor(TFT_BLUE); tft.setTextFont(4);
tft.print("Float = "); tft.println(fnumber); // Print floating point number
tft.print("Binary = "); tft.println((int)fnumber, BIN); // Print as integer value in binary
tft.print("Hexadecimal = "); tft.println((int)fnumber, HEX); // Print as integer number in Hexadecimal
delay(10000);
}

View File

@@ -0,0 +1,158 @@
/*
An example showing rainbow colours on a 3.0 or 3.2" TFT LCD screen
and to show basic examples of font use.
This sketch uses the GLCD, 2, 4, 6 fonts only.
Make sure all the required fonts are loaded by editting the
User_Setup.h file in the TFT_eSPI library folder.
#########################################################################
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
###### TO SELECT THE FONTS AND PINS YOU USE ######
#########################################################################
*/
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
unsigned long targetTime = 0;
byte red = 31;
byte green = 0;
byte blue = 0;
byte state = 0;
unsigned int colour = red << 11; // Colour order is RGB 5+6+5 bits each
void setup(void) {
tft.init();
tft.setRotation(2);
tft.fillScreen(TFT_BLACK);
targetTime = millis() + 1000;
}
void loop() {
if (targetTime < millis()) {
targetTime = millis() + 10000;
rainbow_fill(); // Fill the screen with rainbow colours
// The standard AdaFruit font still works as before
tft.setTextColor(TFT_BLACK); // Background is not defined so it is transparent
tft.setCursor (100, 5);
tft.setTextFont(1); // Select font 1 which is the Adafruit GLCD font
tft.print("Original Adafruit font!");
// The new larger fonts do not need to use the .setCursor call, coords are embedded
tft.setTextColor(TFT_BLACK); // Do not plot the background colour
// Overlay the black text on top of the rainbow plot (the advantage of not drawing the backgorund colour!)
tft.drawCentreString("Font size 2", 160, 14, 2); // Draw text centre at position 120, 14 using font 2
tft.drawCentreString("Font size 4", 160, 30, 4); // Draw text centre at position 120, 30 using font 4
tft.drawCentreString("12.34", 160, 54, 6); // Draw text centre at position 120, 54 using font 6
tft.drawCentreString("12.34 is in font 6", 160, 92, 2); // Draw text centre at position 120, 92 using font 2
// Note the x, y position is the top left corner of the first character printed!
// draw a floating point number
float pi = 3.14159; // Value to print
int precision = 3; // Number of digits after decimal point
int xpos = 130; // x position
int ypos = 110; // y position
int font = 2; // font number 2
xpos += tft.drawFloat(pi, precision, xpos, ypos, font); // Draw rounded number and return new xpos delta for next print position
tft.drawString(" is pi", xpos, ypos, font); // Continue printing from new x position
tft.setTextSize(1); // We are using a text size multiplier of 1
tft.setTextColor(TFT_BLACK); // Set text colour to black, no background (so transparent)
tft.setCursor(76, 150, 4); // Set cursor to x = 76, y = 150 and use font 4
tft.println("Transparent..."); // As we use println, the cursor moves to the next line
tft.setCursor(70, 175); // Set cursor to x = 70, y = 175
tft.setTextColor(TFT_WHITE, TFT_BLACK); // Set text colour to white and background to black
tft.println("White on black");
tft.setTextFont(4); // Select font 4 without moving cursor
tft.setCursor(00, 210); // Set cursor to x = 90, y = 210 without changing the font
tft.setTextColor(TFT_WHITE);
// By using the print class we can use all the formatting features like printing HEX
tft.print(57005, HEX); // Cursor does no move to next line
tft.println(48879, HEX); // print and move cursor to next line
tft.setTextColor(TFT_GREEN, TFT_BLACK); // This time we will use green text on a black background
tft.setTextFont(2); // Select font 2
//Text will wrap to the next line if needed, by luck it breaks the lines at a space..
tft.println(" Ode to a Small Lump of Green Putty I Found in My Armpit One Midsummer Morning ");
tft.drawCentreString("34.56", 160, 300, 7); // Draw text centre at position 120, 54 using font 6
tft.drawCentreString("34.56 is in font 7", 160, 350, 2); // Draw text centre at position 120, 92 using font 2
tft.drawCentreString("78.90", 160, 370, 8); // Draw text centre at position 120, 54 using font 6
tft.drawCentreString("78.90 is in font 8", 160, 450, 2); // Draw text centre at position 120, 92 using font 2
}
}
// Fill screen with a rainbow pattern
void rainbow_fill()
{
// The colours and state are not initialised so the start colour changes each time the funtion is called
for (int i = 479; i > 0; i--) {
// Draw a vertical line 1 pixel wide in the selected colour
tft.drawFastHLine(0, i, tft.width(), colour); // in this example tft.width() returns the pixel width of the display
// This is a "state machine" that ramps up/down the colour brightnesses in sequence
switch (state) {
case 0:
green ++;
if (green == 64) {
green = 63;
state = 1;
}
break;
case 1:
red--;
if (red == 255) {
red = 0;
state = 2;
}
break;
case 2:
blue ++;
if (blue == 32) {
blue = 31;
state = 3;
}
break;
case 3:
green --;
if (green == 255) {
green = 0;
state = 4;
}
break;
case 4:
red ++;
if (red == 32) {
red = 31;
state = 5;
}
break;
case 5:
blue --;
if (blue == 255) {
blue = 0;
state = 0;
}
break;
}
colour = red << 11 | green << 5 | blue;
}
}

View File

@@ -0,0 +1,145 @@
/*
Tests string alignment
Normally strings are printed relative to the top left corner but this can be
changed with the setTextDatum() function. The library has #defines for:
TL_DATUM = 0 = Top left
TC_DATUM = 1 = Top centre
TR_DATUM = 2 = Top right
ML_DATUM = 3 = Middle left
MC_DATUM = 4 = Middle centre
MR_DATUM = 5 = Middle right
BL_DATUM = 6 = Bottom left
BC_DATUM = 7 = Bottom centre
BR_DATUM = 8 = Bottom right
L_BASELINE = 9 = Left character baseline (Line the 'A' character would sit on)
C_BASELINE = 10 = Centre character baseline
R_BASELINE = 11 = Right character baseline
So you can use lines to position text like:
tft.setTextDatum(BC_DATUM); // Set datum to bottom centre
Needs fonts 2, 4, 6, 7 and 8
#########################################################################
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
###### TO SELECT THE FONTS AND PINS YOU USE, SEE ABOVE ######
#########################################################################
*/
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
unsigned long drawTime = 0;
int x, y; // Coordinates for drawing
void setup(void) {
Serial.begin(115200);
tft.init();
tft.setRotation(1);
}
void loop() {
tft.fillScreen(TFT_BLACK);
x = 160, y = 120;
//Test all 9 datums 0-8 when plotting numbers
for(byte datum = 0; datum < 9; datum++) {
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextDatum(datum);
tft.drawNumber(42, x, y, 8);
drawCross(x, y, TFT_RED);
delay(1000);
tft.fillScreen(TFT_BLACK);
}
//Test all 9 datums 0-8 when plotting a string
// Datum works when text size is > 1
for(byte datum = 0; datum < 9; datum++) {
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextDatum(datum);
tft.setTextSize(2);
tft.drawString("[xox]", x, y, 4);
drawCross(x, y, TFT_GREEN);
delay(1000);
tft.fillScreen(TFT_BLACK);
}
tft.setTextSize(1);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
// Here a special function is used that automatically centres the text
// on the x, y coordinate
tft.drawCentreString("69", x, y, 8);
drawCross(x, y, TFT_CYAN);
delay(1000);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.drawRightString("88",160,120,8);
drawCross(x, y, TFT_RED);
delay(1000);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLUE);
//Test floating point drawing function
tft.setTextDatum(BC_DATUM); // Set datum to bottom centre
float test = 67.125;
y = 180;
tft.drawFloat(test, 4, x, y, 4);
delay(1000);
tft.fillScreen(TFT_BLACK);
test = -0.555555;
tft.drawFloat(test, 3, x, y, 4);
delay(1000);
tft.fillScreen(TFT_BLACK);
test = 0.1;
tft.drawFloat(test, 4, x, y, 4);
delay(1000);
tft.fillScreen(TFT_BLACK);
test = 9999999;
tft.drawFloat(test, 1, x, y, 4);
drawCross(x, y, TFT_RED);
delay(4000);
}
void drawCross(int x, int y, unsigned int color)
{
tft.drawLine(x - 5, y, x + 5, y, color);
tft.drawLine(x, y - 5, x, y + 5, color);
}

View File

@@ -0,0 +1,371 @@
/*
Adapted from the Adafruit graphicstest sketch, see orignal header at end
of sketch.
This sketch uses the GLCD font (font 1) only.
Make sure all the display driver and pin comnenctions are correct by
editting 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 "SPI.h"
#include "TFT_eSPI.h"
TFT_eSPI tft = TFT_eSPI();
unsigned long total = 0;
unsigned long tn = 0;
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println(""); Serial.println("");
Serial.println("TFT_eSPI library test!");
tft.init();
tn = micros();
tft.fillScreen(TFT_BLACK);
yield(); Serial.println(F("Benchmark Time (microseconds)"));
yield(); Serial.print(F("Screen fill "));
yield(); Serial.println(testFillScreen());
//total+=testFillScreen();
//delay(500);
yield(); Serial.print(F("Text "));
yield(); Serial.println(testText());
//total+=testText();
//delay(3000);
yield(); Serial.print(F("Lines "));
yield(); Serial.println(testLines(TFT_CYAN));
//total+=testLines(TFT_CYAN);
//delay(500);
yield(); Serial.print(F("Horiz/Vert Lines "));
yield(); Serial.println(testFastLines(TFT_RED, TFT_BLUE));
//total+=testFastLines(TFT_RED, TFT_BLUE);
//delay(500);
yield(); Serial.print(F("Rectangles (outline) "));
yield(); Serial.println(testRects(TFT_GREEN));
//total+=testRects(TFT_GREEN);
//delay(500);
yield(); Serial.print(F("Rectangles (filled) "));
yield(); Serial.println(testFilledRects(TFT_YELLOW, TFT_MAGENTA));
//total+=testFilledRects(TFT_YELLOW, TFT_MAGENTA);
//delay(500);
yield(); Serial.print(F("Circles (filled) "));
yield(); Serial.println(testFilledCircles(10, TFT_MAGENTA));
//total+= testFilledCircles(10, TFT_MAGENTA);
yield(); Serial.print(F("Circles (outline) "));
yield(); Serial.println(testCircles(10, TFT_WHITE));
//total+=testCircles(10, TFT_WHITE);
//delay(500);
yield(); Serial.print(F("Triangles (outline) "));
yield(); Serial.println(testTriangles());
//total+=testTriangles();
//delay(500);
yield(); Serial.print(F("Triangles (filled) "));
yield(); Serial.println(testFilledTriangles());
//total += testFilledTriangles();
//delay(500);
yield(); Serial.print(F("Rounded rects (outline) "));
yield(); Serial.println(testRoundRects());
//total+=testRoundRects();
//delay(500);
yield(); Serial.print(F("Rounded rects (filled) "));
yield(); Serial.println(testFilledRoundRects());
//total+=testFilledRoundRects();
//delay(500);
yield(); Serial.println(F("Done!")); yield();
//Serial.print(F("Total = ")); Serial.println(total);
//yield();Serial.println(millis()-tn);
}
void loop(void) {
for (uint8_t rotation = 0; rotation < 4; rotation++) {
tft.setRotation(rotation);
testText();
delay(2000);
}
}
unsigned long testFillScreen() {
unsigned long start = micros();
tft.fillScreen(TFT_BLACK);
tft.fillScreen(TFT_RED);
tft.fillScreen(TFT_GREEN);
tft.fillScreen(TFT_BLUE);
tft.fillScreen(TFT_BLACK);
return micros() - start;
}
unsigned long testText() {
tft.fillScreen(TFT_BLACK);
unsigned long start = micros();
tft.setCursor(0, 0);
tft.setTextColor(TFT_WHITE); tft.setTextSize(1);
tft.println("Hello World!");
tft.setTextColor(TFT_YELLOW); tft.setTextSize(2);
tft.println(1234.56);
tft.setTextColor(TFT_RED); tft.setTextSize(3);
tft.println(0xDEADBEEF, HEX);
tft.println();
tft.setTextColor(TFT_GREEN);
tft.setTextSize(5);
tft.println("Groop");
tft.setTextSize(2);
tft.println("I implore thee,");
//tft.setTextColor(TFT_GREEN,TFT_BLACK);
tft.setTextSize(1);
tft.println("my foonting turlingdromes.");
tft.println("And hooptiously drangle me");
tft.println("with crinkly bindlewurdles,");
tft.println("Or I will rend thee");
tft.println("in the gobberwarts");
tft.println("with my blurglecruncheon,");
tft.println("see if I don't!");
return micros() - start;
}
unsigned long testLines(uint16_t color) {
unsigned long start, t;
int x1, y1, x2, y2,
w = tft.width(),
h = tft.height();
tft.fillScreen(TFT_BLACK);
x1 = y1 = 0;
y2 = h - 1;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = w - 1;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
t = micros() - start; // fillScreen doesn't count against timing
yield();
tft.fillScreen(TFT_BLACK);
x1 = w - 1;
y1 = 0;
y2 = h - 1;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = 0;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
t += micros() - start;
yield();
tft.fillScreen(TFT_BLACK);
x1 = 0;
y1 = h - 1;
y2 = 0;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = w - 1;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
t += micros() - start;
yield();
tft.fillScreen(TFT_BLACK);
x1 = w - 1;
y1 = h - 1;
y2 = 0;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = 0;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
yield();
return micros() - start;
}
unsigned long testFastLines(uint16_t color1, uint16_t color2) {
unsigned long start;
int x, y, w = tft.width(), h = tft.height();
tft.fillScreen(TFT_BLACK);
start = micros();
for (y = 0; y < h; y += 5) tft.drawFastHLine(0, y, w, color1);
for (x = 0; x < w; x += 5) tft.drawFastVLine(x, 0, h, color2);
return micros() - start;
}
unsigned long testRects(uint16_t color) {
unsigned long start;
int n, i, i2,
cx = tft.width() / 2,
cy = tft.height() / 2;
tft.fillScreen(TFT_BLACK);
n = min(tft.width(), tft.height());
start = micros();
for (i = 2; i < n; i += 6) {
i2 = i / 2;
tft.drawRect(cx - i2, cy - i2, i, i, color);
}
return micros() - start;
}
unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
unsigned long start, t = 0;
int n, i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
n = min(tft.width(), tft.height());
for (i = n - 1; i > 0; i -= 6) {
i2 = i / 2;
start = micros();
tft.fillRect(cx - i2, cy - i2, i, i, color1);
t += micros() - start;
// Outlines are not included in timing results
tft.drawRect(cx - i2, cy - i2, i, i, color2);
}
return t;
}
unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
unsigned long start;
int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
tft.fillScreen(TFT_BLACK);
start = micros();
for (x = radius; x < w; x += r2) {
for (y = radius; y < h; y += r2) {
tft.fillCircle(x, y, radius, color);
}
}
return micros() - start;
}
unsigned long testCircles(uint8_t radius, uint16_t color) {
unsigned long start;
int x, y, r2 = radius * 2,
w = tft.width() + radius,
h = tft.height() + radius;
// Screen is not cleared for this one -- this is
// intentional and does not affect the reported time.
start = micros();
for (x = 0; x < w; x += r2) {
for (y = 0; y < h; y += r2) {
tft.drawCircle(x, y, radius, color);
}
}
return micros() - start;
}
unsigned long testTriangles() {
unsigned long start;
int n, i, cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
n = min(cx, cy);
start = micros();
for (i = 0; i < n; i += 5) {
tft.drawTriangle(
cx , cy - i, // peak
cx - i, cy + i, // bottom left
cx + i, cy + i, // bottom right
tft.color565(0, 0, i));
}
return micros() - start;
}
unsigned long testFilledTriangles() {
unsigned long start, t = 0;
int i, cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
start = micros();
for (i = min(cx, cy); i > 10; i -= 5) {
start = micros();
tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
tft.color565(0, i, i));
t += micros() - start;
tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
tft.color565(i, i, 0));
}
return t;
}
unsigned long testRoundRects() {
unsigned long start;
int w, i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
w = min(tft.width(), tft.height());
start = micros();
for (i = 0; i < w; i += 6) {
i2 = i / 2;
tft.drawRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(i, 0, 0));
}
return micros() - start;
}
unsigned long testFilledRoundRects() {
unsigned long start;
int i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
start = micros();
for (i = min(tft.width(), tft.height()); i > 20; i -= 6) {
i2 = i / 2;
tft.fillRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(0, i, 0));
yield();
}
return micros() - start;
}
/***************************************************
Original Adafruit text:
This is an example sketch for the Adafruit 2.2" SPI display.
This library works with the Adafruit 2.2" TFT Breakout w/SD card
----> http://www.adafruit.com/products/1480
Check out the links above for our tutorials and wiring diagrams
These displays use SPI to communicate, 4 or 5 pins are required to
interface (RST is optional)
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/

View File

@@ -0,0 +1,42 @@
// We need this header file to use FLASH as storage with PROGMEM directive:
#include <pgmspace.h>
// Icon width and height
const uint16_t alertWidth = 32;
const uint16_t alertHeight = 32;
// The icon file can be created with the "UTFT ImageConverter 565" bitmap to .c file creation utility, more can be pasted in here
const unsigned short alert[1024] PROGMEM={
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0840,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 0, 32 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1080,0xAC66,0xEDE8,0xFE69,0xC4C6,0x2901,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 1, 64 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xBCC6,0xFE68,0xFE68,0xFE6A,0xFE68,0xEDE8,0x18A1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 2, 96 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8344,0xFE48,0xFE8C,0xFFDD,0xFFFF,0xFEF0,0xFE48,0xB466,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 3, 128 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1880,0xEDC7,0xFE48,0xFF99,0xFFBC,0xFF9B,0xFFBD,0xFE6A,0xFE48,0x5A23,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 4, 160 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x9BE5,0xFE28,0xFED0,0xFFBC,0xFF7A,0xFF9A,0xFF9B,0xFF35,0xFE28,0xBCA6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 5, 192 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3962,0xFE28,0xFE28,0xFF9A,0xFF79,0xFF9A,0xFF9B,0xFF9A,0xFFBD,0xFE6B,0xFE28,0x72E3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 6, 224 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xB465,0xFE28,0xFEF2,0xFF7A,0xFF79,0xFF7A,0xFF9A,0xFF7A,0xFF7A,0xFF78,0xFE28,0xDD67,0x0860,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 7, 256 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5A22,0xFE07,0xFE29,0xFF9B,0xFF37,0xFF58,0xFF79,0xFF79,0xFF79,0xFF58,0xFF9B,0xFEAE,0xFE07,0x93A4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 8, 288 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xC4A5,0xFE07,0xFF15,0xFF37,0xFF36,0xAD11,0x2965,0x2965,0xCDF4,0xFF37,0xFF37,0xFF79,0xFE07,0xFE07,0x2901,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 9, 320 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7B03,0xFDE7,0xFE4B,0xFF79,0xFEF4,0xFF15,0xB552,0x2945,0x2945,0xDE55,0xFF16,0xFF15,0xFF58,0xFED1,0xFDE7,0xAC25,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 10, 352 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0840,0xDD26,0xFDE7,0xFF57,0xFED3,0xFED2,0xFEF4,0xBD93,0x2124,0x2124,0xDE75,0xFF14,0xFED3,0xFED3,0xFF7A,0xFE08,0xFDE7,0x49A2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 11, 384 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x9BA4,0xFDC6,0xFE6E,0xFF36,0xFE90,0xFEB1,0xFED3,0xC592,0x2124,0x2124,0xE675,0xFED3,0xFEB2,0xFEB1,0xFEF3,0xFEF3,0xFDC6,0xBC45,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 12, 416 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3141,0xF5C6,0xF5C7,0xFF58,0xFE90,0xFE6F,0xFE8F,0xFEB1,0xCDB2,0x2104,0x2104,0xF6B4,0xFEB1,0xFE90,0xFE8F,0xFE90,0xFF58,0xFE0A,0xF5C6,0x72A3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 13, 448 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xABE4,0xF5A6,0xFEB1,0xFED3,0xFE4E,0xFE6E,0xFE6F,0xFE90,0xD5F2,0x18E3,0x18E3,0xFED4,0xFE90,0xFE6F,0xFE6F,0xFE6E,0xFE91,0xFF36,0xF5A6,0xCCA5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 14, 480 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x5202,0xF5A6,0xF5C7,0xFF58,0xFE4D,0xFE4D,0xFE4D,0xFE4E,0xFE6F,0xDE11,0x18C3,0x18C3,0xFED3,0xFE6F,0xFE6E,0xFE4E,0xFE4D,0xFE4D,0xFF16,0xFE2C,0xF5A6,0x9363,0x0000,0x0000,0x0000,0x0000,0x0000, // row 15, 512 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0xBC44,0xF585,0xFED3,0xFE6F,0xFE2C,0xFE2C,0xFE2D,0xFE4D,0xFE4E,0xE630,0x10A2,0x2104,0xFED1,0xFE4E,0xFE4D,0xFE4D,0xFE2D,0xFE2C,0xFE4D,0xFF37,0xF586,0xF585,0x28E1,0x0000,0x0000,0x0000,0x0000, // row 16, 544 pixels
0x0000,0x0000,0x0000,0x0000,0x7282,0xF565,0xF5EA,0xFF16,0xFE0B,0xFE0B,0xFE0B,0xFE2C,0xFE2C,0xFE4D,0xF670,0x1082,0x2924,0xFEB0,0xFE2D,0xFE2C,0xFE2C,0xFE2C,0xFE0B,0xFE0B,0xFEB2,0xFE6F,0xF565,0xA383,0x0000,0x0000,0x0000,0x0000, // row 17, 576 pixels
0x0000,0x0000,0x0000,0x0840,0xD4C4,0xF565,0xFEF5,0xFE0C,0xFDE9,0xFDEA,0xFE0A,0xFE0B,0xFE0B,0xFE2C,0xFE8F,0x0861,0x2964,0xFE8F,0xFE2C,0xFE0B,0xFE0B,0xFE0B,0xFE0A,0xFDEA,0xFE0B,0xFF37,0xF586,0xF565,0x4181,0x0000,0x0000,0x0000, // row 18, 608 pixels
0x0000,0x0000,0x0000,0x9343,0xF545,0xF60C,0xFED3,0xFDC8,0xFDC8,0xFDC9,0xFDE9,0xFDEA,0xFDEA,0xFE0B,0xFE8E,0x0861,0x3184,0xFE6D,0xFE0B,0xFE0A,0xFDEA,0xFDEA,0xFDE9,0xFDC9,0xFDC9,0xFE4E,0xFEB2,0xF545,0xB3E3,0x0000,0x0000,0x0000, // row 19, 640 pixels
0x0000,0x0000,0x28E0,0xF544,0xF545,0xFF17,0xFDC8,0xFDA7,0xFDA7,0xFDC8,0xFDC8,0xFDC9,0xFDC9,0xFDE9,0xFE6C,0x10A2,0x39C4,0xFE4C,0xFDEA,0xFDE9,0xFDC9,0xFDC9,0xFDC8,0xFDC8,0xFDA7,0xFDA8,0xFF16,0xF588,0xF544,0x6222,0x0000,0x0000, // row 20, 672 pixels
0x0000,0x0000,0xA383,0xF524,0xF64E,0xFE4E,0xFD86,0xFD86,0xFD87,0xFDA7,0xFDA7,0xFDA8,0xFDC8,0xFDC8,0xFE2A,0xA469,0xB4EA,0xFE2A,0xFDC9,0xFDC8,0xFDC8,0xFDA8,0xFDA7,0xFDA7,0xFD87,0xFD86,0xFDEA,0xFED3,0xF524,0xC443,0x0000,0x0000, // row 21, 704 pixels
0x0000,0x51C1,0xF504,0xF546,0xFF16,0xF565,0xFD65,0xFD65,0xFD86,0xFD86,0xFD86,0xFDA7,0xFDA7,0xFDA7,0xFDE8,0xFE6A,0xFE4A,0xFDE8,0xFDA7,0xFDA7,0xFDA7,0xFDA7,0xFD86,0xFD86,0xFD86,0xFD65,0xFD65,0xFEB2,0xF5CA,0xF504,0x8AE2,0x0000, // row 22, 736 pixels
0x0000,0xB3A2,0xED03,0xFE92,0xFDC9,0xF543,0xF544,0xFD44,0xFD65,0xFD65,0xFD65,0xFD86,0xFD86,0xFD86,0xFDA7,0xFDC7,0xFDC7,0xFDA7,0xFD86,0xFD86,0xFD86,0xFD86,0xFD65,0xFD65,0xFD65,0xFD44,0xF544,0xFD86,0xFEF5,0xED03,0xE4C3,0x1880, // row 23, 768 pixels
0x7241,0xECE3,0xF567,0xFED3,0xF523,0xF523,0xF523,0xF543,0xF544,0xF544,0xFD65,0xFD65,0xFD65,0xFD65,0xD4E6,0x39C5,0x39A5,0xD4E6,0xFD86,0xFD65,0xFD65,0xFD65,0xFD65,0xF544,0xF544,0xF543,0xF523,0xF523,0xFE2E,0xF5EC,0xECE3,0x9B42, // row 24, 800 pixels
0xD443,0xECE3,0xFED4,0xF565,0xF502,0xF502,0xF522,0xF523,0xF523,0xF543,0xF544,0xF544,0xF544,0xFD65,0x8B64,0x18C3,0x18C3,0x8344,0xFD85,0xFD44,0xF544,0xF544,0xF544,0xF543,0xF523,0xF523,0xF522,0xF502,0xF523,0xFEF5,0xED04,0xECE3, // row 25, 832 pixels
0xECC3,0xF5AB,0xFE6F,0xF501,0xF4E1,0xF501,0xF502,0xF502,0xF522,0xF522,0xF523,0xF523,0xF523,0xFD84,0xC504,0x20E1,0x18E1,0xC4E4,0xFD84,0xF543,0xF523,0xF523,0xF523,0xF522,0xF522,0xF502,0xF502,0xF501,0xF501,0xFDC9,0xF62F,0xECC3, // row 26, 864 pixels
0xECC2,0xFE92,0xF523,0xF4E0,0xF4E0,0xF4E1,0xF4E1,0xF501,0xF501,0xF502,0xF502,0xF522,0xF522,0xF543,0xFDE3,0xFEA5,0xF6A4,0xFE04,0xF543,0xF522,0xF522,0xF522,0xF502,0xF502,0xF501,0xF501,0xF4E1,0xF4E1,0xF4E0,0xF4E1,0xFED4,0xECC2, // row 27, 896 pixels
0xECA2,0xF5EC,0xF4E0,0xF4C0,0xF4E0,0xF4E0,0xF4E0,0xF4E1,0xF4E1,0xF501,0xF501,0xF501,0xF502,0xF502,0xF542,0xFDA2,0xFDA2,0xF542,0xF502,0xF502,0xF502,0xF501,0xF501,0xF501,0xF4E1,0xF4E1,0xF4E0,0xF4E0,0xF4E0,0xF4C0,0xF5A9,0xECA2, // row 28, 928 pixels
0xECA2,0xECA2,0xECC2,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4E1,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xECC2,0xECC3,0xECA2, // row 29, 960 pixels
0x8AC1,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0x9B01, // row 30, 992 pixels
0x0000,0x1880,0x51A0,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x61E0,0x28E0,0x0000}; // row 31, 1024 pixels

View File

@@ -0,0 +1,277 @@
/*
An example showing 'ring' analogue meter on a TFT
colour screen
Needs Fonts 2, 4 and 7 (also Font 6 if using a large size meter)
*/
// Meter colour schemes
#define RED2RED 0
#define GREEN2GREEN 1
#define BLUE2BLUE 2
#define BLUE2RED 3
#define GREEN2RED 4
#define RED2GREEN 5
#define TFT_GREY 0x2104 // Dark grey 16 bit colour
#include "alert.h" // Out of range alert icon
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library with default width and height
uint32_t runTime = -99999; // time for next update
int reading = 0; // Value to be displayed
int d = 0; // Variable used for the sinewave test waveform
boolean range_error = 0;
int8_t ramp = 1;
void setup(void) {
tft.begin();
//Serial.begin(9600);
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
}
void loop() {
if (millis() - runTime >= 0L) { // Execute every TBD ms
runTime = millis();
// Test with a slowly changing value from a Sine function
//d += 4; if (d >= 360) d = 0;
// Set the the position, gap between meters, and inner radius of the meters
int xpos = 0, ypos = 5, gap = 4, radius = 52;
// Draw meter and get back x position of next meter
// Test with Sine wave function, normally reading will be from a sensor
//reading = 250 + 250 * sineWave(d+0);
//xpos = gap + ringMeter(reading, 0, 500, xpos, ypos, radius, "mA", GREEN2RED); // Draw analogue meter
//reading = 20 + 30 * sineWave(d+60);
//xpos = gap + ringMeter(reading, -10, 50, xpos, ypos, radius, "degC", BLUE2RED); // Draw analogue meter
//reading = 50 + 50 * sineWave(d + 120);
//ringMeter(reading, 0, 100, xpos, ypos, radius, "%RH", BLUE2BLUE); // Draw analogue meter
// Draw two more larger meters
//xpos = 20, ypos = 115, gap = 24, radius = 64;
//reading = 1000 + 150 * sineWave(d + 90);
//xpos = gap + ringMeter(reading, 850, 1150, xpos, ypos, radius, "mb", BLUE2RED); // Draw analogue meter
//reading = 15 + 15 * sineWave(d + 150);
//xpos = gap + ringMeter(reading, 0, 30, xpos, ypos, radius, "Volts", GREEN2GREEN); // Draw analogue meter
// Draw a large meter
xpos = 480/2 - 160, ypos = 0, gap = 15, radius = 170;
reading +=(ramp);
if (reading>98) ramp = -1;
if (reading<0) ramp = 1;
// Comment out above meters, then uncomment the next line to show large meter
ringMeter(reading,0,100, xpos,ypos,radius," Watts",GREEN2RED); // Draw analogue meter
if (reading<0) delay(1000);
}
}
// #########################################################################
// Draw the meter on the screen, returns x coord of righthand side
// #########################################################################
int ringMeter(int value, int vmin, int vmax, int x, int y, int r, const char *units, byte scheme)
{
// Minimum value of r is about 52 before value text intrudes on ring
// drawing the text first is an option
x += r; y += r; // Calculate coords of centre of ring
int w = r / 3; // Width of outer ring is 1/4 of radius
int angle = 150; // Half the sweep angle of meter (300 degrees)
int v = map(value, vmin, vmax, -angle, angle); // Map the value to an angle v
byte seg = 3; // Segments are 3 degrees wide = 100 segments for 300 degrees
byte inc = 6; // Draw segments every 3 degrees, increase to 6 for segmented ring
// Variable to save "value" text colour from scheme and set default
int colour = TFT_BLUE;
// Draw colour blocks every inc degrees
for (int i = -angle+inc/2; i < angle-inc/2; i += inc) {
// Calculate pair of coordinates for segment start
float sx = cos((i - 90) * 0.0174532925);
float sy = sin((i - 90) * 0.0174532925);
uint16_t x0 = sx * (r - w) + x;
uint16_t y0 = sy * (r - w) + y;
uint16_t x1 = sx * r + x;
uint16_t y1 = sy * r + y;
// Calculate pair of coordinates for segment end
float sx2 = cos((i + seg - 90) * 0.0174532925);
float sy2 = sin((i + seg - 90) * 0.0174532925);
int x2 = sx2 * (r - w) + x;
int y2 = sy2 * (r - w) + y;
int x3 = sx2 * r + x;
int y3 = sy2 * r + y;
if (i < v) { // Fill in coloured segments with 2 triangles
switch (scheme) {
case 0: colour = TFT_RED; break; // Fixed colour
case 1: colour = TFT_GREEN; break; // Fixed colour
case 2: colour = TFT_BLUE; break; // Fixed colour
case 3: colour = rainbow(map(i, -angle, angle, 0, 127)); break; // Full spectrum blue to red
case 4: colour = rainbow(map(i, -angle, angle, 70, 127)); break; // Green to red (high temperature etc)
case 5: colour = rainbow(map(i, -angle, angle, 127, 63)); break; // Red to green (low battery etc)
default: colour = TFT_BLUE; break; // Fixed colour
}
tft.fillTriangle(x0, y0, x1, y1, x2, y2, colour);
tft.fillTriangle(x1, y1, x2, y2, x3, y3, colour);
//text_colour = colour; // Save the last colour drawn
}
else // Fill in blank segments
{
tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_GREY);
tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_GREY);
}
}
// Convert value to a string
char buf[10];
byte len = 3; if (value > 999) len = 5;
dtostrf(value, len, 0, buf);
buf[len] = ' '; buf[len+1] = 0; // Add blanking space and terminator, helps to centre text too!
// Set the text colour to default
tft.setTextSize(1);
if (value<vmin || value>vmax) {
drawAlert(x,y+90,50,1);
}
else {
drawAlert(x,y+90,50,0);
}
tft.setTextColor(TFT_WHITE, TFT_BLACK);
// Uncomment next line to set the text colour to the last segment value!
tft.setTextColor(colour, TFT_BLACK);
tft.setTextDatum(MC_DATUM);
// Print value, if the meter is large then use big font 8, othewise use 4
if (r > 84) {
tft.setTextPadding(55*3); // Allow for 3 digits each 55 pixels wide
tft.drawString(buf, x, y, 8); // Value in middle
}
else {
tft.setTextPadding(3 * 14); // Allow for 3 digits each 14 pixels wide
tft.drawString(buf, x, y, 4); // Value in middle
}
tft.setTextSize(1);
tft.setTextPadding(0);
// Print units, if the meter is large then use big font 4, othewise use 2
tft.setTextColor(TFT_WHITE, TFT_BLACK);
if (r > 84) tft.drawString(units, x, y + 60, 4); // Units display
else tft.drawString(units, x, y + 15, 2); // Units display
// Calculate and return right hand side x coordinate
return x + r;
}
void drawAlert(int x, int y , int side, boolean draw)
{
if (draw && !range_error) {
drawIcon(alert, x - alertWidth/2, y - alertHeight/2, alertWidth, alertHeight);
range_error = 1;
}
else if (!draw) {
tft.fillRect(x - alertWidth/2, y - alertHeight/2, alertWidth, alertHeight, TFT_BLACK);
range_error = 0;
}
}
// #########################################################################
// Return a 16 bit rainbow colour
// #########################################################################
unsigned int rainbow(byte value)
{
// Value is expected to be in range 0-127
// The value is converted to a spectrum colour from 0 = blue through to 127 = red
byte red = 0; // Red is the top 5 bits of a 16 bit colour value
byte green = 0;// Green is the middle 6 bits
byte blue = 0; // Blue is the bottom 5 bits
byte quadrant = value / 32;
if (quadrant == 0) {
blue = 31;
green = 2 * (value % 32);
red = 0;
}
if (quadrant == 1) {
blue = 31 - (value % 32);
green = 63;
red = 0;
}
if (quadrant == 2) {
blue = 0;
green = 63;
red = value % 32;
}
if (quadrant == 3) {
blue = 0;
green = 63 - 2 * (value % 32);
red = 31;
}
return (red << 11) + (green << 5) + blue;
}
// #########################################################################
// Return a value in range -1 to +1 for a given phase angle in degrees
// #########################################################################
float sineWave(int phase) {
return sin(phase * 0.0174532925);
}
//====================================================================================
// This is the function to draw the icon stored as an array in program memory (FLASH)
//====================================================================================
// To speed up rendering we use a 64 pixel buffer
#define BUFF_SIZE 64
// Draw array "icon" of defined width and height at coordinate x,y
// Maximum icon size is 255x255 pixels to avoid integer overflow
void drawIcon(const unsigned short* icon, int16_t x, int16_t y, int8_t width, int8_t height) {
uint16_t pix_buffer[BUFF_SIZE]; // Pixel buffer (16 bits per pixel)
// Set up a window the right size to stream pixels into
tft.setWindow(x, y, x + width - 1, y + height - 1);
// Work out the number whole buffers to send
uint16_t nb = ((uint16_t)height * width) / BUFF_SIZE;
// Fill and send "nb" buffers to TFT
for (int i = 0; i < nb; i++) {
for (int j = 0; j < BUFF_SIZE; j++) {
pix_buffer[j] = pgm_read_word(&icon[i * BUFF_SIZE + j]);
}
tft.pushColors(pix_buffer, BUFF_SIZE);
}
// Work out number of pixels not yet sent
uint16_t np = ((uint16_t)height * width) % BUFF_SIZE;
// Send any partial buffer left over
if (np) {
for (int i = 0; i < np; i++) pix_buffer[i] = pgm_read_word(&icon[nb * BUFF_SIZE + i]);
tft.pushColors(pix_buffer, np);
}
}

View File

@@ -0,0 +1,326 @@
// Demo based on:
// UTFT_Demo by Henning Karlsen
// web: http://www.henningkarlsen.com/electronics
/*
The delay between tests is set to 0. The tests run so fast you will need to
change the WAIT value below to see what is being plotted!
This sketch uses the GLCD and font 2 only.
Make sure all the required fonts are loaded by editting the
User_Setup.h file in the TFT_eSPI library folder.
#########################################################################
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
###### TO SELECT THE FONTS YOU USE, SEE ABOVE ######
#########################################################################
*/
// Delay between demo pages
#define WAIT 0 // Delay between tests, set to 0 to demo speed, 2000 to see what it does!
#define CENTRE 240
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library with default width and height
#define TFT_GREY 0x7BEF
uint32_t runTime = 0;
void setup()
{
randomSeed(analogRead(0));
Serial.begin(38400);
// Setup the LCD
tft.init();
tft.setRotation(1);
}
void loop()
{
int buf[478];
int x, x2;
int y, y2;
int r;
runTime = millis();
// Clear the screen and draw the frame
tft.fillScreen(TFT_BLACK);
tft.fillRect(0, 0, 480, 13, TFT_RED);
tft.fillRect(0, 305, 480, 320, TFT_GREY);
tft.setTextColor(TFT_BLACK,TFT_RED);
tft.drawCentreString("* TFT_eSPI *", CENTRE, 3, 1);
tft.setTextColor(TFT_YELLOW,TFT_GREY);
tft.drawCentreString("Adapted by Bodmer", CENTRE, 309,1);
tft.drawRect(0, 14, 479, 305-14, TFT_BLUE);
// Draw crosshairs
tft.drawLine(239, 15, 239, 304, TFT_BLUE);
tft.drawLine(1, 159, 478, 159, TFT_BLUE);
for (int i=9; i<470; i+=10)
tft.drawLine(i, 157, i, 161, TFT_BLUE);
for (int i=19; i<220; i+=10)
tft.drawLine(237, i, 241, i, TFT_BLUE);
// Draw sin-, cos- and tan-lines
tft.setTextColor(TFT_CYAN);
tft.drawString("Sin", 5, 15,2);
for (int i=1; i<478; i++)
{
tft.drawPixel(i,159+(sin(((i*1.13)*3.14)/180)*95),TFT_CYAN);
}
tft.setTextColor(TFT_RED);
tft.drawString("Cos", 5, 30,2);
for (int i=1; i<478; i++)
{
tft.drawPixel(i,159+(cos(((i*1.13)*3.14)/180)*95),TFT_RED);
}
tft.setTextColor(TFT_YELLOW);
tft.drawString("Tan", 5, 45,2);
for (int i=1; i<478; i++)
{
tft.drawPixel(i,159+(tan(((i*1.13)*3.14)/180)),TFT_YELLOW);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
tft.drawLine(239, 15, 239, 304,TFT_BLUE);
tft.drawLine(1, 159, 478, 159,TFT_BLUE);
// Draw a moving sinewave
int col = 0;
x=1;
for (int i=1; i<(477*15); i++)
{
x++;
if (x==478)
x=1;
if (i>478)
{
if ((x==239)||(buf[x-1]==159))
col = TFT_BLUE;
else
tft.drawPixel(x,buf[x-1],TFT_BLACK);
}
y=159+(sin(((i*0.7)*3.14)/180)*(90-(i / 100)));
tft.drawPixel(x,y, TFT_BLUE);
buf[x-1]=y;
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
// Draw some filled rectangles
for (int i=1; i<6; i++)
{
switch (i)
{
case 1:
col = TFT_MAGENTA;
break;
case 2:
col = TFT_RED;
break;
case 3:
col = TFT_GREEN;
break;
case 4:
col = TFT_BLUE;
break;
case 5:
col = TFT_YELLOW;
break;
}
tft.fillRect(150+(i*20), 70+(i*20), 60, 60,col);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
// Draw some filled, rounded rectangles
for (int i=1; i<6; i++)
{
switch (i)
{
case 1:
col = TFT_MAGENTA;
break;
case 2:
col = TFT_RED;
break;
case 3:
col = TFT_GREEN;
break;
case 4:
col = TFT_BLUE;
break;
case 5:
col = TFT_YELLOW;
break;
}
tft.fillRoundRect(270-(i*20), 70+(i*20), 60, 60, 3, col);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
// Draw some filled circles
for (int i=1; i<6; i++)
{
switch (i)
{
case 1:
col = TFT_MAGENTA;
break;
case 2:
col = TFT_RED;
break;
case 3:
col = TFT_GREEN;
break;
case 4:
col = TFT_BLUE;
break;
case 5:
col = TFT_YELLOW;
break;
}
tft.fillCircle(180+(i*20),100+(i*20), 30,col);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
// Draw some lines in a pattern
for (int i=15; i<304; i+=5)
{
tft.drawLine(1, i, (i*1.6)-10, 303, TFT_RED);
}
for (int i=304; i>15; i-=5)
{
tft.drawLine(477, i, (i*1.6)-11, 15, TFT_RED);
}
for (int i=304; i>15; i-=5)
{
tft.drawLine(1, i, 491-(i*1.6), 15, TFT_CYAN);
}
for (int i=15; i<304; i+=5)
{
tft.drawLine(477, i, 490-(i*1.6), 303, TFT_CYAN);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
// Draw some random circles
for (int i=0; i<100; i++)
{
x=32+random(416);
y=45+random(226);
r=random(30);
tft.drawCircle(x, y, r,random(0xFFFF));
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
// Draw some random rectangles
for (int i=0; i<100; i++)
{
x=2+random(476);
y=16+random(289);
x2=2+random(476);
y2=16+random(289);
if (x2<x) {
r=x;x=x2;x2=r;
}
if (y2<y) {
r=y;y=y2;y2=r;
}
tft.drawRect(x, y, x2-x, y2-y,random(0xFFFF));
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
// Draw some random rounded rectangles
for (int i=0; i<100; i++)
{
x=2+random(476);
y=16+random(289);
x2=2+random(476);
y2=16+random(289);
if (x2<x) {
r=x;x=x2;x2=r;
}
if (y2<y) {
r=y;y=y2;y2=r;
}
tft.drawRoundRect(x, y, x2-x, y2-y, 3,random(0xFFFF));
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
for (int i=0; i<100; i++)
{
x=2+random(476);
y=16+random(289);
x2=2+random(476);
y2=16+random(289);
col=random(0xFFFF);
tft.drawLine(x, y, x2, y2,col);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
for (int i=0; i<10000; i++)
{
tft.drawPixel(2+random(476), 16+random(289),random(0xFFFF));
}
delay(WAIT);
tft.fillRect(0, 0, 480, 320, TFT_BLUE);
tft.fillRoundRect(160, 70, 319-160, 169-70, 3,TFT_RED);
tft.setTextColor(TFT_WHITE,TFT_RED);
tft.drawCentreString("That's it!", CENTRE, 93,2);
tft.drawCentreString("Restarting in a", CENTRE, 119, 2);
tft.drawCentreString("few seconds...", CENTRE, 132, 2);
tft.setTextColor(TFT_GREEN,TFT_BLUE);
tft.drawCentreString("Runtime: (msecs)", CENTRE, 280, 2);
tft.setTextDatum(TC_DATUM);
runTime = millis()-runTime;
tft.drawNumber(runTime, CENTRE, 300,2);
tft.setTextDatum(TL_DATUM);
delay (10000);
}