diff --git a/TFT_Drivers/RPI_ILI9486_Defines.h b/TFT_Drivers/RPI_ILI9486_Defines.h new file mode 100644 index 0000000..70bd26c --- /dev/null +++ b/TFT_Drivers/RPI_ILI9486_Defines.h @@ -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 diff --git a/TFT_Drivers/RPI_ILI9486_Init.h b/TFT_Drivers/RPI_ILI9486_Init.h new file mode 100644 index 0000000..f7ce458 --- /dev/null +++ b/TFT_Drivers/RPI_ILI9486_Init.h @@ -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); +} \ No newline at end of file diff --git a/TFT_Drivers/RPI_ILI9486_Rotation.h b/TFT_Drivers/RPI_ILI9486_Rotation.h new file mode 100644 index 0000000..cd6b0f7 --- /dev/null +++ b/TFT_Drivers/RPI_ILI9486_Rotation.h @@ -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; + } + \ No newline at end of file diff --git a/TFT_Drivers/XXXXXXX_init.h b/TFT_Drivers/XXXXXXX_init.h new file mode 100644 index 0000000..f547e1e --- /dev/null +++ b/TFT_Drivers/XXXXXXX_init.h @@ -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 + +} \ No newline at end of file diff --git a/TFT_eSPI.cpp b/TFT_eSPI.cpp index 108aeea..80eaa4a 100644 --- a/TFT_eSPI.cpp +++ b/TFT_eSPI.cpp @@ -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 +// 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 diff --git a/User_Setup.h b/User_Setup.h index 716f981..47c9549 100644 --- a/User_Setup.h +++ b/User_Setup.h @@ -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 diff --git a/User_Setup_Select.h b/User_Setup_Select.h index b0b2d7c..af781a2 100644 --- a/User_Setup_Select.h +++ b/User_Setup_Select.h @@ -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 #elif defined (S6D02A1_DRIVER) #include +#elif defined (RPI_ILI9486_DRIVER) + #include #endif diff --git a/User_Setups/Setup5_ILI9486.h b/User_Setups/Setup5_ILI9486.h new file mode 100644 index 0000000..8a6ef81 --- /dev/null +++ b/User_Setups/Setup5_ILI9486.h @@ -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 diff --git a/examples/RPi/Cellular_Automata/Cellular_Automata.ino b/examples/RPi/Cellular_Automata/Cellular_Automata.ino new file mode 100644 index 0000000..df1d64b --- /dev/null +++ b/examples/RPi/Cellular_Automata/Cellular_Automata.ino @@ -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 + +#include // 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. +*/ + diff --git a/examples/RPi/Demo_3D_cube/Demo_3D_cube.ino b/examples/RPi/Demo_3D_cube/Demo_3D_cube.ino new file mode 100644 index 0000000..cfcac3c --- /dev/null +++ b/examples/RPi/Demo_3D_cube/Demo_3D_cube.ino @@ -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 + +#include // 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; + +} + diff --git a/examples/RPi/Flash_Bitmap/Alert.h b/examples/RPi/Flash_Bitmap/Alert.h new file mode 100644 index 0000000..54d013d --- /dev/null +++ b/examples/RPi/Flash_Bitmap/Alert.h @@ -0,0 +1,42 @@ +// We need this header file to use FLASH as storage with PROGMEM directive: +#include + +// 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 + diff --git a/examples/RPi/Flash_Bitmap/Close.h b/examples/RPi/Flash_Bitmap/Close.h new file mode 100644 index 0000000..c16d522 --- /dev/null +++ b/examples/RPi/Flash_Bitmap/Close.h @@ -0,0 +1,41 @@ +// We need this header file to use FLASH as storage with PROGMEM directive: +#include + +// 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 diff --git a/examples/RPi/Flash_Bitmap/Flash_Bitmap.ino b/examples/RPi/Flash_Bitmap/Flash_Bitmap.ino new file mode 100644 index 0000000..0329e5f --- /dev/null +++ b/examples/RPi/Flash_Bitmap/Flash_Bitmap.ino @@ -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 // Hardware-specific library +#include + +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); + } +} + diff --git a/examples/RPi/Flash_Bitmap/Info.h b/examples/RPi/Flash_Bitmap/Info.h new file mode 100644 index 0000000..c4ee633 --- /dev/null +++ b/examples/RPi/Flash_Bitmap/Info.h @@ -0,0 +1,41 @@ +// We need this header file to use FLASH as storage with PROGMEM directive: +#include + +// 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 diff --git a/examples/RPi/Free_Font_Demo/Free_Font_Demo.ino b/examples/RPi/Free_Font_Demo/Free_Font_Demo.ino new file mode 100644 index 0000000..a38f266 --- /dev/null +++ b/examples/RPi/Free_Font_Demo/Free_Font_Demo.ino @@ -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 // Hardware-specific library +#include + +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 + diff --git a/examples/RPi/Free_Font_Demo/Free_Fonts.h b/examples/RPi/Free_Font_Demo/Free_Fonts.h new file mode 100644 index 0000000..a87be36 --- /dev/null +++ b/examples/RPi/Free_Font_Demo/Free_Fonts.h @@ -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 diff --git a/examples/RPi/Graph_2/Graph_2.ino b/examples/RPi/Graph_2/Graph_2.ino new file mode 100644 index 0000000..5b16db3 --- /dev/null +++ b/examples/RPi/Graph_2/Graph_2.ino @@ -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 // Hardware-specific library +#include + +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) { + +} + + + + diff --git a/examples/RPi/TFT_Char_times/TFT_Char_times.ino b/examples/RPi/TFT_Char_times/TFT_Char_times.ino new file mode 100644 index 0000000..7968f18 --- /dev/null +++ b/examples/RPi/TFT_Char_times/TFT_Char_times.ino @@ -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 + +#include // 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); +} + + + + + + + + diff --git a/examples/RPi/TFT_Ellipse/TFT_Ellipse.ino b/examples/RPi/TFT_Ellipse/TFT_Ellipse.ino new file mode 100644 index 0000000..5f8def2 --- /dev/null +++ b/examples/RPi/TFT_Ellipse/TFT_Ellipse.ino @@ -0,0 +1,51 @@ +/* + Ellipse drawing example + + This sketch does not use any fonts. +*/ + +#include + +#include // 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); +} + + + diff --git a/examples/RPi/TFT_Meter_4/TFT_Meter_4.ino b/examples/RPi/TFT_Meter_4/TFT_Meter_4.ino new file mode 100644 index 0000000..60acdc4 --- /dev/null +++ b/examples/RPi/TFT_Meter_4/TFT_Meter_4.ino @@ -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 + +#include // 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); + } +} + diff --git a/examples/RPi/TFT_Meters/TFT_Meters.ino b/examples/RPi/TFT_Meters/TFT_Meters.ino new file mode 100644 index 0000000..339fc32 --- /dev/null +++ b/examples/RPi/TFT_Meters/TFT_Meters.ino @@ -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 + +#include // 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); + } + } + } +} + diff --git a/examples/RPi/TFT_Padding_demo/TFT_Padding_demo.ino b/examples/RPi/TFT_Padding_demo/TFT_Padding_demo.ino new file mode 100644 index 0000000..eac348f --- /dev/null +++ b/examples/RPi/TFT_Padding_demo/TFT_Padding_demo.ino @@ -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 + +#include // 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); + +} + + + + + diff --git a/examples/RPi/TFT_Print_Test/TFT_Print_Test.ino b/examples/RPi/TFT_Print_Test/TFT_Print_Test.ino new file mode 100644 index 0000000..4b41327 --- /dev/null +++ b/examples/RPi/TFT_Print_Test/TFT_Print_Test.ino @@ -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 + +#include // 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); +} + + + diff --git a/examples/RPi/TFT_Rainbow480/TFT_Rainbow480.ino b/examples/RPi/TFT_Rainbow480/TFT_Rainbow480.ino new file mode 100644 index 0000000..be51aee --- /dev/null +++ b/examples/RPi/TFT_Rainbow480/TFT_Rainbow480.ino @@ -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 + +#include // 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; + } +} + + + diff --git a/examples/RPi/TFT_String_Align/TFT_String_Align.ino b/examples/RPi/TFT_String_Align/TFT_String_Align.ino new file mode 100644 index 0000000..98c5ffe --- /dev/null +++ b/examples/RPi/TFT_String_Align/TFT_String_Align.ino @@ -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 + +#include // 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); +} + + + + + diff --git a/examples/RPi/TFT_graphicstest_one_lib/TFT_graphicstest_one_lib.ino b/examples/RPi/TFT_graphicstest_one_lib/TFT_graphicstest_one_lib.ino new file mode 100644 index 0000000..ef54c3f --- /dev/null +++ b/examples/RPi/TFT_graphicstest_one_lib/TFT_graphicstest_one_lib.ino @@ -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 + ****************************************************/ + diff --git a/examples/RPi/TFT_ring_meter/Alert.h b/examples/RPi/TFT_ring_meter/Alert.h new file mode 100644 index 0000000..54d013d --- /dev/null +++ b/examples/RPi/TFT_ring_meter/Alert.h @@ -0,0 +1,42 @@ +// We need this header file to use FLASH as storage with PROGMEM directive: +#include + +// 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 + diff --git a/examples/RPi/TFT_ring_meter/TFT_ring_meter.ino b/examples/RPi/TFT_ring_meter/TFT_ring_meter.ino new file mode 100644 index 0000000..ebed42b --- /dev/null +++ b/examples/RPi/TFT_ring_meter/TFT_ring_meter.ino @@ -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 // Hardware-specific library +#include + +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 (valuevmax) { + 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); + } +} + diff --git a/examples/RPi/UTFT_Demo_480x320/UTFT_Demo_480x320.ino b/examples/RPi/UTFT_Demo_480x320/UTFT_Demo_480x320.ino new file mode 100644 index 0000000..973efa5 --- /dev/null +++ b/examples/RPi/UTFT_Demo_480x320/UTFT_Demo_480x320.ino @@ -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 // Hardware-specific library +#include + +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