diff --git a/User_Setup.h b/User_Setup.h index 5004e1f..54695fc 100644 --- a/User_Setup.h +++ b/User_Setup.h @@ -22,7 +22,7 @@ // 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: +// User_Setup file, then rebuild and upload the sketch to the board again: //#define ST7735_INITB //#define ST7735_GREENTAB diff --git a/examples/ILI9341/Cellular_Automata/Cellular_Automata.ino b/examples/ILI9341/Cellular_Automata/Cellular_Automata.ino index e00bec6..265f246 100644 --- a/examples/ILI9341/Cellular_Automata/Cellular_Automata.ino +++ b/examples/ILI9341/Cellular_Automata/Cellular_Automata.ino @@ -9,9 +9,13 @@ TFT_eSPI tft = TFT_eSPI(); // Invoke custom library -#define GRIDX 64 -#define GRIDY 48 -#define CELLXY 5 +//#define GRIDX 80 +//#define GRIDY 60 +//#define CELLXY 4 + +#define GRIDX 160 +#define GRIDY 120 +#define CELLXY 2 #define GEN_DELAY 0 @@ -23,6 +27,7 @@ uint8_t newgrid[GRIDX][GRIDY]; //Number of generations #define NUMGEN 600 + uint16_t genCount = 0; void setup() { diff --git a/examples/ILI9341/Free_Font_Demo/Free_Font_Demo.ino b/examples/ILI9341/Free_Font_Demo/Free_Font_Demo.ino index 548b546..bb47cce 100644 --- a/examples/ILI9341/Free_Font_Demo/Free_Font_Demo.ino +++ b/examples/ILI9341/Free_Font_Demo/Free_Font_Demo.ino @@ -261,7 +261,7 @@ void loop() { } // Print the header for a display screen -void header(char *string, uint16_t color) +void header(const char *string, uint16_t color) { tft.fillScreen(color); tft.setTextSize(1); diff --git a/examples/ILI9341/TFT_ArcFill/TFT_ArcFill.ino b/examples/ILI9341/TFT_ArcFill/TFT_ArcFill.ino index 55a149d..b9b5198 100644 --- a/examples/ILI9341/TFT_ArcFill/TFT_ArcFill.ino +++ b/examples/ILI9341/TFT_ArcFill/TFT_ArcFill.ino @@ -6,13 +6,15 @@ TFT_eSPI tft = TFT_eSPI(); // Invoke custom library #define DEG2RAD 0.0174532925 +#define LOOP_DELAY 10 // Loop delay to slow things down + byte inc = 0; unsigned int col = 0; - byte red = 31; // 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 state = 0; +byte red = 31; // 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 state = 0; void setup(void) { tft.begin(); @@ -27,19 +29,20 @@ void setup(void) { void loop() { // Continuous elliptical arc drawing - fillArc(160, 120, inc*6, 1, 140, 100, 10, rainbow(col)); + fillArc(160, 120, inc * 6, 1, 140, 100, 10, rainbow(col)); // Continuous segmented (inc*2) elliptical arc drawing - fillArc(160, 120, ((inc*2)%60)*6, 1, 120, 80, 30, rainbow(col)); + fillArc(160, 120, ((inc * 2) % 60) * 6, 1, 120, 80, 30, rainbow(col)); // Circle drawing using arc with arc width = radius - fillArc(160, 120, inc*6, 1, 42, 42, 42, rainbow(col)); + fillArc(160, 120, inc * 6, 1, 42, 42, 42, rainbow(col)); inc++; - col+=1; - if (col>191) col = 0; + col += 1; + if (col > 191) col = 0; if (inc > 59) inc = 0; - //delay(10); + + delay(LOOP_DELAY); } @@ -62,13 +65,13 @@ int fillArc(int x, int y, int start_angle, int seg_count, int rx, int ry, int w, byte seg = 6; // Segments are 3 degrees wide = 120 segments for 360 degrees byte inc = 6; // Draw segments every 3 degrees, increase to 6 for segmented ring - // Calculate first pair of coordinates for segment start - float sx = cos((start_angle - 90) * DEG2RAD); - float sy = sin((start_angle - 90) * DEG2RAD); - uint16_t x0 = sx * (rx - w) + x; - uint16_t y0 = sy * (ry - w) + y; - uint16_t x1 = sx * rx + x; - uint16_t y1 = sy * ry + y; + // Calculate first pair of coordinates for segment start + float sx = cos((start_angle - 90) * DEG2RAD); + float sy = sin((start_angle - 90) * DEG2RAD); + uint16_t x0 = sx * (rx - w) + x; + uint16_t y0 = sy * (ry - w) + y; + uint16_t x1 = sx * rx + x; + uint16_t y1 = sy * ry + y; // Draw colour blocks every inc degrees for (int i = start_angle; i < start_angle + seg * seg_count; i += inc) { @@ -101,9 +104,9 @@ unsigned int brightness(unsigned int colour, int brightness) byte green = (colour & 0x7E0) >> 5; byte blue = colour & 0x1F; - blue = (blue * brightness)/100; - green = (green * brightness)/100; - red = (red * brightness)/100; + blue = (blue * brightness) / 100; + green = (green * brightness) / 100; + red = (red * brightness) / 100; return (red << 11) + (green << 5) + blue; } @@ -116,50 +119,50 @@ 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 - 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; - } - return red << 11 | green << 5 | blue; + 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; + } + return red << 11 | green << 5 | blue; } diff --git a/examples/ILI9341/TFT_Char_times/TFT_Char_times.ino b/examples/ILI9341/TFT_Char_times/TFT_Char_times.ino index 518179a..2292b7c 100644 --- a/examples/ILI9341/TFT_Char_times/TFT_Char_times.ino +++ b/examples/ILI9341/TFT_Char_times/TFT_Char_times.ino @@ -5,10 +5,11 @@ Needs fonts 2, 4, 6, 7 and 8 + 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 ###### - ###### TO SELECT THE FONTS AND PINS YOU USE, SEE ABOVE ###### ######################################################################### */ diff --git a/examples/ILI9341/TFT_Clock/TFT_Clock.ino b/examples/ILI9341/TFT_Clock/TFT_Clock.ino index 888d1e0..66395fa 100644 --- a/examples/ILI9341/TFT_Clock/TFT_Clock.ino +++ b/examples/ILI9341/TFT_Clock/TFT_Clock.ino @@ -1,15 +1,17 @@ /* An example analogue clock using a TFT LCD screen to show the time - use of some of the drawing commands with the modified Adafruit_TFT_AS library. + use of some of the drawing commands with the library. + For a more accurate clock, it would be better to use the RTClib library. But this is just a demo. This sketch uses font 4 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 ###### - ###### TO SELECT THE FONTS AND PINS YOU USE, SEE ABOVE ###### ######################################################################### Based on a sketch by Gilchrist 6/2/2014 1.0 @@ -35,7 +37,7 @@ boolean initial = 1; void setup(void) { tft.init(); - tft.setRotation(2); + tft.setRotation(0); //tft.fillScreen(TFT_BLACK); //tft.fillScreen(TFT_RED); @@ -88,7 +90,7 @@ void setup(void) { void loop() { if (targetTime < millis()) { - targetTime = millis()+1000; + targetTime += 1000; ss++; // Advance second if (ss==60) { ss=0; diff --git a/examples/ILI9341/TFT_Clock_Digital/TFT_Clock_Digital.ino b/examples/ILI9341/TFT_Clock_Digital/TFT_Clock_Digital.ino index 835aca9..ea26a2b 100644 --- a/examples/ILI9341/TFT_Clock_Digital/TFT_Clock_Digital.ino +++ b/examples/ILI9341/TFT_Clock_Digital/TFT_Clock_Digital.ino @@ -6,10 +6,11 @@ For a more accurate clock, it would be better to use the RTClib library. But this is just a demo... + 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 ###### - ###### TO SELECT THE FONTS AND PINS YOU USE, SEE ABOVE ###### ######################################################################### Based on clock sketch by Gilchrist 6/2/2014 1.0 diff --git a/examples/ILI9341/TFT_Ellipse/TFT_Ellipse.ino b/examples/ILI9341/TFT_Ellipse/TFT_Ellipse.ino index 3b1354a..7911d8b 100644 --- a/examples/ILI9341/TFT_Ellipse/TFT_Ellipse.ino +++ b/examples/ILI9341/TFT_Ellipse/TFT_Ellipse.ino @@ -20,7 +20,7 @@ void loop() { tft.fillScreen(TFT_BLACK); - // Draw some random circles + // Draw some random ellipses for (int i = 0; i < 40; i++) { int rx = random(60); diff --git a/examples/ILI9341/TFT_FillArcSpiral/TFT_FillArcSpiral.ino b/examples/ILI9341/TFT_FillArcSpiral/TFT_FillArcSpiral.ino index 32b3093..d26fb48 100644 --- a/examples/ILI9341/TFT_FillArcSpiral/TFT_FillArcSpiral.ino +++ b/examples/ILI9341/TFT_FillArcSpiral/TFT_FillArcSpiral.ino @@ -28,7 +28,7 @@ void setup(void) { void loop() { - fillArc(160, 120, segment*6, 1, 120-segment/4, 120-segment/4, 6, rainbow(col)); + fillArc(160, 120, segment*6, 1, 120-segment/4, 120-segment/4, 3, rainbow(col)); segment+=delta; col+=1; diff --git a/examples/ILI9341/TFT_Flash_Bitmap/Alert.h b/examples/ILI9341/TFT_Flash_Bitmap/Alert.h index 54d013d..44196a9 100644 --- a/examples/ILI9341/TFT_Flash_Bitmap/Alert.h +++ b/examples/ILI9341/TFT_Flash_Bitmap/Alert.h @@ -5,7 +5,6 @@ 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 diff --git a/examples/ILI9341/TFT_Flash_Bitmap/Close.h b/examples/ILI9341/TFT_Flash_Bitmap/Close.h index c16d522..b58ec12 100644 --- a/examples/ILI9341/TFT_Flash_Bitmap/Close.h +++ b/examples/ILI9341/TFT_Flash_Bitmap/Close.h @@ -5,7 +5,6 @@ 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 diff --git a/examples/ILI9341/TFT_Flash_Bitmap/Info.h b/examples/ILI9341/TFT_Flash_Bitmap/Info.h index c4ee633..bd66aae 100644 --- a/examples/ILI9341/TFT_Flash_Bitmap/Info.h +++ b/examples/ILI9341/TFT_Flash_Bitmap/Info.h @@ -5,7 +5,6 @@ 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 diff --git a/examples/ILI9341/TFT_Flash_Bitmap/TFT_Flash_Bitmap.ino b/examples/ILI9341/TFT_Flash_Bitmap/TFT_Flash_Bitmap.ino index 01a6639..081087c 100644 --- a/examples/ILI9341/TFT_Flash_Bitmap/TFT_Flash_Bitmap.ino +++ b/examples/ILI9341/TFT_Flash_Bitmap/TFT_Flash_Bitmap.ino @@ -9,18 +9,14 @@ 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 - - Performance is good enough for most applications: - A 32 x 32 icon can be drawn by a humble ESP8266 in ~3.6 milliseconds, i.e. ~280 icons per second! - A 320 x 240 screen can be completely filled with icons in about 270ms - Code derived from ILI9341_due example + + 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 // Hardware-specific library @@ -48,14 +44,14 @@ void setup() drawIcon(close, 180, 100, closeWidth, closeHeight); // Pause here to admire the icons! - delay(4000); + delay(2000); } void loop() { - // Loop filling and clearing screen to show draw speed - drawIcon(info, random(tft.width() - infoWidth), random(tft.height() - infoHeight), infoWidth, infoHeight); + // 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); @@ -65,7 +61,7 @@ void loop() 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()); + //Serial.println(millis()); } } diff --git a/examples/ILI9341/TFT_Float_Test/TFT_Float_Test.ino b/examples/ILI9341/TFT_Float_Test/TFT_Float_Test.ino index 19c9df9..910a995 100644 --- a/examples/ILI9341/TFT_Float_Test/TFT_Float_Test.ino +++ b/examples/ILI9341/TFT_Float_Test/TFT_Float_Test.ino @@ -21,10 +21,11 @@ BR_DATUM 8 //Bottom right Needs fonts 2 and 6 + 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 ###### - ###### TO SELECT THE FONTS AND PINS YOU USE, SEE ABOVE ###### ######################################################################### */ diff --git a/examples/ILI9341/TFT_Mandlebrot/TFT_Mandlebrot.ino b/examples/ILI9341/TFT_Mandlebrot/TFT_Mandlebrot.ino index 2986be5..73e0afc 100644 --- a/examples/ILI9341/TFT_Mandlebrot/TFT_Mandlebrot.ino +++ b/examples/ILI9341/TFT_Mandlebrot/TFT_Mandlebrot.ino @@ -1,6 +1,6 @@ // Mandlebrot -// This will run slowly due to the large number of calculations per pixel +// This will run quite slowly due to the large number of floating point calculations per pixel #include // Hardware-specific library #include @@ -17,10 +17,7 @@ uint16_t x0 = 0, x1 = 0, yy0 = 0, yy1 = 0; void setup() { //randomSeed(analogRead(A0)); - //pinMode(7, OUTPUT); - //digitalWrite(7, LOW); - //delay(10); - //digitalWrite(7, HIGH); + // Setup the LCD tft.init(); tft.setRotation(3); @@ -59,7 +56,7 @@ unsigned int rainbow(int value) { // Value is expected to be in range 0-127 // The value is converted to a spectrum colour from 0 = blue through to red = blue - //int value = random (128); + 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 diff --git a/examples/ILI9341/TFT_Matrix/TFT_Matrix.ino b/examples/ILI9341/TFT_Matrix/TFT_Matrix.ino index 2b9ba74..2e2e449 100644 --- a/examples/ILI9341/TFT_Matrix/TFT_Matrix.ino +++ b/examples/ILI9341/TFT_Matrix/TFT_Matrix.ino @@ -2,7 +2,16 @@ // Screen will flicker initially until fully drawn // then scroll smoothly -// Needs GLCD font enabled in User_Setup.h +// Needs GLCD font + +/* + 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 // Hardware-specific library #include @@ -11,7 +20,7 @@ TFT_eSPI tft = TFT_eSPI(); // Invoke custom library #define TEXT_HEIGHT 8 // Height of text to be printed and scrolled #define BOT_FIXED_AREA 0 // Number of lines in bottom fixed area (lines counted from bottom of screen) -#define TOP_FIXED_AREA 0 // Number of lines in top fixed area (lines counted from top of screen) +#define TOP_FIXED_AREA 0 // Number of lines in top fixed area (lines counted from top of screen) uint16_t yStart = TOP_FIXED_AREA; uint16_t yArea = 320 - TOP_FIXED_AREA - BOT_FIXED_AREA; @@ -21,21 +30,21 @@ uint16_t xPos = 0; void setup() { Serial.begin(115200); - //randomSeed(analogRead(A0)); + randomSeed(analogRead(A0)); tft.init(); - tft.setRotation(0); + tft.setRotation(2); tft.fillScreen(ILI9341_BLACK); setupScrollArea(TOP_FIXED_AREA, BOT_FIXED_AREA); } void loop(void) { - // First fill the screen with randomt streaks of characters + // First fill the screen with random streaks of characters for (int j = 0; j < 600; j += TEXT_HEIGHT) { for (int i = 0; i < 40; i++) { if (pos[i] > 20) pos[i] -= 3; // Rapid fade initially brightness values if (pos[i] > 0) pos[i] -= 1; // Slow fade later if ((random(20) == 1) && (j<400)) pos[i] = 63; // ~1 in 20 probability of a new character - tft.setTextColor(pos[i] << 5, ILI9341_BLACK); // Set the character brightness + tft.setTextColor(pos[i] << 5, ILI9341_BLACK); // Set the green character brightness if (pos[i] == 63) tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); // Draw white character xPos += tft.drawChar(random(32, 128), xPos, yDraw, 1); // Draw the character } @@ -49,7 +58,7 @@ void loop(void) { //tft.setRotation(0); // Now scroll smoothly forever - while (1) yDraw = scroll_slow(320,8); // Scroll 320 lines, 8ms per line + while (1) {yield(); yDraw = scroll_slow(320,5); }// Scroll 320 lines, 5ms per line } diff --git a/examples/ILI9341/TFT_Meter_linear/TFT_Meter_linear.ino b/examples/ILI9341/TFT_Meter_linear/TFT_Meter_linear.ino index a777ffe..e526000 100644 --- a/examples/ILI9341/TFT_Meter_linear/TFT_Meter_linear.ino +++ b/examples/ILI9341/TFT_Meter_linear/TFT_Meter_linear.ino @@ -1,13 +1,13 @@ /* An example analogue meter using a ILI9341 TFT LCD screen - This example uses the hardware SPI only Needs Font 2 (also Font 4 if using large scale label) + 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 ###### - ###### TO SELECT THE FONTS AND PINS YOU USE, SEE ABOVE ###### ######################################################################### Updated by Bodmer for variable meter size diff --git a/examples/ILI9341/TFT_Meters/TFT_Meters.ino b/examples/ILI9341/TFT_Meters/TFT_Meters.ino index 3218e6b..3521d0a 100644 --- a/examples/ILI9341/TFT_Meters/TFT_Meters.ino +++ b/examples/ILI9341/TFT_Meters/TFT_Meters.ino @@ -1,12 +1,15 @@ /* - Example animated analogue meters using a ILI9341 TFT LCD screen + Example animated analogue meters using a ILI9341 TFT LCD screen - Needs Font 2 (also Font 4 if using large scale label) + Needs Font 2 (also Font 4 if using large scale label) - Comment out lines 153 and 197 to reduce needle flicker and - to remove need for Font 4 (which uses ~5k of FLASH!) + 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 // Hardware-specific library #include @@ -15,6 +18,8 @@ TFT_eSPI tft = TFT_eSPI(); // Invoke custom library #define TFT_GREY 0x5AEB +#define LOOP_PERIOD 35 // Display updates every 35 ms + 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 @@ -49,16 +54,11 @@ void setup(void) { void loop() { if (updateTime <= millis()) { - updateTime = millis() + 35; - + updateTime = millis() + LOOP_PERIOD; + 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); @@ -67,11 +67,13 @@ void loop() { 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 + + //unsigned long t = millis(); + + plotPointer(); + + plotNeedle(value[0], 0); + //Serial.println(millis()-t); // Print time taken for meter update } } @@ -235,7 +237,7 @@ 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.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); @@ -248,10 +250,10 @@ void plotLinear(char *label, int x, int y) { 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.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); } diff --git a/examples/ILI9341/TFT_Pie_Chart/TFT_Pie_Chart.ino b/examples/ILI9341/TFT_Pie_Chart/TFT_Pie_Chart.ino index 459d262..b239049 100644 --- a/examples/ILI9341/TFT_Pie_Chart/TFT_Pie_Chart.ino +++ b/examples/ILI9341/TFT_Pie_Chart/TFT_Pie_Chart.ino @@ -22,7 +22,8 @@ void setup(void) } void loop() { - + + // Draw 4 pie chart segments fillSegment(160, 120, 0, 60, 100, TFT_RED); fillSegment(160, 120, 60, 30, 100, TFT_GREEN); fillSegment(160, 120, 60 + 30, 120, 100, TFT_BLUE); @@ -30,6 +31,7 @@ void loop() { delay(4000); + // Erase old chart with 360 degree black plot fillSegment(160, 120, 0, 360, 100, TFT_BLACK); } diff --git a/examples/ILI9341/TFT_Pong/TFT_Pong.ino b/examples/ILI9341/TFT_Pong/TFT_Pong.ino index 2302b53..6cf91f2 100644 --- a/examples/ILI9341/TFT_Pong/TFT_Pong.ino +++ b/examples/ILI9341/TFT_Pong/TFT_Pong.ino @@ -100,7 +100,7 @@ void initgame() { tft.setTextDatum(TC_DATUM); tft.setTextColor(WHITE,GREY); - //tft.drawString("TFT_eSPI example", w/2, h-26 , 4); + tft.drawString("TFT_eSPI example", w/2, h-26 , 4); } void midline() { diff --git a/examples/ILI9341/TFT_Print_Test/TFT_Print_Test.ino b/examples/ILI9341/TFT_Print_Test/TFT_Print_Test.ino index 4fe3ecb..a4fd703 100644 --- a/examples/ILI9341/TFT_Print_Test/TFT_Print_Test.ino +++ b/examples/ILI9341/TFT_Print_Test/TFT_Print_Test.ino @@ -3,10 +3,11 @@ This sketch used font 2, 4, 7 + 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 ###### - ###### TO SELECT THE FONTS AND PINS YOU USE, SEE ABOVE ###### ######################################################################### */ diff --git a/examples/ILI9341/TFT_Rainbow_one_lib/TFT_Rainbow_one_lib.ino b/examples/ILI9341/TFT_Rainbow_one_lib/TFT_Rainbow_one_lib.ino index b9f4b7f..dce909d 100644 --- a/examples/ILI9341/TFT_Rainbow_one_lib/TFT_Rainbow_one_lib.ino +++ b/examples/ILI9341/TFT_Rainbow_one_lib/TFT_Rainbow_one_lib.ino @@ -4,10 +4,11 @@ This sketch uses the GLCD, 2, 4, 6 fonts 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 ###### - ###### TO SELECT THE FONTS AND PINS YOU USE, SEE ABOVE ###### ######################################################################### */ diff --git a/examples/ILI9341/TFT_Spiro/TFT_Spiro.ino b/examples/ILI9341/TFT_Spiro/TFT_Spiro.ino index 6313756..3e7f8d7 100644 --- a/examples/ILI9341/TFT_Spiro/TFT_Spiro.ino +++ b/examples/ILI9341/TFT_Spiro/TFT_Spiro.ino @@ -6,6 +6,8 @@ TFT_eSPI tft = TFT_eSPI(); // Invoke custom library +#define DEG2RAD 0.0174532925 // Convert angles in degrees to radians + unsigned long runTime = 0; float sx = 0, sy = 0; @@ -14,10 +16,7 @@ uint16_t x0 = 0, x1 = 0, yy0 = 0, yy1 = 0; void setup() { //randomSeed(analogRead(A0)); - //pinMode(7, OUTPUT); - //digitalWrite(7, LOW); - //delay(10); - //digitalWrite(7, HIGH); + // Setup the LCD tft.init(); tft.setRotation(3); @@ -31,14 +30,14 @@ void loop() int n = random(2, 23), r = random(20, 100), colour = 0; //rainbow(); for (long i = 0; i < (360 * n); i++) { - sx = cos((i / n - 90) * 0.0174532925); - sy = sin((i / n - 90) * 0.0174532925); + sx = cos((i / n - 90) * DEG2RAD); + sy = sin((i / n - 90) * DEG2RAD); x0 = sx * (120 - r) + 159; yy0 = sy * (120 - r) + 119; - sy = cos(((i % 360) - 90) * 0.0174532925); - sx = sin(((i % 360) - 90) * 0.0174532925); + sy = cos(((i % 360) - 90) * DEG2RAD); + sx = sin(((i % 360) - 90) * DEG2RAD); x1 = sx * r + x0; yy1 = sy * r + yy0; tft.drawPixel(x1, yy1, rainbow(map(i%360,0,360,0,127))); //colour); @@ -46,14 +45,14 @@ void loop() r = random(20, 100);//r = r / random(2,4); for (long i = 0; i < (360 * n); i++) { - sx = cos((i / n - 90) * 0.0174532925); - sy = sin((i / n - 90) * 0.0174532925); + sx = cos((i / n - 90) * DEG2RAD); + sy = sin((i / n - 90) * DEG2RAD); x0 = sx * (120 - r) + 159; yy0 = sy * (120 - r) + 119; - sy = cos(((i % 360) - 90) * 0.0174532925); - sx = sin(((i % 360) - 90) * 0.0174532925); + sy = cos(((i % 360) - 90) * DEG2RAD); + sx = sin(((i % 360) - 90) * DEG2RAD); x1 = sx * r + x0; yy1 = sy * r + yy0; tft.drawPixel(x1, yy1, rainbow(map(i%360,0,360,0,127))); //colour); diff --git a/examples/ILI9341/TFT_Starfield/TFT_Starfield.ino b/examples/ILI9341/TFT_Starfield/TFT_Starfield.ino index 4d2822d..ccc4b44 100644 --- a/examples/ILI9341/TFT_Starfield/TFT_Starfield.ino +++ b/examples/ILI9341/TFT_Starfield/TFT_Starfield.ino @@ -1,7 +1,4 @@ -// Animates 256 white pixels to simulate flying through a star field - -// Demonstrates use of the fastPixel() function in the library -// which is about 15% faster than drawPixel() +// Animates white pixels to simulate flying through a star field #include #include @@ -9,8 +6,8 @@ // Use hardware SPI TFT_eSPI tft = TFT_eSPI(); -// With 256 stars the update frame rate is about 45Hz -#define NSTARS 256 +// With 1024 stars the update rate is ~65 frames per second +#define NSTARS 1024 uint8_t sx[NSTARS] = {}; uint8_t sy[NSTARS] = {}; uint8_t sz[NSTARS] = {}; @@ -85,7 +82,8 @@ void loop() unsigned long t1 = micros(); //static char timeMicros[8] = {}; - Serial.println(t1 - t0); + // Calcualte frames per second + Serial.println(1.0/((t1 - t0)/1000000.0)); } diff --git a/examples/ILI9341/TFT_String_Align/TFT_String_Align.ino b/examples/ILI9341/TFT_String_Align/TFT_String_Align.ino index 97a2413..9e3a71c 100644 --- a/examples/ILI9341/TFT_String_Align/TFT_String_Align.ino +++ b/examples/ILI9341/TFT_String_Align/TFT_String_Align.ino @@ -17,10 +17,11 @@ BR_DATUM = Bottom right Needs fonts 2, 4, 6, 7 and 8 + 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 ###### - ###### TO SELECT THE FONTS AND PINS YOU USE, SEE ABOVE ###### ######################################################################### */ diff --git a/examples/ILI9341/TFT_Terminal/TFT_Terminal.ino b/examples/ILI9341/TFT_Terminal/TFT_Terminal.ino index d93f4e5..c204302 100644 --- a/examples/ILI9341/TFT_Terminal/TFT_Terminal.ino +++ b/examples/ILI9341/TFT_Terminal/TFT_Terminal.ino @@ -23,14 +23,6 @@ redistribution *************************************************************/ -// In most cases characters don't get lost at 9600 baud but -// it is a good idea to increase the serial Rx buffer from 64 -// to 512 or 1024 bytes especially if higher baud rates are -// used (this sketch does not need much RAM). -// The method described here works well: -// http://www.hobbytronics.co.uk/arduino-serial-buffer-size -// - #include // Hardware-specific library #include diff --git a/examples/ILI9341/TFT_graphicstest_PDQ/TFT_graphicstest_PDQ.ino b/examples/ILI9341/TFT_graphicstest_PDQ/TFT_graphicstest_PDQ.ino index 0cfc894..7db002e 100644 --- a/examples/ILI9341/TFT_graphicstest_PDQ/TFT_graphicstest_PDQ.ino +++ b/examples/ILI9341/TFT_graphicstest_PDQ/TFT_graphicstest_PDQ.ino @@ -1,23 +1,21 @@ /* Adapted from the Adafruit and Xark's PDQ graphicstest sketch. + See end of file for original header text and MIT license info. + This sketch uses the GLCD font 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 ###### - ###### TO SELECT THE FONTS AND PINS YOU USE, SEE ABOVE ###### ######################################################################### */ - #include "SPI.h" #include "TFT_eSPI.h" -// These are used to get information about static SRAM and flash memory sizes -extern "C" char __data_start[]; // start of SRAM data -extern "C" char _end[]; // end of SRAM data (used to check amount of SRAM this program's variables use) -extern "C" char __data_load_end[]; // end of FLASH (used to check amount of Flash this program's code and data uses) - // Use hardware SPI TFT_eSPI tft = TFT_eSPI(); @@ -26,17 +24,14 @@ unsigned long tn = 0; void setup() { Serial.begin(115200); while (!Serial); - Serial.println("Bodmer's 2.2\" SPI TFT Test!"); + Serial.println(""); Serial.println(""); + Serial.println("Bodmer's TFT_eSPI library Test!"); tft.init(); } void loop(void) { - Serial.print(F(__DATE__ " " __TIME__ " - Flash=0x")); - //Serial.print((uint16_t)__data_load_end, HEX); - Serial.print(F(" RAM=0x")); - //Serial.println((uint16_t)_end - (uint16_t)__data_start, HEX); Serial.println(F("Benchmark Time (microseconds)")); @@ -126,21 +121,18 @@ void loop(void) tft.setTextColor(TFT_MAGENTA); tft.setTextSize(2); - tft.println(F(" TFT_eSPI ")); + tft.println(F(" TFT_eSPI test")); tft.setTextSize(1); tft.setTextColor(TFT_WHITE); - tft.println(F(" SPI LCD Benchmark (Atmega328p @ 16MHz)")); + tft.println(F("")); tft.setTextSize(1); tft.println(F("")); tft.setTextColor(tft.color565(0x80, 0x80, 0x80)); - tft.print(F(" Memory Used: Flash=0x")); - //tft.print((uint16_t)__data_load_end, HEX); - tft.print(F(" RAM=0x")); - // tft.println((uint16_t)_end - (uint16_t)__data_start, HEX); - tft.println(F("")); + tft.println(F("")); + tft.setTextColor(TFT_GREEN); tft.println(F(" Benchmark microseconds")); tft.println(F("")); diff --git a/examples/ILI9341/TFT_graphicstest_one_lib/TFT_graphicstest_one_lib.ino b/examples/ILI9341/TFT_graphicstest_one_lib/TFT_graphicstest_one_lib.ino index 77d1d54..553304d 100644 --- a/examples/ILI9341/TFT_graphicstest_one_lib/TFT_graphicstest_one_lib.ino +++ b/examples/ILI9341/TFT_graphicstest_one_lib/TFT_graphicstest_one_lib.ino @@ -1,102 +1,106 @@ /* - Adapted from the Adafruit graphicstest sketch. + 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 ###### - ###### TO SELECT THE FONTS AND PINS YOU USE, SEE ABOVE ###### ######################################################################### - */ +*/ #include "SPI.h" #include "TFT_eSPI.h" -// Use hardware SPI TFT_eSPI tft = TFT_eSPI(); unsigned long total = 0; unsigned long tn = 0; void setup() { - yield();Serial.begin(9600); + Serial.begin(9600); while (!Serial); - yield();Serial.println("TFT_eSPI 2.2\" SPI TFT Test!"); - + 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.println(F("Benchmark Time (microseconds)")); - yield();Serial.print(F("Screen fill ")); - yield();Serial.println(testFillScreen()); + yield(); Serial.print(F("Screen fill ")); + yield(); Serial.println(testFillScreen()); //total+=testFillScreen(); //delay(500); - yield();Serial.print(F("Text ")); - yield();Serial.println(testText()); + yield(); Serial.print(F("Text ")); + yield(); Serial.println(testText()); //total+=testText(); //delay(3000); - yield();Serial.print(F("Lines ")); - yield();Serial.println(testLines(TFT_CYAN)); + 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)); + 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)); + 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)); + 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)); + 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)); + + 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()); + yield(); Serial.print(F("Triangles (outline) ")); + yield(); Serial.println(testTriangles()); //total+=testTriangles(); //delay(500); - yield();Serial.print(F("Triangles (filled) ")); - yield();Serial.println(testFilledTriangles()); + 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()); + 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()); + yield(); Serial.print(F("Rounded rects (filled) ")); + yield(); Serial.println(testFilledRoundRects()); //total+=testFilledRoundRects(); //delay(500); - yield();Serial.print(F("Done! Total = ")); yield();Serial.println(total); - + 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++) { + for (uint8_t rotation = 0; rotation < 4; rotation++) { tft.setRotation(rotation); testText(); delay(2000); @@ -153,9 +157,9 @@ unsigned long testLines(uint16_t color) { x1 = y1 = 0; y2 = h - 1; start = micros(); - for(x2=0; x20; i-=6) { + for (i = n - 1; i > 0; i -= 6) { i2 = i / 2; start = micros(); - tft.fillRect(cx-i2, cy-i2, i, i, color1); + 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); + tft.drawRect(cx - i2, cy - i2, i, i, color2); } return t; @@ -248,8 +252,8 @@ unsigned long testFilledCircles(uint8_t radius, uint16_t color) { tft.fillScreen(TFT_BLACK); start = micros(); - for(x=radius; x10; i-=5) { + 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)); + 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)); + tft.color565(i, i, 0)); } return t; @@ -322,9 +326,9 @@ unsigned long testRoundRects() { tft.fillScreen(TFT_BLACK); w = min(tft.width(), tft.height()); start = micros(); - for(i=0; i20; i-=6) { + 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)); + tft.fillRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(0, i, 0)); } return micros() - start; @@ -352,7 +356,7 @@ unsigned long testFilledRoundRects() { 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) @@ -363,4 +367,4 @@ unsigned long testFilledRoundRects() { Written by Limor Fried/Ladyada for Adafruit Industries. MIT license, all text above must be included in any redistribution ****************************************************/ - + diff --git a/examples/ILI9341/UTFT_demo/UTFT_demo.ino b/examples/ILI9341/UTFT_demo/UTFT_demo.ino index 2fe5419..c10b562 100644 --- a/examples/ILI9341/UTFT_demo/UTFT_demo.ino +++ b/examples/ILI9341/UTFT_demo/UTFT_demo.ino @@ -4,43 +4,14 @@ // /* - This sketch uses the GLCD and font 2 only. Disable other fonts to make - the sketch fit in an UNO! + This sketch uses the GLCD and font 2 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. - Make sure all the required fonts are loaded by editting the - User_Setup.h file in the TFT_eSPI library folder. - - If using an UNO or Mega (ATmega328 or ATmega2560 processor) then for best - performance use the F_AS_T option found in the User_Setup.h file in the - TFT_eSPI library folder. - - The library uses the hardware SPI pins only: - For UNO, Nano, Micro Pro ATmega328 based processors - MOSI = pin 11, SCK = pin 13 - For Mega: - MOSI = pin 51, SCK = pin 52 - - The pins used for the TFT chip select (CS) and Data/command (DC) and Reset (RST) - signal lines to the TFT must also be defined in the library User_Setup.h file. - - Sugested TFT connections for UNO and Atmega328 based boards - sclk 13 // Don't change, this is the hardware SPI SCLK line - mosi 11 // Don't change, this is the hardware SPI MOSI line - cs 10 // Chip select for TFT display - dc 9 // Data/command line - rst 7 // Reset, you could connect this to the Arduino reset pin - - Suggested TFT connections for the MEGA and ATmega2560 based boards - sclk 52 // Don't change, this is the hardware SPI SCLK line - mosi 51 // Don't change, this is the hardware SPI MOSI line - cs 47 // TFT chip select line - dc 48 // TFT data/command line - rst 44 // you could alternatively connect this to the Arduino reset - - ######################################################################### - ###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ###### - ###### TO SELECT THE FONTS AND PINS YOU USE, SEE ABOVE ###### - ######################################################################### + ######################################################################### + ###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ###### + ######################################################################### */ #include "SPI.h" diff --git a/examples/ILI9341/weather-station-v6/ArialRoundedMTBold_36.h b/examples/ILI9341/weather-station-v6/ArialRoundedMTBold_36.h new file mode 100644 index 0000000..767147c --- /dev/null +++ b/examples/ILI9341/weather-station-v6/ArialRoundedMTBold_36.h @@ -0,0 +1,226 @@ +/**The MIT License (MIT) +Copyright (c) 2015 by Daniel Eichhorn +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. +See more at http://blog.squix.ch +*/ + +// Created by http://oleddisplay.squix.ch/ Consider a donation +// In case of problems make sure that you are using the font file with the correct version! + +// Bodmer fix: End character is 0x7D not 0x7E, so bug in last line of the file corrected +// this avoids screen corruption if ~ is printer + +// Bodmer change: '`' changed to tiny degree symbol (typically this character is on top left key of a QWERTY keyboard) + +const uint8_t ArialRoundedMTBold_36Bitmaps[] PROGMEM = { + + // Bitmap Data: + 0x00, // ' ' + 0x77,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0x39,0xCE,0x73,0x00,0x00,0x3B,0xFF,0xFB,0x80, // '!' + 0xFC,0xFF,0xF3,0xFF,0xCF,0xFF,0x3F,0xFC,0xFF,0xF3,0xFF,0xCF,0xDE,0x1E,0x78,0x78, // '"' + 0x01,0x83,0x80,0x78,0x70,0x0F,0x0E,0x01,0xC3,0xC0,0x78,0x78,0x0F,0x0F,0x01,0xE1,0xE3,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0x07,0x87,0x80,0xF0,0xE0,0x1E,0x3C,0x07,0x87,0x80,0xF0,0xF0,0x7F,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xE3,0xC3,0xC0,0x78,0x78,0x0F,0x0E,0x01,0xC3,0xC0,0x78,0x78,0x07,0x06,0x00, // '#' + 0x00,0x60,0x00,0x0C,0x00,0x01,0x80,0x00,0x30,0x00,0x7F,0xE0,0x3F,0xFE,0x0F,0xFF,0xE1,0xF3,0x7E,0x7C,0x67,0xCF,0x0C,0x79,0xE1,0x8F,0x3C,0x30,0xC7,0xC6,0x00,0xFE,0xC0,0x0F,0xF8,0x00,0xFF,0xE0,0x0F,0xFF,0x00,0x7F,0xF0,0x01,0xFF,0x00,0x37,0xE0,0x06,0x3E,0xE0,0xC3,0xFC,0x18,0x7F,0xC3,0x0F,0xF8,0x61,0xEF,0x8C,0x79,0xFD,0x9F,0x1F,0xFF,0xC1,0xFF,0xF0,0x0F,0xFC,0x00,0x38,0x00,0x03,0x00,0x00,0x60,0x00,0x0C,0x00,0x01,0x80,0x00,0x30,0x00,0x06,0x00, // '$' + 0x1F,0x00,0x06,0x03,0xFC,0x00,0x70,0x1C,0x70,0x03,0x01,0xC1,0x80,0x38,0x0E,0x0E,0x03,0x80,0x70,0x70,0x1C,0x03,0x83,0x81,0xC0,0x1C,0x1C,0x0C,0x00,0xE0,0xE0,0xE0,0x07,0x07,0x0E,0x00,0x1C,0x70,0x70,0x00,0xFF,0x87,0x00,0x03,0xF8,0x30,0x00,0x00,0x03,0x87,0xF0,0x00,0x38,0x7F,0xC0,0x01,0xC3,0x8E,0x00,0x1C,0x38,0x38,0x00,0xC1,0xC1,0xC0,0x0E,0x0E,0x0E,0x00,0xE0,0x70,0x70,0x07,0x03,0x83,0x80,0x70,0x1C,0x1C,0x07,0x00,0xE0,0xE0,0x38,0x03,0x8E,0x03,0x80,0x0F,0xE0,0x1C,0x00,0x3E,0x00,0xC0,0x00,0x00, // '%' + 0x00,0xFC,0x00,0x01,0xFF,0x80,0x01,0xFF,0xE0,0x01,0xF0,0xF0,0x00,0xF0,0x3C,0x00,0x78,0x1E,0x00,0x3C,0x0F,0x00,0x1F,0x0F,0x80,0x0F,0xDF,0x80,0x03,0xFF,0x80,0x00,0xFF,0x80,0x00,0xFF,0x00,0x00,0xFF,0xC1,0x81,0xFF,0xF0,0xE1,0xF9,0xF8,0xF8,0xF8,0x7E,0x78,0xF8,0x1F,0xFC,0x7C,0x07,0xFC,0x3E,0x01,0xFE,0x1F,0x00,0x7F,0x0F,0xC0,0x3F,0xC3,0xF0,0x7F,0xF1,0xFF,0xFF,0xFC,0x7F,0xFF,0x3F,0x0F,0xFE,0x0F,0x01,0xFC,0x03,0x80, // '&' + 0xFF,0xFF,0xFF,0xFF,0xFF,0xDE,0x78, // ''' + 0x03,0x81,0xC1,0xC1,0xE0,0xF0,0xF0,0xF8,0x78,0x3C,0x3E,0x1F,0x0F,0x0F,0x87,0xC3,0xE1,0xF0,0xF8,0x7C,0x3E,0x1F,0x0F,0x83,0xC1,0xF0,0xF8,0x3C,0x1E,0x0F,0x83,0xC0,0xF0,0x78,0x1C,0x07,0x01,0x80, // '(' + 0xE0,0x70,0x1C,0x0F,0x03,0x81,0xE0,0xF8,0x3C,0x1E,0x0F,0x87,0xC1,0xE0,0xF8,0x7C,0x3E,0x1F,0x0F,0x87,0xC3,0xE1,0xF0,0xF8,0x78,0x7C,0x3E,0x1E,0x0F,0x0F,0x87,0x83,0x83,0xC1,0xC1,0xC0,0xE0,0x00, // ')' + 0x03,0x80,0x07,0x00,0x0E,0x00,0x1C,0x0E,0x38,0xFF,0x77,0xDF,0xFF,0x07,0xF0,0x07,0xC0,0x1D,0xC0,0x3B,0xC0,0xE3,0x83,0xC7,0x83,0x06,0x00, // '*' + 0x01,0xF0,0x00,0x3E,0x00,0x07,0xC0,0x00,0xF8,0x00,0x1F,0x00,0x03,0xE0,0x00,0x7C,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x1F,0x00,0x03,0xE0,0x00,0x7C,0x00,0x0F,0x80,0x01,0xF0,0x00,0x3E,0x00, // '+' + 0x7B,0xEF,0xFF,0x7C,0x71,0xCE,0x7B,0xCE,0x00, // ',' + 0x7F,0xDF,0xFF,0xFF,0xBF,0xE0, // '-' + 0x77,0xFF,0xF7,0x00, // '.' + 0x03,0x81,0xC1,0xE0,0xF0,0x70,0x78,0x3C,0x1E,0x0E,0x07,0x07,0x83,0xC1,0xC0,0xE0,0xF0,0x78,0x38,0x1C,0x1E,0x0F,0x07,0x03,0x83,0xC1,0xE0,0xE0,0x70,0x00, // '/' + 0x03,0xF0,0x03,0xFF,0x01,0xFF,0xE0,0xFF,0xFC,0x3E,0x1F,0x1F,0x03,0xE7,0xC0,0xF9,0xE0,0x1E,0xF8,0x07,0xFE,0x01,0xFF,0x80,0x7F,0xE0,0x1F,0xF8,0x07,0xFE,0x01,0xFF,0x80,0x7F,0xE0,0x1F,0xF8,0x07,0xFE,0x01,0xF7,0x80,0x79,0xF0,0x3E,0x7C,0x0F,0x8F,0x87,0xC3,0xFF,0xF0,0x7F,0xF8,0x0F,0xFC,0x00,0xFC,0x00, // '0' + 0x00,0x30,0x03,0xC0,0x3E,0x03,0xF0,0x3F,0x83,0xFC,0x7F,0xEF,0xDF,0xFC,0xFF,0xC7,0xD8,0x3E,0x01,0xF0,0x0F,0x80,0x7C,0x03,0xE0,0x1F,0x00,0xF8,0x07,0xC0,0x3E,0x01,0xF0,0x0F,0x80,0x7C,0x03,0xE0,0x1F,0x00,0xF8,0x03,0x80, // '1' + 0x03,0xF8,0x03,0xFF,0x83,0xFF,0xF0,0xFF,0xFE,0x7E,0x1F,0x9F,0x03,0xFF,0x80,0x7F,0xE0,0x1F,0xF0,0x07,0xD8,0x01,0xF0,0x00,0xF8,0x00,0x7E,0x00,0x1F,0x00,0x1F,0x80,0x0F,0xC0,0x07,0xE0,0x03,0xF0,0x01,0xF8,0x00,0xFC,0x00,0x7E,0x00,0x3F,0x00,0x1F,0x80,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xF0, // '2' + 0x03,0xF0,0x07,0xFF,0x03,0xFF,0xE1,0xF0,0xFC,0x78,0x1F,0x1E,0x03,0xE7,0x00,0xF8,0x80,0x3E,0x00,0x1F,0x00,0x0F,0xC0,0x7F,0xE0,0x1F,0xF0,0x07,0xFE,0x01,0xFF,0xC0,0x01,0xF8,0x00,0x3F,0x00,0x07,0xD8,0x01,0xFF,0x00,0x7F,0xE0,0x1F,0xF8,0x0F,0x9F,0x07,0xE7,0xFF,0xF0,0xFF,0xF8,0x1F,0xFC,0x01,0xFC,0x00, // '3' + 0x00,0x0F,0x00,0x00,0xFC,0x00,0x07,0xE0,0x00,0x7F,0x00,0x07,0xF8,0x00,0x7F,0xC0,0x03,0xFE,0x00,0x3D,0xF0,0x03,0xCF,0x80,0x3C,0x7C,0x03,0xE3,0xE0,0x1E,0x1F,0x01,0xE0,0xF8,0x1E,0x07,0xC1,0xF0,0x3E,0x0F,0x01,0xF0,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xE0,0x00,0xF8,0x00,0x07,0xC0,0x00,0x3E,0x00,0x01,0xF0,0x00,0x0F,0x80,0x00,0x38,0x00, // '4' + 0x1F,0xFF,0x8F,0xFF,0xE3,0xFF,0xF8,0xFF,0xFC,0x3C,0x00,0x0F,0x00,0x07,0xC0,0x01,0xF0,0x00,0x78,0x00,0x1E,0x7E,0x07,0xFF,0xE1,0xFF,0xFC,0xFF,0xFF,0xBF,0x07,0xE7,0x80,0xFC,0x80,0x1F,0x00,0x07,0xC0,0x01,0xF6,0x00,0x7F,0xC0,0x1F,0xF0,0x0F,0xBE,0x03,0xE7,0xC1,0xF1,0xFF,0xF8,0x1F,0xFC,0x01,0xFC,0x00, // '5' + 0x03,0xF8,0x01,0xFF,0x81,0xFF,0xF0,0x7C,0x7C,0x3C,0x0F,0x9F,0x03,0xE7,0x80,0x71,0xE0,0x00,0xF8,0x00,0x3E,0x3E,0x0F,0xBF,0xE3,0xFF,0xFC,0xFE,0x1F,0xBF,0x03,0xEF,0x80,0x7F,0xE0,0x1F,0xF8,0x07,0xFE,0x01,0xF7,0x80,0x7D,0xF0,0x1F,0x7C,0x0F,0x8F,0x87,0xE3,0xFF,0xF0,0x7F,0xFC,0x0F,0xFC,0x00,0xFC,0x00, // '6' + 0x7F,0xFF,0xBF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0x00,0x0F,0x80,0x07,0xC0,0x01,0xE0,0x00,0xF8,0x00,0x7C,0x00,0x1E,0x00,0x0F,0x80,0x03,0xC0,0x01,0xF0,0x00,0x78,0x00,0x3E,0x00,0x0F,0x80,0x07,0xC0,0x01,0xF0,0x00,0x7C,0x00,0x3F,0x00,0x0F,0x80,0x03,0xE0,0x00,0xF8,0x00,0x3E,0x00,0x0F,0x80,0x01,0xC0,0x00, // '7' + 0x03,0xF8,0x01,0xFF,0xC0,0x7F,0xFC,0x1F,0x0F,0xC7,0xC0,0xFC,0xF8,0x0F,0x9F,0x01,0xF3,0xE0,0x3E,0x7C,0x07,0xCF,0x80,0xF0,0xF8,0x7E,0x0F,0xFF,0x80,0xFF,0xE0,0x7F,0xFE,0x1F,0x83,0xF3,0xE0,0x3E,0xF8,0x03,0xFF,0x00,0x7F,0xE0,0x0F,0xFC,0x01,0xFF,0x80,0x3E,0xF8,0x0F,0x9F,0x83,0xF1,0xFF,0xFC,0x1F,0xFF,0x00,0x7F,0x00, // '8' + 0x03,0xF0,0x03,0xFF,0x03,0xFF,0xE0,0xFF,0xFC,0x7E,0x1F,0x1F,0x03,0xEF,0x80,0xFB,0xE0,0x1E,0xF8,0x07,0xFE,0x01,0xFF,0x80,0x7F,0xE0,0x1F,0x7C,0x0F,0xDF,0x87,0xF3,0xFF,0xFC,0x7F,0xDF,0x07,0xC7,0xC0,0x01,0xF0,0x00,0x78,0xE0,0x1E,0x78,0x0F,0x9F,0x03,0xC3,0xE3,0xE0,0xFF,0xF8,0x1F,0xF8,0x01,0xF8,0x00, // '9' + 0x77,0xFF,0xF7,0x00,0x00,0x00,0x00,0x00,0x01,0xDF,0xFF,0xDC, // ':' + 0x77,0xFF,0xF7,0x00,0x00,0x00,0x00,0x00,0x01,0xDE,0xFF,0xFE,0x73,0x9B,0xDC,0xC0, // ';' + 0x00,0x00,0x40,0x00,0x70,0x00,0xFC,0x00,0xFF,0x00,0xFF,0xC1,0xFF,0xE1,0xFF,0xC1,0xFF,0xC0,0xFF,0x80,0x3F,0x80,0x0F,0xE0,0x03,0xFE,0x00,0x7F,0xF0,0x07,0xFF,0x00,0x7F,0xF8,0x03,0xFF,0x00,0x3F,0xC0,0x03,0xF0,0x00,0x1C,0x00,0x01, // '<' + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0, // '=' + 0x80,0x00,0x38,0x00,0x0F,0xC0,0x03,0xFC,0x00,0xFF,0xC0,0x1F,0xFE,0x00,0xFF,0xE0,0x0F,0xFE,0x00,0x7F,0xC0,0x07,0xF0,0x01,0xFC,0x01,0xFF,0x03,0xFF,0x83,0xFF,0x87,0xFF,0x83,0xFF,0x00,0xFF,0x00,0x3F,0x00,0x0E,0x00,0x02,0x00,0x00, // '>' + 0x03,0xF8,0x03,0xFF,0x83,0xFF,0xF0,0xFF,0xFE,0x7E,0x1F,0xBF,0x03,0xFF,0x80,0x7F,0xE0,0x1F,0x70,0x07,0xC8,0x03,0xE0,0x01,0xF8,0x00,0xFC,0x00,0x7E,0x00,0x3F,0x00,0x0F,0x80,0x03,0xC0,0x01,0xF0,0x00,0x78,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x1F,0x00,0x07,0xC0,0x01,0xF0,0x00,0x38,0x00, // '?' + 0x00,0x07,0xFE,0x00,0x00,0x0F,0xFF,0xF0,0x00,0x0F,0xFF,0xFE,0x00,0x07,0xE0,0x0F,0xE0,0x07,0xC0,0x00,0x7C,0x03,0xE0,0x00,0x0F,0x00,0xE0,0x00,0x01,0xE0,0x70,0x1F,0x9F,0x3C,0x3C,0x1F,0xF7,0xC7,0x0E,0x0F,0xFF,0xE1,0xC7,0x07,0xE3,0xF8,0x39,0xC3,0xE0,0x7E,0x0E,0x70,0xF8,0x0F,0x83,0xB8,0x7C,0x03,0xE0,0xEE,0x1F,0x00,0xF0,0x3B,0x8F,0x80,0x3C,0x0E,0xE3,0xE0,0x1F,0x07,0xB8,0xF8,0x07,0xC1,0xCE,0x3E,0x01,0xE0,0xF3,0x8F,0x80,0xF8,0x78,0xE3,0xE0,0x3E,0x1E,0x1C,0x7C,0x1F,0x9F,0x07,0x1F,0xFF,0xFF,0x81,0xC3,0xFF,0xFF,0xC0,0x38,0x7F,0xBF,0xE0,0x0F,0x07,0x87,0xE0,0x01,0xE0,0x00,0x00,0x3C,0x3C,0x00,0x00,0x3E,0x07,0xC0,0x00,0x1F,0x00,0xFE,0x00,0x3F,0x80,0x1F,0xFF,0xFF,0x80,0x00,0xFF,0xFF,0x80,0x00,0x07,0xFF,0x00,0x00, // '@' + 0x00,0x3C,0x00,0x00,0x7E,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x01,0xFF,0x00,0x01,0xFF,0x80,0x01,0xEF,0x80,0x03,0xE7,0xC0,0x03,0xE7,0xC0,0x07,0xC7,0xC0,0x07,0xC3,0xE0,0x07,0xC3,0xE0,0x0F,0x81,0xF0,0x0F,0x81,0xF0,0x1F,0x81,0xF8,0x1F,0x00,0xF8,0x1F,0xFF,0xF8,0x3F,0xFF,0xFC,0x3F,0xFF,0xFC,0x7F,0xFF,0xFE,0x7C,0x00,0x7E,0x7C,0x00,0x3E,0xFC,0x00,0x3F,0xF8,0x00,0x1F,0xF8,0x00,0x1F,0x70,0x00,0x0E, // 'A' + 0x7F,0xFF,0x07,0xFF,0xFC,0x3F,0xFF,0xF1,0xFF,0xFF,0xCF,0x80,0x7F,0x7C,0x01,0xFB,0xE0,0x07,0xDF,0x00,0x3E,0xF8,0x01,0xF7,0xC0,0x1F,0x3E,0x01,0xF9,0xFF,0xFF,0x8F,0xFF,0xF0,0x7F,0xFF,0xE3,0xFF,0xFF,0x9F,0x00,0x7E,0xF8,0x01,0xFF,0xC0,0x07,0xFE,0x00,0x3F,0xF0,0x01,0xFF,0x80,0x1F,0xFC,0x01,0xFB,0xFF,0xFF,0xDF,0xFF,0xFC,0xFF,0xFF,0xC3,0xFF,0xF8,0x00, // 'B' + 0x00,0xFF,0x00,0x07,0xFF,0x80,0x3F,0xFF,0xC0,0xFF,0xFF,0xC3,0xF8,0x1F,0xC7,0xE0,0x1F,0x9F,0x80,0x1F,0x3E,0x00,0x1F,0x7C,0x00,0x3D,0xF0,0x00,0x33,0xE0,0x00,0x07,0xC0,0x00,0x0F,0x80,0x00,0x1F,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x04,0xF8,0x00,0x1C,0xF8,0x00,0x7D,0xF0,0x00,0xFB,0xF0,0x03,0xE3,0xF0,0x0F,0xC7,0xF0,0x3F,0x07,0xFF,0xFE,0x07,0xFF,0xF8,0x03,0xFF,0xC0,0x01,0xFE,0x00, // 'C' + 0x7F,0xFE,0x03,0xFF,0xFE,0x0F,0xFF,0xFC,0x3F,0xFF,0xF8,0xF8,0x07,0xF3,0xE0,0x07,0xEF,0x80,0x1F,0xBE,0x00,0x3E,0xF8,0x00,0xFF,0xE0,0x01,0xFF,0x80,0x07,0xFE,0x00,0x1F,0xF8,0x00,0x7F,0xE0,0x01,0xFF,0x80,0x07,0xFE,0x00,0x1F,0xF8,0x00,0x7F,0xE0,0x03,0xFF,0x80,0x0F,0xBE,0x00,0x7E,0xF8,0x01,0xFB,0xE0,0x1F,0xCF,0xFF,0xFE,0x3F,0xFF,0xF0,0xFF,0xFF,0x81,0xFF,0xF8,0x00, // 'D' + 0x7F,0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xEF,0xFF,0xFE,0xF8,0x00,0x0F,0x80,0x00,0xF8,0x00,0x0F,0x80,0x00,0xF8,0x00,0x0F,0x80,0x00,0xFF,0xFF,0xCF,0xFF,0xFC,0xFF,0xFF,0xCF,0xFF,0xFC,0xF8,0x00,0x0F,0x80,0x00,0xF8,0x00,0x0F,0x80,0x00,0xF8,0x00,0x0F,0x80,0x00,0xF8,0x00,0x0F,0x80,0x00,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFE, // 'E' + 0x7F,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xF8,0x00,0x3E,0x00,0x0F,0x80,0x03,0xE0,0x00,0xF8,0x00,0x3E,0x00,0x0F,0x80,0x03,0xFF,0xF8,0xFF,0xFF,0x3F,0xFF,0xCF,0xFF,0xE3,0xE0,0x00,0xF8,0x00,0x3E,0x00,0x0F,0x80,0x03,0xE0,0x00,0xF8,0x00,0x3E,0x00,0x0F,0x80,0x03,0xE0,0x00,0xF8,0x00,0x1C,0x00,0x00, // 'F' + 0x00,0x7F,0x80,0x03,0xFF,0xF0,0x07,0xFF,0xF8,0x1F,0xFF,0xFC,0x1F,0xC1,0xFE,0x3F,0x00,0x7E,0x7E,0x00,0x3E,0x7C,0x00,0x3E,0x7C,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0xF8,0x07,0xFE,0xF8,0x0F,0xFF,0xF8,0x0F,0xFF,0xF8,0x07,0xFF,0xF8,0x00,0x1F,0x7C,0x00,0x1F,0x7C,0x00,0x1F,0x7E,0x00,0x1F,0x3F,0x00,0x3F,0x1F,0xC0,0xFF,0x1F,0xFF,0xFE,0x07,0xFF,0xFC,0x03,0xFF,0xF0,0x00,0x7F,0x80, // 'G' + 0x70,0x00,0x77,0xC0,0x07,0xFE,0x00,0x3F,0xF0,0x01,0xFF,0x80,0x0F,0xFC,0x00,0x7F,0xE0,0x03,0xFF,0x00,0x1F,0xF8,0x00,0xFF,0xC0,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x03,0xFF,0x00,0x1F,0xF8,0x00,0xFF,0xC0,0x07,0xFE,0x00,0x3F,0xF0,0x01,0xFF,0x80,0x0F,0xFC,0x00,0x7F,0xE0,0x03,0xFF,0x00,0x1F,0xF8,0x00,0xFB,0x80,0x03,0x80, // 'H' + 0x77,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0x80, // 'I' + 0x00,0x07,0x00,0x07,0xC0,0x03,0xE0,0x01,0xF0,0x00,0xF8,0x00,0x7C,0x00,0x3E,0x00,0x1F,0x00,0x0F,0x80,0x07,0xC0,0x03,0xE0,0x01,0xF0,0x00,0xF8,0x00,0x7C,0x00,0x3E,0x00,0x1F,0x70,0x0F,0xFC,0x07,0xFE,0x03,0xFF,0x01,0xFF,0xC1,0xFB,0xF1,0xF9,0xFF,0xFC,0x7F,0xFC,0x1F,0xFC,0x03,0xF8,0x00, // 'J' + 0x70,0x00,0xE3,0xE0,0x07,0xCF,0x80,0x3F,0x3E,0x01,0xFC,0xF8,0x0F,0xE3,0xE0,0x7F,0x0F,0x83,0xF8,0x3E,0x1F,0xC0,0xF8,0xFE,0x03,0xE7,0xF0,0x0F,0xBF,0x80,0x3F,0xFF,0x00,0xFF,0xFC,0x03,0xFF,0xF8,0x0F,0xFB,0xF0,0x3F,0xCF,0xE0,0xFE,0x1F,0x83,0xE0,0x3F,0x0F,0x80,0xFE,0x3E,0x01,0xF8,0xF8,0x03,0xF3,0xE0,0x0F,0xEF,0x80,0x1F,0xBE,0x00,0x3F,0xF8,0x00,0xFD,0xC0,0x01,0xE0, // 'K' + 0x70,0x00,0x3E,0x00,0x0F,0x80,0x03,0xE0,0x00,0xF8,0x00,0x3E,0x00,0x0F,0x80,0x03,0xE0,0x00,0xF8,0x00,0x3E,0x00,0x0F,0x80,0x03,0xE0,0x00,0xF8,0x00,0x3E,0x00,0x0F,0x80,0x03,0xE0,0x00,0xF8,0x00,0x3E,0x00,0x0F,0x80,0x03,0xE0,0x00,0xF8,0x00,0x3E,0x00,0x0F,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xE0, // 'L' + 0x7E,0x00,0x3F,0x7F,0x80,0x3F,0xFF,0xE0,0x1F,0xFF,0xF0,0x1F,0xFF,0xF8,0x0F,0xFF,0xFC,0x07,0xFF,0xFF,0x07,0xFF,0xFF,0x83,0xFF,0xFB,0xC1,0xEF,0xFD,0xE0,0xF7,0xFE,0xF8,0xFB,0xFF,0x7C,0x7D,0xFF,0x9E,0x3C,0xFF,0xCF,0x1E,0x7F,0xE7,0xDF,0x3F,0xF3,0xEF,0x9F,0xF8,0xF7,0x8F,0xFC,0x7B,0xC7,0xFE,0x3F,0xE3,0xFF,0x1F,0xF1,0xFF,0x87,0xF0,0xFF,0xC3,0xF8,0x7F,0xE1,0xFC,0x3F,0xF0,0x7C,0x1F,0xF8,0x3E,0x0F,0xB8,0x0E,0x03,0x80, // 'M' + 0x78,0x00,0x3B,0xF0,0x01,0xFF,0xC0,0x07,0xFF,0x80,0x1F,0xFF,0x00,0x7F,0xFE,0x01,0xFF,0xF8,0x07,0xFF,0xF0,0x1F,0xFF,0xE0,0x7F,0xEF,0x81,0xFF,0x9F,0x07,0xFE,0x7E,0x1F,0xF8,0xF8,0x7F,0xE1,0xF1,0xFF,0x87,0xE7,0xFE,0x0F,0x9F,0xF8,0x1F,0x7F,0xE0,0x7F,0xFF,0x80,0xFF,0xFE,0x01,0xFF,0xF8,0x07,0xFF,0xE0,0x0F,0xFF,0x80,0x1F,0xFE,0x00,0x7F,0xF8,0x00,0xFD,0xC0,0x01,0xE0, // 'N' + 0x00,0xFF,0x00,0x01,0xFF,0xF0,0x03,0xFF,0xFE,0x03,0xFF,0xFF,0x83,0xFC,0x1F,0xE1,0xF8,0x03,0xF1,0xF8,0x00,0xFC,0xF8,0x00,0x3E,0x7C,0x00,0x1F,0x7C,0x00,0x07,0xFE,0x00,0x03,0xFF,0x00,0x01,0xFF,0x80,0x00,0xFF,0xC0,0x00,0x7F,0xE0,0x00,0x3F,0xF0,0x00,0x1F,0xFC,0x00,0x0F,0xBE,0x00,0x0F,0x9F,0x00,0x07,0xCF,0xC0,0x07,0xE3,0xF0,0x07,0xE0,0xFE,0x0F,0xF0,0x7F,0xFF,0xF0,0x1F,0xFF,0xF0,0x03,0xFF,0xE0,0x00,0x3F,0xC0,0x00, // 'O' + 0x7F,0xFC,0x1F,0xFF,0xE3,0xFF,0xFE,0x7F,0xFF,0xEF,0x80,0xFD,0xF0,0x0F,0xFE,0x00,0xFF,0xC0,0x1F,0xF8,0x03,0xFF,0x00,0x7F,0xE0,0x1F,0xFC,0x07,0xEF,0xFF,0xFD,0xFF,0xFF,0x3F,0xFF,0xC7,0xFF,0xE0,0xF8,0x00,0x1F,0x00,0x03,0xE0,0x00,0x7C,0x00,0x0F,0x80,0x01,0xF0,0x00,0x3E,0x00,0x07,0xC0,0x00,0xF8,0x00,0x0E,0x00,0x00, // 'P' + 0x00,0xFF,0x00,0x00,0xFF,0xF8,0x00,0xFF,0xFF,0x80,0x7F,0xFF,0xF0,0x3F,0xC1,0xFE,0x0F,0xC0,0x1F,0x87,0xE0,0x03,0xF1,0xF0,0x00,0x7C,0x7C,0x00,0x1F,0x3E,0x00,0x03,0xEF,0x80,0x00,0xFB,0xE0,0x00,0x3E,0xF8,0x00,0x0F,0xBE,0x00,0x03,0xEF,0x80,0x00,0xFB,0xE0,0x00,0x3E,0xF8,0x00,0x0F,0x9F,0x07,0x07,0xC7,0xC1,0xF1,0xF1,0xF8,0x3F,0xFC,0x3F,0x03,0xFE,0x07,0xF0,0x7F,0x81,0xFF,0xFF,0xC0,0x1F,0xFF,0xF8,0x03,0xFF,0xFF,0x80,0x1F,0xE3,0xF0,0x00,0x00,0x7C,0x00,0x00,0x07, // 'Q' + 0x7F,0xFF,0x07,0xFF,0xFE,0x3F,0xFF,0xF9,0xFF,0xFF,0xEF,0x80,0x3F,0xFC,0x00,0xFF,0xE0,0x03,0xFF,0x00,0x1F,0xF8,0x00,0xFF,0xC0,0x0F,0xFE,0x00,0xFD,0xFF,0xFF,0xEF,0xFF,0xFE,0x7F,0xFF,0xC3,0xFF,0xF8,0x1F,0x07,0xE0,0xF8,0x1F,0x87,0xC0,0x7E,0x3E,0x01,0xF9,0xF0,0x0F,0xCF,0x80,0x3F,0x7C,0x00,0xFF,0xE0,0x07,0xFF,0x00,0x1F,0xF8,0x00,0xFB,0x80,0x03,0xC0, // 'R' + 0x03,0xF8,0x01,0xFF,0xF0,0x3F,0xFF,0x87,0xFF,0xFC,0x7E,0x0F,0xCF,0xC0,0x7E,0xF8,0x03,0xEF,0x80,0x1E,0xFC,0x00,0xCF,0xF0,0x00,0x7F,0xF0,0x03,0xFF,0xE0,0x1F,0xFF,0x80,0x7F,0xFC,0x00,0x7F,0xE0,0x00,0x7F,0x60,0x03,0xFF,0x00,0x1F,0xF0,0x01,0xFF,0x80,0x1F,0xFC,0x03,0xFF,0xE0,0x7E,0x7F,0xFF,0xC3,0xFF,0xFC,0x0F,0xFF,0x00,0x3F,0xC0, // 'S' + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x0F,0x80,0x00,0x7C,0x00,0x03,0xE0,0x00,0x1F,0x00,0x00,0xF8,0x00,0x07,0xC0,0x00,0x3E,0x00,0x01,0xF0,0x00,0x0F,0x80,0x00,0x7C,0x00,0x03,0xE0,0x00,0x1F,0x00,0x00,0xF8,0x00,0x07,0xC0,0x00,0x3E,0x00,0x01,0xF0,0x00,0x0F,0x80,0x00,0x7C,0x00,0x03,0xE0,0x00,0x1F,0x00,0x00,0xF8,0x00,0x03,0x80,0x00, // 'T' + 0x70,0x00,0x77,0xC0,0x07,0xFE,0x00,0x3F,0xF0,0x01,0xFF,0x80,0x0F,0xFC,0x00,0x7F,0xE0,0x03,0xFF,0x00,0x1F,0xF8,0x00,0xFF,0xC0,0x07,0xFE,0x00,0x3F,0xF0,0x01,0xFF,0x80,0x0F,0xFC,0x00,0x7F,0xE0,0x03,0xFF,0x00,0x1F,0xF8,0x00,0xFF,0xC0,0x07,0xFE,0x00,0x3F,0xF8,0x03,0xF7,0xC0,0x1F,0x3F,0x83,0xF8,0xFF,0xFF,0x83,0xFF,0xF8,0x0F,0xFF,0x80,0x1F,0xF0,0x00, // 'U' + 0x70,0x00,0x1D,0xF0,0x00,0x7F,0xE0,0x00,0xFF,0xE0,0x03,0xF7,0xC0,0x07,0xCF,0x80,0x0F,0x9F,0x80,0x3F,0x1F,0x00,0x7C,0x3F,0x00,0xF8,0x7E,0x03,0xE0,0x7C,0x07,0xC0,0xFC,0x0F,0x80,0xF8,0x3E,0x01,0xF0,0x7C,0x03,0xF0,0xF8,0x03,0xE3,0xE0,0x07,0xC7,0xC0,0x07,0xDF,0x00,0x0F,0xBE,0x00,0x1F,0x7C,0x00,0x1F,0xF0,0x00,0x3F,0xE0,0x00,0x7F,0x80,0x00,0x7F,0x00,0x00,0xFE,0x00,0x00,0x70,0x00, // 'V' + 0x70,0x03,0xC0,0x0E,0xF8,0x07,0xE0,0x1F,0xF8,0x07,0xE0,0x1F,0xF8,0x0F,0xF0,0x1F,0xF8,0x0F,0xF0,0x1F,0x7C,0x0F,0xF0,0x3E,0x7C,0x0F,0xF0,0x3E,0x7C,0x1F,0xF8,0x3E,0x7C,0x1E,0x78,0x3E,0x3E,0x1E,0x78,0x7C,0x3E,0x1E,0x78,0x7C,0x3E,0x3E,0x7C,0x7C,0x3E,0x3C,0x3C,0x7C,0x1E,0x3C,0x3C,0x78,0x1F,0x7C,0x3E,0xF8,0x1F,0x78,0x1E,0xF8,0x1F,0x78,0x1E,0xF8,0x0F,0x78,0x1E,0xF0,0x0F,0xF8,0x1F,0xF0,0x0F,0xF0,0x0F,0xF0,0x0F,0xF0,0x0F,0xF0,0x07,0xF0,0x0F,0xE0,0x07,0xF0,0x0F,0xE0,0x07,0xE0,0x07,0xE0,0x03,0xE0,0x07,0xC0,0x03,0xC0,0x03,0xC0, // 'W' + 0x38,0x00,0x73,0xE0,0x07,0x9F,0x00,0x7E,0xFC,0x07,0xE3,0xF0,0x3F,0x1F,0x83,0xF0,0x7E,0x3F,0x01,0xF9,0xF8,0x0F,0xDF,0x80,0x3F,0xF8,0x00,0xFF,0xC0,0x07,0xFC,0x00,0x1F,0xC0,0x00,0xFE,0x00,0x0F,0xF8,0x00,0xFF,0xE0,0x07,0xFF,0x80,0x7E,0xFC,0x07,0xE3,0xF0,0x7F,0x1F,0xC3,0xF0,0x7E,0x3F,0x01,0xFB,0xF0,0x07,0xFF,0x80,0x3F,0xF8,0x00,0xFB,0x80,0x03,0x80, // 'X' + 0x70,0x00,0x77,0xC0,0x07,0xFF,0x00,0x3E,0xF8,0x03,0xF7,0xE0,0x3F,0x1F,0x01,0xF0,0xFC,0x1F,0x83,0xF0,0xF8,0x0F,0x8F,0x80,0x7E,0xFC,0x01,0xF7,0xC0,0x07,0xFC,0x00,0x3F,0xE0,0x00,0xFE,0x00,0x03,0xE0,0x00,0x1F,0x00,0x00,0xF8,0x00,0x07,0xC0,0x00,0x3E,0x00,0x01,0xF0,0x00,0x0F,0x80,0x00,0x7C,0x00,0x03,0xE0,0x00,0x1F,0x00,0x00,0xF8,0x00,0x03,0x80,0x00, // 'Y' + 0x3F,0xFF,0xF8,0x7F,0xFF,0xF9,0xFF,0xFF,0xF1,0xFF,0xFF,0xE0,0x00,0x1F,0x80,0x00,0x7F,0x00,0x01,0xFC,0x00,0x07,0xF0,0x00,0x0F,0xC0,0x00,0x3F,0x00,0x00,0xFC,0x00,0x03,0xF0,0x00,0x0F,0xE0,0x00,0x3F,0x80,0x00,0x7E,0x00,0x01,0xF8,0x00,0x07,0xE0,0x00,0x1F,0x80,0x00,0x7F,0x00,0x01,0xFC,0x00,0x07,0xF0,0x00,0x0F,0xC0,0x00,0x3F,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xF8, // 'Z' + 0x7F,0xFF,0xFF,0xFF,0xFF,0xF8,0x3E,0x0F,0x83,0xE0,0xF8,0x3E,0x0F,0x83,0xE0,0xF8,0x3E,0x0F,0x83,0xE0,0xF8,0x3E,0x0F,0x83,0xE0,0xF8,0x3E,0x0F,0x83,0xE0,0xF8,0x3E,0x0F,0x83,0xE0,0xF8,0x3F,0xFF,0xFF,0xFF,0x7F,0xC0, // '[' + 0x70,0x3C,0x07,0x01,0xE0,0x78,0x1E,0x03,0x80,0xF0,0x3C,0x0F,0x01,0xC0,0x78,0x1E,0x07,0x80,0xE0,0x3C,0x0F,0x03,0xC0,0x70,0x1E,0x07,0x81,0xE0,0x38,0x0F,0x03,0xC0,0x60, // '\' + 0xFF,0xBF,0xFF,0xFF,0xFF,0x07,0xC1,0xF0,0x7C,0x1F,0x07,0xC1,0xF0,0x7C,0x1F,0x07,0xC1,0xF0,0x7C,0x1F,0x07,0xC1,0xF0,0x7C,0x1F,0x07,0xC1,0xF0,0x7C,0x1F,0x07,0xC1,0xF0,0x7C,0x1F,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0x80, // ']' + 0x03,0xE0,0x01,0xF0,0x01,0xFC,0x00,0xFE,0x00,0x7F,0x80,0x7B,0xC0,0x3D,0xF0,0x3E,0xF8,0x1E,0x3C,0x1F,0x1F,0x0F,0x07,0x8F,0x83,0xE7,0xC1,0xF7,0xC0,0x7C, // '^' + 0xFF,0xFF,0xFF,0xFF,0xF0, // '_' + 0x0E,0x1B,0x11,0x1B,0x0E, // '`' Changed into a degree symbol + 0x03,0xFC,0x03,0xFF,0xE0,0xFF,0xFE,0x3F,0x07,0xC7,0xC0,0x7C,0xF0,0x0F,0x9C,0x01,0xF0,0x00,0xFE,0x01,0xFF,0xC3,0xFF,0xF8,0xFF,0x9F,0x3F,0x03,0xEF,0x80,0x7D,0xF0,0x0F,0xBE,0x03,0xF7,0xE1,0xFE,0x7F,0xFF,0xE7,0xFE,0x7C,0x3E,0x07,0x00, // 'a' + 0x70,0x00,0x1F,0x00,0x03,0xE0,0x00,0x7C,0x00,0x0F,0x80,0x01,0xF0,0x00,0x3E,0x00,0x07,0xC7,0xE0,0xF9,0xFF,0x1F,0x7F,0xF3,0xFF,0xFF,0x7F,0x87,0xEF,0xE0,0x7D,0xF8,0x0F,0xFF,0x00,0xFF,0xC0,0x1F,0xF8,0x03,0xFF,0x00,0x7F,0xE0,0x0F,0xFE,0x03,0xFF,0xC0,0x7D,0xFE,0x1F,0xBF,0xFF,0xE7,0xDF,0xFC,0xF9,0xFF,0x0E,0x1F,0x80, // 'b' + 0x03,0xF8,0x03,0xFF,0x81,0xFF,0xF0,0xFF,0xFE,0x7F,0x0F,0xDF,0x01,0xFF,0xC0,0x3F,0xE0,0x04,0xF8,0x00,0x3E,0x00,0x0F,0x80,0x03,0xE0,0x07,0xFC,0x03,0xDF,0x01,0xF7,0xF0,0xFC,0xFF,0xFE,0x1F,0xFF,0x83,0xFF,0x80,0x3F,0x80, // 'c' + 0x00,0x01,0xC0,0x00,0x7C,0x00,0x0F,0x80,0x01,0xF0,0x00,0x3E,0x00,0x07,0xC0,0x00,0xF8,0x3F,0x1F,0x1F,0xF3,0xE7,0xFF,0x7D,0xFF,0xFF,0xBF,0x0F,0xF7,0xC0,0xFF,0xF8,0x0F,0xFE,0x01,0xFF,0xC0,0x1F,0xF8,0x03,0xFF,0x00,0x7F,0xE0,0x1F,0xFE,0x03,0xF7,0xC0,0x7E,0xFC,0x3F,0xCF,0xFF,0xF9,0xFF,0xDF,0x1F,0xF3,0xE0,0xF8,0x38, // 'd' + 0x03,0xF8,0x03,0xFF,0x81,0xFF,0xF0,0xF8,0x7E,0x7C,0x07,0x9F,0x01,0xFF,0x80,0x7F,0xE0,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xE0,0x00,0xF8,0x00,0x1F,0x00,0x77,0xC0,0x3C,0xFC,0x3F,0x1F,0xFF,0x83,0xFF,0xC0,0x3F,0x80, // 'e' + 0x01,0xF8,0x0F,0xF8,0x1F,0xF8,0x7F,0xE0,0xF8,0x01,0xF0,0x03,0xE0,0x3F,0xF8,0x7F,0xF9,0xFF,0xF1,0xFF,0xC0,0x7C,0x00,0xF8,0x01,0xF0,0x03,0xE0,0x07,0xC0,0x0F,0x80,0x1F,0x00,0x3E,0x00,0x7C,0x00,0xF8,0x01,0xF0,0x03,0xE0,0x07,0xC0,0x0F,0x80,0x0E,0x00, // 'f' + 0x07,0xE1,0xC3,0xFE,0x7C,0xFF,0xEF,0xBF,0xFF,0xF7,0xE1,0xFE,0xF8,0x0F,0xFF,0x01,0xFF,0xC0,0x1F,0xF8,0x03,0xFF,0x00,0x7F,0xE0,0x0F,0xFC,0x01,0xFF,0xC0,0x7E,0xF8,0x0F,0xDF,0x87,0xF9,0xFF,0xFF,0x3F,0xFB,0xE3,0xFE,0x7C,0x1F,0x8F,0x80,0x01,0xF7,0x00,0x7E,0xF0,0x0F,0x9F,0x83,0xF3,0xFF,0xFC,0x1F,0xFF,0x00,0xFF,0x80, // 'g' + 0x70,0x00,0x3E,0x00,0x0F,0x80,0x03,0xE0,0x00,0xF8,0x00,0x3E,0x00,0x0F,0x80,0x03,0xE3,0xF0,0xF9,0xFF,0x3E,0xFF,0xEF,0xFF,0xFB,0xF8,0x3F,0xFC,0x0F,0xFE,0x01,0xFF,0x80,0x7F,0xE0,0x1F,0xF8,0x07,0xFE,0x01,0xFF,0x80,0x7F,0xE0,0x1F,0xF8,0x07,0xFE,0x01,0xFF,0x80,0x7F,0xE0,0x1F,0xF8,0x07,0xDC,0x00,0xE0, // 'h' + 0x77,0xFF,0xF7,0x00,0x0E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0x80, // 'i' + 0x03,0x81,0xF0,0x7C,0x1F,0x03,0x80,0x00,0x00,0x0E,0x07,0xC1,0xF0,0x7C,0x1F,0x07,0xC1,0xF0,0x7C,0x1F,0x07,0xC1,0xF0,0x7C,0x1F,0x07,0xC1,0xF0,0x7C,0x1F,0x07,0xC1,0xF0,0x7C,0x1F,0x07,0xFF,0xFF,0xFB,0xFE,0x7E,0x00, // 'j' + 0x70,0x00,0x7C,0x00,0x3E,0x00,0x1F,0x00,0x0F,0x80,0x07,0xC0,0x03,0xE0,0x01,0xF0,0x1C,0xF8,0x1E,0x7C,0x1F,0x3E,0x1F,0x9F,0x1F,0x8F,0x9F,0x07,0xDF,0x03,0xFF,0x81,0xFF,0xE0,0xFF,0xF0,0x7F,0x7C,0x3F,0x1F,0x1F,0x0F,0x8F,0x83,0xE7,0xC1,0xFB,0xE0,0x7D,0xF0,0x1F,0xF8,0x0F,0xB8,0x03,0x80, // 'k' + 0x77,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0x80, // 'l' + 0x70,0xFC,0x0F,0x8F,0x3F,0xE3,0xFC,0xFF,0xFF,0x7F,0xEF,0xFF,0xFF,0xFE,0xFE,0x1F,0xE3,0xFF,0xC0,0xFC,0x1F,0xF8,0x0F,0x81,0xFF,0x80,0xF8,0x1F,0xF8,0x0F,0x81,0xFF,0x80,0xF8,0x1F,0xF8,0x0F,0x81,0xFF,0x80,0xF8,0x1F,0xF8,0x0F,0x81,0xFF,0x80,0xF8,0x1F,0xF8,0x0F,0x81,0xFF,0x80,0xF8,0x1F,0xF8,0x0F,0x81,0xFF,0x80,0xF8,0x1F,0x70,0x07,0x00,0xE0, // 'm' + 0x70,0xFC,0x3C,0x7F,0xCF,0xBF,0xFB,0xFF,0xFE,0xFE,0x0F,0xFF,0x03,0xFF,0xC0,0x7F,0xE0,0x1F,0xF8,0x07,0xFE,0x01,0xFF,0x80,0x7F,0xE0,0x1F,0xF8,0x07,0xFE,0x01,0xFF,0x80,0x7F,0xE0,0x1F,0xF8,0x07,0xFE,0x01,0xF7,0x00,0x38, // 'n' + 0x01,0xF8,0x00,0xFF,0xF0,0x1F,0xFF,0x83,0xFF,0xFC,0x7F,0x0F,0xE7,0xC0,0x3E,0xFC,0x03,0xFF,0x80,0x1F,0xF8,0x01,0xFF,0x80,0x1F,0xF8,0x01,0xFF,0x80,0x1F,0xFC,0x03,0xF7,0xC0,0x3E,0x7F,0x0F,0xE3,0xFF,0xFC,0x1F,0xFF,0x80,0xFF,0xF0,0x01,0xF8,0x00, // 'o' + 0x70,0xFC,0x1F,0x3F,0xE3,0xEF,0xFE,0x7F,0xFF,0xCF,0xF0,0xFD,0xF8,0x0F,0xBF,0x01,0xFF,0xC0,0x1F,0xF8,0x03,0xFF,0x00,0x7F,0xE0,0x0F,0xFC,0x01,0xFF,0xC0,0x7F,0xF8,0x0F,0xBF,0xC3,0xF7,0xFF,0xFC,0xFB,0xFF,0x9F,0x3F,0xE3,0xE3,0xF0,0x7C,0x00,0x0F,0x80,0x01,0xF0,0x00,0x3E,0x00,0x07,0xC0,0x00,0xF8,0x00,0x0E,0x00,0x00, // 'p' + 0x07,0xE1,0xC3,0xFE,0x7C,0xFF,0xEF,0x9F,0xFF,0xF7,0xE1,0xFE,0xF8,0x0F,0xFF,0x01,0xFF,0xC0,0x1F,0xF8,0x03,0xFF,0x00,0x7F,0xE0,0x0F,0xFC,0x01,0xFF,0xC0,0x7E,0xF8,0x0F,0xDF,0x87,0xF9,0xFF,0xFF,0x3F,0xFB,0xE3,0xFE,0x7C,0x1F,0x0F,0x80,0x01,0xF0,0x00,0x3E,0x00,0x07,0xC0,0x00,0xF8,0x00,0x1F,0x00,0x03,0xE0,0x00,0x38, // 'q' + 0x71,0xE7,0xDF,0xFF,0xFF,0xFF,0xFF,0xE1,0x7E,0x03,0xF0,0x1F,0x00,0xF8,0x07,0xC0,0x3E,0x01,0xF0,0x0F,0x80,0x7C,0x03,0xE0,0x1F,0x00,0xF8,0x07,0xC0,0x1C,0x00, // 'r' + 0x0F,0xF0,0x1F,0xFE,0x1F,0xFF,0x8F,0x87,0xEF,0x81,0xF7,0xC0,0x7B,0xF0,0x00,0xFF,0x80,0x3F,0xF8,0x0F,0xFF,0x00,0xFF,0xC0,0x0F,0xF6,0x01,0xFF,0x80,0x7F,0xE0,0x3F,0xF8,0x3E,0x7F,0xFF,0x1F,0xFF,0x03,0xFC,0x00, // 's' + 0x0E,0x00,0xF8,0x07,0xC0,0x3E,0x01,0xF0,0x0F,0x80,0x7C,0x0F,0xFC,0xFF,0xF7,0xFF,0x9F,0xF8,0x3E,0x01,0xF0,0x0F,0x80,0x7C,0x03,0xE0,0x1F,0x00,0xF8,0x07,0xC0,0x3E,0x01,0xF0,0x0F,0x80,0x7F,0xE3,0xFF,0x0F,0xF8,0x3F,0x80, // 't' + 0x70,0x03,0xBE,0x01,0xFF,0x80,0x7F,0xE0,0x1F,0xF8,0x07,0xFE,0x01,0xFF,0x80,0x7F,0xE0,0x1F,0xF8,0x07,0xFE,0x01,0xFF,0x80,0x7F,0xE0,0x1F,0xF8,0x07,0xFF,0x03,0xFF,0xE3,0xFD,0xFF,0xFF,0x7F,0xF7,0xCF,0xF8,0xF0,0xF8,0x38, // 'u' + 0x70,0x03,0xBC,0x00,0xFF,0x80,0x7F,0xE0,0x1F,0x7C,0x07,0x9F,0x03,0xE3,0xC0,0xF0,0xF8,0x7C,0x3E,0x1E,0x07,0x87,0x81,0xF3,0xE0,0x3C,0xF0,0x0F,0x3C,0x01,0xFE,0x00,0x7F,0x80,0x1F,0xE0,0x03,0xF0,0x00,0xFC,0x00,0x1E,0x00, // 'v' + 0x70,0x0F,0x00,0xEF,0x00,0xF0,0x0F,0xF8,0x1F,0x81,0xFF,0x81,0xF8,0x1F,0x78,0x1F,0x81,0xE7,0x83,0xFC,0x1E,0x7C,0x3F,0xC3,0xE3,0xC3,0xFC,0x3C,0x3C,0x79,0xE3,0xC3,0xE7,0x9E,0x7C,0x1E,0x79,0xE7,0x81,0xE7,0x0E,0x78,0x0E,0xF0,0xF7,0x00,0xFF,0x0F,0xF0,0x0F,0xE0,0x7F,0x00,0x7E,0x07,0xE0,0x07,0xE0,0x7E,0x00,0x7C,0x03,0xE0,0x03,0xC0,0x3C,0x00, // 'w' + 0x70,0x07,0x3C,0x07,0xBF,0x07,0xEF,0xC7,0xE3,0xE3,0xE0,0xFB,0xE0,0x7F,0xE0,0x1F,0xF0,0x07,0xF0,0x03,0xF8,0x03,0xFE,0x01,0xFF,0x01,0xF7,0xC1,0xF1,0xF1,0xF8,0xFC,0xF8,0x3E,0xF8,0x0F,0xFC,0x07,0xDC,0x01,0xC0, // 'x' + 0x38,0x01,0xCF,0x80,0x3D,0xF0,0x0F,0xBE,0x01,0xF3,0xE0,0x3C,0x7C,0x0F,0x87,0x81,0xE0,0xF8,0x7C,0x1F,0x0F,0x81,0xE1,0xE0,0x3E,0x7C,0x03,0xCF,0x00,0x7D,0xE0,0x07,0xFC,0x00,0xFF,0x00,0x1F,0xE0,0x01,0xF8,0x00,0x3F,0x00,0x07,0xE0,0x00,0xF8,0x00,0x1F,0x00,0x07,0xC0,0x1F,0xF8,0x07,0xFE,0x00,0x7F,0xC0,0x07,0xE0,0x00, // 'y' + 0x7F,0xFF,0x1F,0xFF,0xE7,0xFF,0xF9,0xFF,0xFE,0x00,0x3F,0x00,0x1F,0x80,0x07,0xC0,0x03,0xE0,0x01,0xF0,0x00,0xF8,0x00,0x7E,0x00,0x3F,0x00,0x1F,0x80,0x0F,0xC0,0x07,0xE0,0x03,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xF8, // 'z' + 0x01,0xF0,0x1F,0xC1,0xFE,0x1F,0xE0,0xFC,0x07,0xC0,0x3E,0x01,0xF0,0x0F,0x80,0x7C,0x03,0xE0,0x1F,0x01,0xF8,0x0F,0x81,0xFC,0x1F,0xC0,0xF8,0x07,0xF0,0x1F,0xC0,0x3E,0x01,0xF8,0x07,0xC0,0x3E,0x01,0xF0,0x0F,0x80,0x7C,0x03,0xE0,0x1F,0x00,0xFC,0x07,0xF8,0x1F,0xE0,0x7F,0x01,0xF0, // '{' + 0x6F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x60, // '|' + 0x7C,0x07,0xF0,0x3F,0xC0,0xFF,0x01,0xF8,0x07,0xC0,0x3E,0x01,0xF0,0x0F,0x80,0x7C,0x03,0xE0,0x1F,0x00,0xFC,0x03,0xE0,0x1F,0xC0,0x7F,0x00,0xF8,0x1F,0xC1,0xFC,0x0F,0x80,0xFC,0x07,0xC0,0x3E,0x01,0xF0,0x0F,0x80,0x7C,0x03,0xE0,0x1F,0x01,0xF8,0x3F,0xC3,0xFC,0x1F,0xC0,0x7C,0x00 // '}' +}; +const GFXglyph ArialRoundedMTBold_36Glyphs[] PROGMEM = { +// bitmapOffset, width, height, xAdvance, xOffset, yOffset + { 0, 1, 1, 10, 0, 0 }, // ' ' + { 1, 5, 26, 13, 4, -26 }, // '!' + { 18, 14, 9, 18, 2, -26 }, // '"' + { 34, 19, 26, 21, 0, -26 }, // '#' + { 96, 19, 37, 22, 1, -30 }, // '$' + { 184, 29, 27, 32, 1, -26 }, // '%' + { 282, 25, 26, 28, 2, -26 }, // '&' + { 364, 6, 9, 10, 1, -26 }, // ''' + { 371, 9, 33, 14, 2, -26 }, // '(' + { 409, 9, 33, 14, 2, -26 }, // ')' + { 447, 15, 14, 17, 0, -28 }, // '*' + { 474, 19, 18, 22, 1, -22 }, // '+' + { 517, 6, 11, 12, 3, -5 }, // ',' + { 526, 11, 4, 13, 1, -11 }, // '-' + { 532, 5, 5, 12, 3, -5 }, // '.' + { 536, 9, 26, 11, 1, -26 }, // '/' + { 566, 18, 26, 22, 2, -26 }, // '0' + { 625, 13, 26, 22, 2, -26 }, // '1' + { 668, 18, 26, 22, 2, -26 }, // '2' + { 727, 18, 26, 22, 2, -26 }, // '3' + { 786, 21, 26, 22, 0, -26 }, // '4' + { 855, 18, 26, 22, 2, -26 }, // '5' + { 914, 18, 26, 22, 2, -26 }, // '6' + { 973, 18, 26, 22, 3, -26 }, // '7' + { 1032, 19, 26, 22, 1, -26 }, // '8' + { 1094, 18, 26, 22, 1, -26 }, // '9' + { 1153, 5, 19, 12, 3, -19 }, // ':' + { 1165, 5, 25, 12, 3, -19 }, // ';' + { 1181, 18, 20, 22, 1, -23 }, // '<' + { 1226, 18, 13, 22, 2, -19 }, // '=' + { 1256, 18, 20, 22, 1, -23 }, // '>' + { 1301, 18, 26, 22, 1, -26 }, // '?' + { 1360, 34, 33, 36, 1, -26 }, // '@' + { 1501, 24, 26, 27, 1, -26 }, // 'A' + { 1579, 21, 26, 27, 3, -26 }, // 'B' + { 1648, 23, 26, 28, 2, -26 }, // 'C' + { 1723, 22, 26, 28, 3, -26 }, // 'D' + { 1795, 20, 26, 25, 3, -26 }, // 'E' + { 1860, 18, 26, 23, 3, -26 }, // 'F' + { 1919, 24, 26, 30, 2, -26 }, // 'G' + { 1997, 21, 26, 28, 3, -26 }, // 'H' + { 2066, 5, 26, 12, 3, -26 }, // 'I' + { 2083, 17, 26, 22, 1, -26 }, // 'J' + { 2139, 22, 26, 28, 3, -26 }, // 'K' + { 2211, 18, 26, 23, 3, -26 }, // 'L' + { 2270, 25, 26, 31, 3, -26 }, // 'M' + { 2352, 22, 26, 28, 3, -26 }, // 'N' + { 2424, 25, 26, 30, 2, -26 }, // 'O' + { 2506, 19, 26, 25, 3, -26 }, // 'P' + { 2568, 26, 28, 30, 2, -26 }, // 'Q' + { 2659, 21, 26, 27, 3, -26 }, // 'R' + { 2728, 20, 26, 25, 2, -26 }, // 'S' + { 2793, 21, 26, 24, 1, -26 }, // 'T' + { 2862, 21, 26, 28, 3, -26 }, // 'U' + { 2931, 23, 26, 26, 1, -26 }, // 'V' + { 3006, 32, 26, 35, 1, -26 }, // 'W' + { 3110, 21, 26, 23, 0, -26 }, // 'X' + { 3179, 21, 26, 24, 1, -26 }, // 'Y' + { 3248, 23, 26, 24, 0, -26 }, // 'Z' + { 3323, 10, 33, 14, 2, -26 }, // '[' + { 3365, 10, 26, 11, 0, -26 }, // '\' + { 3398, 10, 33, 14, 0, -26 }, // ']' + { 3440, 17, 14, 22, 2, -26 }, // '^' + { 3470, 18, 2, 19, 0, 3 }, // '_' + { 3475, 8, 5, 10, 0, -26 }, // '`' Changed to degree symbol + { 3480, 19, 19, 22, 1, -19 }, // 'a' + { 3526, 19, 26, 24, 2, -26 }, // 'b' + { 3588, 18, 19, 22, 1, -19 }, // 'c' + { 3631, 19, 26, 24, 1, -26 }, // 'd' + { 3693, 18, 19, 22, 2, -19 }, // 'e' + { 3736, 15, 26, 13, -1, -26 }, // 'f' + { 3785, 19, 26, 24, 1, -19 }, // 'g' + { 3847, 18, 26, 23, 2, -26 }, // 'h' + { 3906, 5, 26, 11, 2, -26 }, // 'i' + { 3923, 10, 33, 11, -3, -26 }, // 'j' + { 3965, 17, 26, 22, 3, -26 }, // 'k' + { 4021, 5, 26, 11, 2, -26 }, // 'l' + { 4038, 28, 19, 33, 2, -19 }, // 'm' + { 4105, 18, 19, 23, 2, -19 }, // 'n' + { 4148, 20, 19, 23, 1, -19 }, // 'o' + { 4196, 19, 26, 24, 2, -19 }, // 'p' + { 4258, 19, 26, 24, 1, -19 }, // 'q' + { 4320, 13, 19, 17, 2, -19 }, // 'r' + { 4351, 17, 19, 21, 1, -19 }, // 's' + { 4392, 13, 26, 14, 0, -26 }, // 't' + { 4435, 18, 19, 23, 2, -19 }, // 'u' + { 4478, 18, 19, 21, 1, -19 }, // 'v' + { 4521, 28, 19, 30, 1, -19 }, // 'w' + { 4588, 17, 19, 20, 1, -19 }, // 'x' + { 4629, 19, 26, 21, 0, -19 }, // 'y' + { 4691, 18, 19, 20, 1, -19 }, // 'z' + { 4734, 13, 33, 15, 1, -26 }, // '{' + { 4788, 4, 33, 11, 3, -26 }, // '|' + { 4805, 13, 33, 15, 0, -26 } // '}' character 0x7D +}; +const GFXfont ArialRoundedMTBold_36 PROGMEM = { // Last character bug fixed 0x7E to 0x7D +(uint8_t *)ArialRoundedMTBold_36Bitmaps,(GFXglyph *)ArialRoundedMTBold_36Glyphs,0x20, 0x7D, 43}; + diff --git a/examples/ILI9341/weather-station-v6/ArialRoundedMtBold_14.h b/examples/ILI9341/weather-station-v6/ArialRoundedMtBold_14.h new file mode 100644 index 0000000..b08d84f --- /dev/null +++ b/examples/ILI9341/weather-station-v6/ArialRoundedMtBold_14.h @@ -0,0 +1,224 @@ +/**The MIT License (MIT) +Copyright (c) 2015 by Daniel Eichhorn +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. +See more at http://blog.squix.ch +*/ + +// Created by http://oleddisplay.squix.ch/ Consider a donation +// In case of problems make sure that you are using the font file with the correct version! + +// Bodmer fix: End character is 0x7D not 0x7E, so bug in last line of the file corrected +// this avoids screen corruption if ~ is printer + +const uint8_t ArialRoundedMTBold_14Bitmaps[] PROGMEM = { + + // Bitmap Data: + 0x00, // ' ' + 0xFF,0xF8,0xF0, // '!' + 0xDE,0xF6, // '"' + 0x12,0x32,0x36,0xFF,0xFF,0x24,0xFF,0xFF,0x4C,0x48, // '#' + 0x10,0x61,0xF6,0xAD,0x7A,0x1E,0x0E,0xD7,0xAF,0x5B,0xE1,0x02,0x04,0x00, // '$' + 0x60,0x92,0x22,0x44,0x49,0x07,0x60,0x0B,0x82,0x48,0xC9,0x11,0x24,0x18, // '%' + 0x3C,0x19,0x82,0x60,0xF0,0x39,0x33,0x6C,0x73,0x1C,0xFF,0x8E,0x30, // '&' + 0xFC, // ''' + 0x32,0x64,0xCC,0xCC,0xC4,0x62,0x30, // '(' + 0xC4,0x62,0x33,0x33,0x32,0x64,0xC0, // ')' + 0x21,0x2A,0xE5,0x28, // '*' + 0x18,0x18,0x18,0xFF,0xFF,0x18,0x18, // '+' + 0xF6, // ',' + 0xFF, // '-' + 0xF0, // '.' + 0x33,0x32,0x66,0x4C,0xCC, // '/' + 0x38,0xFB,0x9E,0x3C,0x78,0xF1,0xF6,0x7C,0x70, // '0' + 0x19,0xDF,0xB1,0x8C,0x63,0x18,0xC0, // '1' + 0x38,0xFF,0x1E,0x30,0xC3,0x0C,0x30,0xFF,0xFC, // '2' + 0x79,0x9B,0x10,0x63,0xC7,0x81,0xC3,0xC6,0xF0, // '3' + 0x06,0x0E,0x1E,0x16,0x26,0x46,0xFF,0xFF,0x06,0x06, // '4' + 0x7E,0xFD,0x06,0x0F,0xD8,0xC1,0xC3,0xCC,0xF0, // '5' + 0x38,0xDB,0x1E,0x0F,0xD8,0xF1,0xE3,0x66,0x78, // '6' + 0xFF,0xFC,0x30,0x41,0x82,0x0C,0x18,0x30,0xC0, // '7' + 0x38,0xDB,0x1F,0x63,0x98,0xF1,0xE3,0xC6,0xF8, // '8' + 0x3C,0x66,0xC3,0xC3,0xE7,0x3F,0x03,0xC3,0x66,0x3C, // '9' + 0xF0,0x3C, // ':' + 0xF0,0x3D,0x80, // ';' + 0x02,0x1D,0xF7,0x0E,0x0F,0x83,0x81, // '<' + 0xFF,0xFC,0x07,0xFF,0xE0, // '=' + 0x81,0xC1,0xF0,0x70,0xEF,0xB8,0x40, // '>' + 0x3C,0xFF,0x1E,0x30,0xC7,0x0C,0x00,0x30,0x60, // '?' + 0x0F,0x83,0x06,0x60,0x24,0xED,0x99,0x9B,0x19,0xB1,0xBB,0x12,0xBF,0xE4,0xDC,0x40,0x13,0x06,0x0F,0xC0, // '@' + 0x1C,0x0E,0x05,0x06,0xC3,0x63,0x19,0xFC,0xFE,0xC1,0xE0,0xC0, // 'A' + 0xFC,0xFE,0xC7,0xC6,0xFE,0xFE,0xC3,0xC3,0xFF,0xFE, // 'B' + 0x3E,0x3F,0xB8,0xF8,0x3C,0x06,0x03,0x06,0xC7,0x7F,0x0F,0x00, // 'C' + 0xFE,0x7F,0xB0,0xF8,0x3C,0x1E,0x0F,0x07,0x87,0xFF,0x7F,0x00, // 'D' + 0xFE,0xFF,0xC0,0xC0,0xFE,0xFE,0xC0,0xC0,0xFF,0xFF, // 'E' + 0xFF,0xFF,0x06,0x0F,0xDF,0xB0,0x60,0xC1,0x80, // 'F' + 0x1E,0x3F,0x98,0xF8,0x2C,0x06,0x3F,0x1E,0xC3,0x7F,0x9F,0x00, // 'G' + 0xC1,0xE0,0xF0,0x78,0x3F,0xFF,0xFF,0x07,0x83,0xC1,0xE0,0xC0, // 'H' + 0xFF,0xFF,0xF0, // 'I' + 0x06,0x0C,0x18,0x30,0x60,0xF1,0xF3,0x7E,0x78, // 'J' + 0xC3,0x63,0xB3,0x9B,0x8F,0x87,0x63,0x19,0x8E,0xC3,0x60,0xC0, // 'K' + 0xC1,0x83,0x06,0x0C,0x18,0x30,0x60,0xFF,0xFC, // 'L' + 0xE1,0xFC,0xFF,0x3F,0xCF,0xD2,0xF7,0xBD,0xEF,0x7B,0xCC,0xF3,0x30, // 'M' + 0xC1,0xF0,0xFC,0x7E,0x3D,0x9E,0x6F,0x3F,0x8F,0xC3,0xE0,0xC0, // 'N' + 0x1E,0x1F,0xE6,0x1B,0x03,0xC0,0xF0,0x3C,0x0D,0x86,0x7F,0x87,0x80, // 'O' + 0xFE,0xFF,0xC3,0xC3,0xFF,0xFE,0xC0,0xC0,0xC0,0xC0, // 'P' + 0x1E,0x0F,0xF1,0x87,0x60,0x6C,0x0D,0x81,0xB1,0x33,0x7C,0x7F,0x83,0xD8,0x01,0x80, // 'Q' + 0xFE,0xFF,0xC3,0xC3,0xFE,0xFC,0xCE,0xC6,0xC3,0xC3, // 'R' + 0x7C,0xFE,0xC7,0xC2,0x7C,0x0F,0xC3,0xC3,0x7E,0x3C, // 'S' + 0xFF,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, // 'T' + 0xC1,0xE0,0xF0,0x78,0x3C,0x1E,0x0F,0x07,0xC7,0x7F,0x1F,0x00, // 'U' + 0xC1,0xE0,0xD8,0xCC,0x66,0x31,0xB0,0xD8,0x6C,0x1C,0x0E,0x00, // 'V' + 0xC7,0x1E,0x38,0xF1,0x46,0xDB,0x66,0xDB,0x36,0xD9,0xA2,0xC7,0x1C,0x38,0xE1,0x83,0x00, // 'W' + 0xC3,0x66,0x7E,0x3C,0x18,0x3C,0x7E,0x66,0xC3,0xC3, // 'X' + 0xC3,0xC3,0x66,0x3E,0x3C,0x18,0x18,0x18,0x18,0x18, // 'Y' + 0x7F,0x3F,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0xC0, // 'Z' + 0xFF,0xCC,0xCC,0xCC,0xCC,0xCF,0xF0, // '[' + 0xCC,0x44,0x66,0x22,0x33, // '\' + 0xFF,0x33,0x33,0x33,0x33,0x3F,0xF0, // ']' + 0x30,0xE7,0x9A,0xCF,0x30, // '^' + 0xFE, // '_' + 0xD0, // '`' + 0x7D,0x8C,0x7F,0x3C,0x79,0xDD,0x80, // 'a' + 0xC1,0x83,0x06,0xEF,0xF8,0xF1,0xE3,0xFF,0xB8, // 'b' + 0x3C,0xFF,0x1E,0x0C,0x6F,0xCF,0x00, // 'c' + 0x06,0x0C,0x1B,0xBF,0xF8,0xF1,0xE3,0xFE,0xEC, // 'd' + 0x3C,0xCF,0x1F,0xFC,0x0C,0xCF,0x00, // 'e' + 0x3B,0x19,0xF6,0x31,0x8C,0x63,0x00, // 'f' + 0x77,0xFF,0x1E,0x3C,0x7F,0xDD,0xE3,0xC6,0xF8, // 'g' + 0xC1,0x83,0x06,0xEF,0xF8,0xF1,0xE3,0xC7,0x8C, // 'h' + 0xF3,0xFF,0xF0, // 'i' + 0x33,0x03,0x33,0x33,0x33,0x3F,0xE0, // 'j' + 0xC1,0x83,0x06,0x6D,0x9E,0x3E,0x66,0xCD,0x8C, // 'k' + 0xFF,0xFF,0xF0, // 'l' + 0xD9,0xDF,0xFF,0x31,0xE6,0x3C,0xC7,0x98,0xF3,0x18, // 'm' + 0xDD,0xFF,0x1E,0x3C,0x78,0xF1,0x80, // 'n' + 0x38,0xFB,0x1E,0x3C,0x6F,0x8E,0x00, // 'o' + 0xDD,0xFF,0x1E,0x3C,0x7F,0xF7,0x60,0xC1,0x80, // 'p' + 0x77,0xFF,0x1E,0x3C,0x7F,0xDD,0x83,0x06,0x0C, // 'q' + 0xDF,0xF1,0x8C,0x63,0x00, // 'r' + 0x7B,0x3E,0x1E,0x0F,0x37,0x80, // 's' + 0x63,0x19,0xF6,0x31,0x8C,0x79,0xC0, // 't' + 0xC7,0x8F,0x1E,0x3C,0x7F,0xDD,0x80, // 'u' + 0xC7,0x8D,0x93,0x62,0x87,0x04,0x00, // 'v' + 0xC4,0x79,0xCD,0x29,0x35,0x67,0xBC,0x63,0x0C,0x60, // 'w' + 0xC6,0xD9,0xF1,0xC7,0xCD,0xB1,0x80, // 'x' + 0xC7,0x8D,0x93,0x62,0xC7,0x06,0x18,0xF1,0xC0, // 'y' + 0xFE,0x18,0x61,0x86,0x1F,0xFF,0x80, // 'z' + 0x19,0xCC,0x63,0x3B,0x8E,0x31,0x8C,0x71,0x80, // '{' + 0xFF,0xFF,0xFF,0xC0, // '|' + 0xC7,0x18,0xC6,0x38,0xEE,0x63,0x19,0xCC,0x00 // '}' +}; +const GFXglyph ArialRoundedMTBold_14Glyphs[] PROGMEM = { +// bitmapOffset, width, height, xAdvance, xOffset, yOffset + { 0, 1, 1, 5, 0, 0 }, // ' ' + { 1, 2, 10, 6, 1, -10 }, // '!' + { 4, 5, 3, 8, 1, -10 }, // '"' + { 6, 8, 10, 9, 0, -10 }, // '#' + { 16, 7, 15, 9, 1, -12 }, // '$' + { 30, 11, 10, 13, 0, -10 }, // '%' + { 44, 10, 10, 12, 1, -10 }, // '&' + { 57, 2, 3, 4, 1, -10 }, // ''' + { 58, 4, 13, 6, 1, -10 }, // '(' + { 65, 4, 13, 6, 0, -10 }, // ')' + { 72, 5, 6, 7, 1, -11 }, // '*' + { 76, 8, 7, 9, 0, -9 }, // '+' + { 83, 2, 4, 5, 1, -2 }, // ',' + { 84, 4, 2, 6, 0, -5 }, // '-' + { 85, 2, 2, 5, 1, -2 }, // '.' + { 86, 4, 10, 5, 0, -10 }, // '/' + { 91, 7, 10, 9, 1, -10 }, // '0' + { 100, 5, 10, 9, 1, -10 }, // '1' + { 107, 7, 10, 9, 1, -10 }, // '2' + { 116, 7, 10, 9, 1, -10 }, // '3' + { 125, 8, 10, 9, 0, -10 }, // '4' + { 135, 7, 10, 9, 1, -10 }, // '5' + { 144, 7, 10, 9, 1, -10 }, // '6' + { 153, 7, 10, 9, 1, -10 }, // '7' + { 162, 7, 10, 9, 1, -10 }, // '8' + { 171, 8, 10, 9, 0, -10 }, // '9' + { 181, 2, 7, 5, 1, -7 }, // ':' + { 183, 2, 9, 5, 1, -7 }, // ';' + { 186, 7, 8, 9, 1, -9 }, // '<' + { 193, 7, 5, 9, 1, -7 }, // '=' + { 198, 7, 8, 9, 1, -9 }, // '>' + { 205, 7, 10, 9, 1, -10 }, // '?' + { 214, 12, 13, 15, 1, -10 }, // '@' + { 234, 9, 10, 11, 1, -10 }, // 'A' + { 246, 8, 10, 11, 1, -10 }, // 'B' + { 256, 9, 10, 11, 1, -10 }, // 'C' + { 268, 9, 10, 11, 1, -10 }, // 'D' + { 280, 8, 10, 10, 1, -10 }, // 'E' + { 290, 7, 10, 9, 1, -10 }, // 'F' + { 299, 9, 10, 12, 1, -10 }, // 'G' + { 311, 9, 10, 12, 1, -10 }, // 'H' + { 323, 2, 10, 5, 1, -10 }, // 'I' + { 326, 7, 10, 9, 0, -10 }, // 'J' + { 335, 9, 10, 11, 1, -10 }, // 'K' + { 347, 7, 10, 9, 1, -10 }, // 'L' + { 356, 10, 10, 13, 1, -10 }, // 'M' + { 369, 9, 10, 12, 1, -10 }, // 'N' + { 381, 10, 10, 12, 1, -10 }, // 'O' + { 394, 8, 10, 10, 1, -10 }, // 'P' + { 404, 11, 11, 12, 1, -10 }, // 'Q' + { 420, 8, 10, 11, 1, -10 }, // 'R' + { 430, 8, 10, 10, 1, -10 }, // 'S' + { 440, 8, 10, 10, 0, -10 }, // 'T' + { 450, 9, 10, 12, 1, -10 }, // 'U' + { 462, 9, 10, 11, 0, -10 }, // 'V' + { 474, 13, 10, 14, 0, -10 }, // 'W' + { 491, 8, 10, 9, 0, -10 }, // 'X' + { 501, 8, 10, 10, 0, -10 }, // 'Y' + { 511, 9, 10, 10, 0, -10 }, // 'Z' + { 523, 4, 13, 6, 1, -10 }, // '[' + { 530, 4, 10, 5, 0, -10 }, // '\' + { 535, 4, 13, 6, 0, -10 }, // ']' + { 542, 6, 6, 9, 1, -10 }, // '^' + { 547, 7, 1, 8, 0, 1 }, // '_' + { 548, 2, 2, 6, 1, -10 }, // '`' + { 549, 7, 7, 9, 1, -7 }, // 'a' + { 556, 7, 10, 10, 1, -10 }, // 'b' + { 565, 7, 7, 9, 1, -7 }, // 'c' + { 572, 7, 10, 10, 1, -10 }, // 'd' + { 581, 7, 7, 9, 1, -7 }, // 'e' + { 588, 5, 10, 6, 0, -10 }, // 'f' + { 595, 7, 10, 10, 1, -7 }, // 'g' + { 604, 7, 10, 9, 1, -10 }, // 'h' + { 613, 2, 10, 5, 1, -10 }, // 'i' + { 616, 4, 13, 5, -1, -10 }, // 'j' + { 623, 7, 10, 9, 1, -10 }, // 'k' + { 632, 2, 10, 5, 1, -10 }, // 'l' + { 635, 11, 7, 13, 1, -7 }, // 'm' + { 645, 7, 7, 9, 1, -7 }, // 'n' + { 652, 7, 7, 9, 1, -7 }, // 'o' + { 659, 7, 10, 10, 1, -7 }, // 'p' + { 668, 7, 10, 10, 1, -7 }, // 'q' + { 677, 5, 7, 7, 1, -7 }, // 'r' + { 682, 6, 7, 9, 1, -7 }, // 's' + { 688, 5, 10, 6, 0, -10 }, // 't' + { 695, 7, 7, 9, 1, -7 }, // 'u' + { 702, 7, 7, 9, 0, -7 }, // 'v' + { 709, 11, 7, 12, 0, -7 }, // 'w' + { 719, 7, 7, 8, 0, -7 }, // 'x' + { 726, 7, 10, 9, 0, -7 }, // 'y' + { 735, 7, 7, 8, 0, -7 }, // 'z' + { 742, 5, 13, 6, 0, -10 }, // '{' + { 751, 2, 13, 5, 1, -10 }, // '|' + { 755, 5, 13, 6, 1, -10 } // '}' character 0x7D +}; +const GFXfont ArialRoundedMTBold_14 PROGMEM = { // Last character bug fixed 0x7E to 0x7D +(uint8_t *)ArialRoundedMTBold_14Bitmaps,(GFXglyph *)ArialRoundedMTBold_14Glyphs,0x20, 0x7D, 17}; + diff --git a/examples/ILI9341/weather-station-v6/GfxUi.cpp b/examples/ILI9341/weather-station-v6/GfxUi.cpp new file mode 100644 index 0000000..4716da0 --- /dev/null +++ b/examples/ILI9341/weather-station-v6/GfxUi.cpp @@ -0,0 +1,332 @@ +/**The MIT License (MIT) +Copyright (c) 2015 by Daniel Eichhorn +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. +See more at http://blog.squix.ch + +Adapted by Bodmer to use the faster TFT_eSPI library: +https://github.com/Bodmer/TFT_eSPI + +Bodmer: Functions no longer needed weeded out, Jpeg decoder functions added +Bodmer: drawBMP() updated to buffer in and out pixels and use screen CGRAM rotation for faster bottom up drawing (now ~2x faster) +*/ + +#include "GfxUi.h" + +GfxUi::GfxUi(TFT_eSPI *tft) { + _tft = tft; +} + +void GfxUi::drawProgressBar(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint8_t percentage, uint16_t frameColor, uint16_t barColor) { + if (percentage == 0) { + _tft->fillRoundRect(x0, y0, w, h, 3, TFT_BLACK); + } + uint8_t margin = 2; + uint16_t barHeight = h - 2 * margin; + uint16_t barWidth = w - 2 * margin; + _tft->drawRoundRect(x0, y0, w, h, 3, frameColor); + _tft->fillRect(x0 + margin, y0 + margin, barWidth * percentage / 100.0, barHeight, barColor); +} + +// This drawBMP function contains code from: +// https://github.com/adafruit/Adafruit_ILI9341/blob/master/examples/spitftbitmap/spitftbitmap.ino +// Here is Bodmer's version: this uses the ILI9341 CGRAM coordinate rotation features inside the display and +// buffers both file and TFT pixel blocks, it typically runs about 2x faster for bottom up encoded BMP images + +//void GfxUi::drawBMP(String filename, uint8_t x, uint16_t y, boolean flip) { // Alernative for caller control of flip +void GfxUi::drawBmp(String filename, uint8_t x, uint16_t y) { + // Flips the TFT internal SGRAM coords to draw bottom up BMP images faster, in this application it can be fixed + boolean flip = 1; + + if ((x >= _tft->width()) || (y >= _tft->height())) return; + + fs::File bmpFile; + int16_t bmpWidth, bmpHeight; // Image W+H in pixels + uint32_t bmpImageoffset; // Start address of image data in file + uint32_t rowSize; // Not always = bmpWidth; may have padding + uint8_t sdbuffer[3 * BUFFPIXEL]; // file read pixel buffer (8 bits each R+G+B per pixel) + uint16_t tftbuffer[BUFFPIXEL]; // TFT pixel out buffer (16-bit per pixel) + uint8_t rgb_ptr = sizeof(sdbuffer); // read 24 bit RGB pixel data buffer pointer (8 bit so BUFF_SIZE must be less than 86) + boolean goodBmp = false; // Flag set to true on valid header parse + int16_t w, h, row, col; // to store width, height, row and column + uint8_t rotation; // to restore rotation + uint8_t tft_ptr = 0; // TFT 16 bit 565 format pixel data buffer pointer + + // Check file exists and open it + Serial.println(filename); + if ( !(bmpFile = SPIFFS.open(filename, "r")) ) { + Serial.println(F(" File not found")); // Can comment out if not needed + return; + } + + // Parse BMP header to get the information we need + if (read16(bmpFile) == 0x4D42) { // BMP file start signature check + read32(bmpFile); // Dummy read to throw away and move on + read32(bmpFile); // Read & ignore creator bytes + bmpImageoffset = read32(bmpFile); // Start of image data + read32(bmpFile); // Dummy read to throw away and move on + bmpWidth = read32(bmpFile); // Image width + bmpHeight = read32(bmpFile); // Image height + + // Only proceed if we pass a bitmap file check + // Number of image planes -- must be '1', depth 24 and 0 (uncompressed format) + if ((read16(bmpFile) == 1) && (read16(bmpFile) == 24) && (read32(bmpFile) == 0)) { + goodBmp = true; // Supported BMP format + // BMP rows are padded (if needed) to 4-byte boundary + rowSize = (bmpWidth * 3 + 3) & ~3; + // Crop area to be loaded + w = bmpWidth; + h = bmpHeight; + + // We might need to alter rotation to avoid tedious file pointer manipulation + // Save the current value so we can restore it later + rotation = _tft->getRotation(); + // Use TFT SGRAM coord rotation if flip is set for 25% faster rendering (new rotations 4-7 supported by library) + if (flip) _tft->setRotation((rotation + (flip<<2)) % 8); // Value 0-3 mapped to 4-7 + + // Calculate new y plot coordinate if we are flipping + switch (rotation) { + case 0: + if (flip) y = _tft->height() - y - h; break; + case 1: + y = _tft->height() - y - h; break; + break; + case 2: + if (flip) y = _tft->height() - y - h; break; + break; + case 3: + y = _tft->height() - y - h; break; + break; + } + + // Set TFT address window to image bounds + // Currently, image will not draw or will be corrputed if it does not fit + // TODO -> efficient clipping, but I don't need it to be idiot proof ;-) + _tft->setAddrWindow(x, y, x + w - 1, y + h - 1); + + // Finally we are ready to send rows of pixels, writing like this avoids slow 32 bit multiply in 8 bit processors + for (uint32_t pos = bmpImageoffset; pos < bmpImageoffset + h * rowSize ; pos += rowSize) { + // Seek if we need to on boundaries and arrange to dump buffer and start again + if (bmpFile.position() != pos) { + bmpFile.seek(pos, fs::SeekSet); + rgb_ptr = sizeof(sdbuffer); + //Serial.println("Seeking in file >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); + } + + // Fill the pixel buffer and plot + for (col = 0; col < w; col++) { // For each column... + // Time to read more pixel data? + if (rgb_ptr >= sizeof(sdbuffer)) { + // Push tft buffer to the display + if (tft_ptr) { + // Here we are sending a uint16_t array to the function + _tft->pushColors(tftbuffer, tft_ptr); + tft_ptr = 0; // tft_ptr and rgb_ptr are not always in sync... + } + // Finally reading bytes from SD Card + bmpFile.read(sdbuffer, sizeof(sdbuffer)); + rgb_ptr = 0; // Set buffer index to start + } + // Convert pixel from BMP 8+8+8 format to TFT compatible 16 bit word + // Blue 5 bits, green 6 bits and red 5 bits (16 bits total) + // Is is a long line but it is faster than calling a library fn for this + tftbuffer[tft_ptr] = (sdbuffer[rgb_ptr++] >> 3) ; + tftbuffer[tft_ptr] |= ((sdbuffer[rgb_ptr++] & 0xFC) << 3); + tftbuffer[tft_ptr] |= ((sdbuffer[rgb_ptr++] & 0xF8) << 8); + tft_ptr++; + } // Next row + } // All rows done + + // Write any partially full buffer to TFT + if (tft_ptr) _tft->pushColors(tftbuffer, tft_ptr); + + } // End of bitmap access + } // End of bitmap file check + + bmpFile.close(); + if(!goodBmp) Serial.println(F("BMP format not recognised.")); + _tft->setRotation(rotation); // Put back original rotation +} + +// These read 16- and 32-bit types from the SD card file. +// BMP data is stored little-endian, Arduino is little-endian too. +// May need to reverse subscript order if porting elsewhere. + +uint16_t GfxUi::read16(fs::File &f) { + uint16_t result; + ((uint8_t *)&result)[0] = f.read(); // LSB + ((uint8_t *)&result)[1] = f.read(); // MSB + return result; +} + +uint32_t GfxUi::read32(fs::File &f) { + uint32_t result; + ((uint8_t *)&result)[0] = f.read(); // LSB + ((uint8_t *)&result)[1] = f.read(); + ((uint8_t *)&result)[2] = f.read(); + ((uint8_t *)&result)[3] = f.read(); // MSB + return result; +} + +/*==================================================================================== + This sketch support functions to render the Jpeg images. + + Created by Bodmer 15th Jan 2017 + ==================================================================================*/ + +// Return the minimum of two values a and b +#define minimum(a,b) (((a) < (b)) ? (a) : (b)) + +#define USE_SPI_BUFFER // Comment out to use slower 16 bit pushColor() + +//==================================================================================== +// Opens the image file and prime the Jpeg decoder +//==================================================================================== +void GfxUi::drawJpeg(const char *filename, int xpos, int ypos) { + + Serial.println("==========================="); + Serial.print("Drawing file: "); Serial.println(filename); + Serial.println("==========================="); + + // Open the named file (the Jpeg decoder library will close it after rendering image) + fs::File jpegFile = SPIFFS.open( filename, "r"); // File handle reference for SPIFFS + // File jpegFile = SD.open( filename, FILE_READ); // or, file handle reference for SD library + + if ( !jpegFile ) { + Serial.print("ERROR: File \""); Serial.print(filename); Serial.println ("\" not found!"); + return; + } + + // Use one of the three following methods to initialise the decoder: + //boolean decoded = JpegDec.decodeFsFile(jpegFile); // Pass a SPIFFS file handle to the decoder, + //boolean decoded = JpegDec.decodeSdFile(jpegFile); // or pass the SD file handle to the decoder, + boolean decoded = JpegDec.decodeFsFile(filename); // or pass the filename (leading / distinguishes SPIFFS files) + // Note: the filename can be a String or character array type + if (decoded) { + // print information about the image to the serial port + jpegInfo(); + + // render the image onto the screen at given coordinates + jpegRender(xpos, ypos); + } + else { + Serial.println("Jpeg file format not supported!"); + } +} + +//==================================================================================== +// Decode and render the Jpeg image onto the TFT screen +//==================================================================================== +void GfxUi::jpegRender(int xpos, int ypos) { + + // retrieve infomration about the image + uint16_t *pImg; + uint16_t mcu_w = JpegDec.MCUWidth; + uint16_t mcu_h = JpegDec.MCUHeight; + uint32_t max_x = JpegDec.width; + uint32_t max_y = JpegDec.height; + + // Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs) + // Typically these MCUs are 16x16 pixel blocks + // Determine the width and height of the right and bottom edge image blocks + uint32_t min_w = minimum(mcu_w, max_x % mcu_w); + uint32_t min_h = minimum(mcu_h, max_y % mcu_h); + + // save the current image block size + uint32_t win_w = mcu_w; + uint32_t win_h = mcu_h; + + // record the current time so we can measure how long it takes to draw an image + uint32_t drawTime = millis(); + + // save the coordinate of the right and bottom edges to assist image cropping + // to the screen size + max_x += xpos; + max_y += ypos; + + // read each MCU block until there are no more +#ifdef USE_SPI_BUFFER + while( JpegDec.readSwappedBytes()){ // Swap byte order so the SPI buffer can be used +#else + while ( JpegDec.read()) { // Normal byte order read +#endif + // save a pointer to the image block + pImg = JpegDec.pImage; + + // calculate where the image block should be drawn on the screen + int mcu_x = JpegDec.MCUx * mcu_w + xpos; + int mcu_y = JpegDec.MCUy * mcu_h + ypos; + + // check if the image block size needs to be changed for the right and bottom edges + if (mcu_x + mcu_w <= max_x) win_w = mcu_w; + else win_w = min_w; + if (mcu_y + mcu_h <= max_y) win_h = mcu_h; + else win_h = min_h; + + // calculate how many pixels must be drawn + uint32_t mcu_pixels = win_w * win_h; + + // draw image MCU block only if it will fit on the screen + if ( ( mcu_x + win_w) <= _tft->width() && ( mcu_y + win_h) <= _tft->height()) + { +#ifdef USE_SPI_BUFFER + // Now set a MCU bounding window on the TFT to push pixels into (x, y, x + width - 1, y + height - 1) + _tft->setWindow(mcu_x, mcu_y, mcu_x + win_w - 1, mcu_y + win_h - 1); + // Write all MCU pixels to the TFT window + uint8_t *pImg8 = (uint8_t*)pImg; // Convert 16 bit pointer to an 8 bit pointer + _tft->pushColors(pImg8, mcu_pixels*2); // Send bytes via 64 byte SPI port buffer +#else + // Now set a MCU bounding window on the TFT to push pixels into (x, y, x + width - 1, y + height - 1) + _tft->setAddrWindow(mcu_x, mcu_y, mcu_x + win_w - 1, mcu_y + win_h - 1); + // Write all MCU pixels to the TFT window + while (mcu_pixels--) _tft->pushColor(*pImg++); +#endif + } + + else if ( ( mcu_y + win_h) >= _tft->height()) JpegDec.abort(); + + } + + // calculate how long it took to draw the image + drawTime = millis() - drawTime; // Calculate the time it took + + // print the results to the serial port + Serial.print ("Total render time was : "); Serial.print(drawTime); Serial.println(" ms"); + Serial.println("====================================="); + +} + +//==================================================================================== +// Print information decoded from the Jpeg image +//==================================================================================== +void GfxUi::jpegInfo() { + + Serial.println("==============="); + Serial.println("JPEG image info"); + Serial.println("==============="); + Serial.print ("Width :"); Serial.println(JpegDec.width); + Serial.print ("Height :"); Serial.println(JpegDec.height); + Serial.print ("Components :"); Serial.println(JpegDec.comps); + Serial.print ("MCU / row :"); Serial.println(JpegDec.MCUSPerRow); + Serial.print ("MCU / col :"); Serial.println(JpegDec.MCUSPerCol); + Serial.print ("Scan type :"); Serial.println(JpegDec.scanType); + Serial.print ("MCU width :"); Serial.println(JpegDec.MCUWidth); + Serial.print ("MCU height :"); Serial.println(JpegDec.MCUHeight); + Serial.println("==============="); + Serial.println(""); + +} +//==================================================================================== diff --git a/examples/ILI9341/weather-station-v6/GfxUi.h b/examples/ILI9341/weather-station-v6/GfxUi.h new file mode 100644 index 0000000..f381129 --- /dev/null +++ b/examples/ILI9341/weather-station-v6/GfxUi.h @@ -0,0 +1,60 @@ +/**The MIT License (MIT) +Copyright (c) 2015 by Daniel Eichhorn +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. + +See more at http://blog.squix.ch + +Adapted by Bodmer to use the faster TFT_eSPI library: +https://github.com/Bodmer/TFT_eSPI + +*/ + + +#include // Hardware-specific library + +#define FS_NO_GLOBALS // Avoid conflict with SD library File type definition +#include + +// JPEG decoder library +#include + +#ifndef _GFX_UI_H +#define _GFX_UI_H + +// Maximum of 85 for BUFFPIXEL as 3 x this value is stored in an 8 bit variable! +// 32 is an efficient size for SPIFFS due to SPI hardware pipeline buffer size +// A larger value of 80 is better for SD cards +#define BUFFPIXEL 32 + +class GfxUi { + public: + GfxUi(TFT_eSPI * tft); + void drawBmp(String filename, uint8_t x, uint16_t y); + void drawProgressBar(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t percentage, uint16_t frameColor, uint16_t barColor); + void jpegInfo(); + void drawJpeg(const char *filename, int xpos, int ypos); + void jpegRender(int xpos, int ypos); + + private: + TFT_eSPI * _tft; + uint16_t read16(fs::File &f); + uint32_t read32(fs::File &f); + +}; + +#endif + diff --git a/examples/ILI9341/weather-station-v6/SPIFFS_Support.ino b/examples/ILI9341/weather-station-v6/SPIFFS_Support.ino new file mode 100644 index 0000000..37eefe1 --- /dev/null +++ b/examples/ILI9341/weather-station-v6/SPIFFS_Support.ino @@ -0,0 +1,42 @@ +/*==================================================================================== + This sketch contains support functions for the ESP6266 SPIFFS filing system + + Created by Bodmer 15th Jan 2017 + ==================================================================================*/ + +//==================================================================================== +// Print a SPIFFS directory list (root directory) +//==================================================================================== + +void listFiles(void) { + Serial.println(); + Serial.println("SPIFFS files found:"); + + fs::Dir dir = SPIFFS.openDir("/"); // Root directory + String line = "====================================="; + uint32_t totalBytes = 0; + + Serial.println(line); + Serial.println(" File name Size"); + Serial.println(line); + + while (dir.next()) { + String fileName = dir.fileName(); + Serial.print(fileName); + int spaces = 25 - fileName.length(); // Tabulate nicely + while (spaces--) Serial.print(" "); + fs::File f = dir.openFile("r"); + Serial.print(f.size()); Serial.println(" bytes"); + totalBytes += f.size(); + } + Serial.println(); Serial.print("Total = "); + int spaces = 25 - 8; // Tabulate nicely + while (spaces--) Serial.print(" "); + Serial.print(totalBytes); Serial.println(" bytes"); + + Serial.println(line); + Serial.println(); + delay(1000); +} +//==================================================================================== + diff --git a/examples/ILI9341/weather-station-v6/WebResource.cpp b/examples/ILI9341/weather-station-v6/WebResource.cpp new file mode 100644 index 0000000..2020fd1 --- /dev/null +++ b/examples/ILI9341/weather-station-v6/WebResource.cpp @@ -0,0 +1,105 @@ +/**The MIT License (MIT) +Copyright (c) 2015 by Daniel Eichhorn +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. +See more at http://blog.squix.ch +*/ + +#include "WebResource.h" + +WebResource::WebResource(){ + +} + +void WebResource::downloadFile(String url, String filename) { + downloadFile(url, filename, nullptr); +} + +void WebResource::downloadFile(String url, String filename, ProgressCallback progressCallback) { + + if (SPIFFS.exists(filename) == true) { + Serial.println("Found " + filename); + return; + } + else Serial.println("Downloading " + filename + " from " + url); + + // wait for WiFi connection + if((_wifiMulti.run() == WL_CONNECTED)) { + HTTPClient http; + + Serial.print("[HTTP] begin...\n"); + + // configure server and url + http.begin(url); + + Serial.print("[HTTP] GET...\n"); + // start connection and send HTTP header + int httpCode = http.GET(); + if(httpCode > 0) { + //SPIFFS.remove(filename); + fs::File f = SPIFFS.open(filename, "w+"); + if (!f) { + Serial.println("file open failed"); + return; + } + // HTTP header has been send and Server response header has been handled + Serial.printf("[HTTP] GET... code: %d\n", httpCode); + + // file found at server + if(httpCode == HTTP_CODE_OK) { + + // get length of document (is -1 when Server sends no Content-Length header) + int total = http.getSize(); + int len = total; + progressCallback(filename, 0,total); + // create buffer for read + uint8_t buff[128] = { 0 }; + + // get tcp stream + WiFiClient * stream = http.getStreamPtr(); + + // read all data from server + while(http.connected() && (len > 0 || len == -1)) { + // get available data size + size_t size = stream->available(); + + if(size) { + // read up to 128 byte + int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size)); + + // write it to Serial + f.write(buff, c); + + if(len > 0) { + len -= c; + } + progressCallback(filename, total - len,total); + } + delay(1); + } + + Serial.println(); + Serial.print("[HTTP] connection closed or file end.\n"); + + } + f.close(); + } else { + Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); + } + + http.end(); + } +} diff --git a/examples/ILI9341/weather-station-v6/WebResource.h b/examples/ILI9341/weather-station-v6/WebResource.h new file mode 100644 index 0000000..acff084 --- /dev/null +++ b/examples/ILI9341/weather-station-v6/WebResource.h @@ -0,0 +1,46 @@ +/**The MIT License (MIT) +Copyright (c) 2015 by Daniel Eichhorn +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. +See more at http://blog.squix.ch +*/ + +#define FS_NO_GLOBALS // Avoid conflict with SD library File type definition +#include +#include +#include +#include +#include + +#ifndef _WEBRESOURCE_H +#define _WEBRESOURCE_H + +typedef void (*ProgressCallback)(String fileName, int16_t bytesDownloaded, int16_t bytesTotal); + +class WebResource { + public: + WebResource(); + void downloadFile(String url, String filename, ProgressCallback progressCallback); + void downloadFile(String url, String filename); + + + private: + ESP8266WiFiMulti _wifiMulti; + +}; + +#endif + diff --git a/examples/ILI9341/weather-station-v6/settings.h b/examples/ILI9341/weather-station-v6/settings.h new file mode 100644 index 0000000..d92513a --- /dev/null +++ b/examples/ILI9341/weather-station-v6/settings.h @@ -0,0 +1,71 @@ +/**The MIT License (MIT) +Copyright (c) 2015 by Daniel Eichhorn +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. +See more at http://blog.squix.ch + +Adapted by Bodmer to use the faster TFT_ILI9341_ESP library: +https://github.com/Bodmer/TFT_ILI9341_ESP + +*/ + +// Setup +const int UPDATE_INTERVAL_SECS = 10 * 60; // Update every 10 minutes + +// Pins for the TFT interface are defined in the User_Setup.h file inside the TFT_eSPI library +// These are the ones I used on a NodeMCU plus MOSI and SCK: +// #define TFT_DC D3 +// #define TFT_CS D8 +///#define TFT_RST -1 // Minus one means no pin allocated, connect to NodeMCU RST pin + +// TimeClient settings +const float UTC_OFFSET = 0; + +// Wunderground Settings, EDIT TO SUIT YOUR LOCATION +const boolean IS_METRIC = true; // Temperature only? Wind speed units appear to stay in mph. To do: investigate <<<<<<<<<<<<<<<<<<<<<<<<< + +//const String WUNDERGRROUND_API_KEY = ""; +//const String WUNDERGRROUND_API_KEY = "1c265fajf48s0a82"; // Random key example of what the above line should look like + +// For language codes see https://www.wunderground.com/weather/api/d/docs?d=language-support&_ga=1.55148395.1951311424.1484425551 +const String WUNDERGRROUND_LANGUAGE = "EN"; // Language EN = English + +// For a list of countries, states and cities see https://www.wunderground.com/about/faq/international_cities.asp +const String WUNDERGROUND_COUNTRY = "Peru"; // UK, US etc +const String WUNDERGROUND_CITY = "Lima"; // City, "London", "FL/Boca_Raton" for Boca Raton in Florida (State/City) etc. Use underscore_for spaces) + +// Windspeed conversion, use 1 pair of #defines. To do: investigate a more convenient method <<<<<<<<<<<<<<<<<<<<< +//#define WIND_SPEED_SCALING 1.0 // mph +//#define WIND_SPEED_UNITS " mph" + +//#define WIND_SPEED_SCALING 0.868976 // mph to knots +//#define WIND_SPEED_UNITS " kn" + +#define WIND_SPEED_SCALING 1.60934 // mph to kph +#define WIND_SPEED_UNITS " kph" + + +//Thingspeak Settings - not used, no need to populate this at the moment +const String THINGSPEAK_CHANNEL_ID = ""; +const String THINGSPEAK_API_READ_KEY = ""; + + +// List, so that the downloader knows what to fetch +String wundergroundIcons [] = {"chanceflurries","chancerain","chancesleet","chancesnow","clear","cloudy","flurries","fog","hazy","mostlycloudy","mostlysunny","partlycloudy","partlysunny","rain","sleet","snow","sunny","tstorms","unknown"}; + +/*************************** + * End Settings + **************************/ diff --git a/examples/ILI9341/weather-station-v6/weather-station-v6.ino b/examples/ILI9341/weather-station-v6/weather-station-v6.ino new file mode 100644 index 0000000..fdac896 --- /dev/null +++ b/examples/ILI9341/weather-station-v6/weather-station-v6.ino @@ -0,0 +1,579 @@ +/**The MIT License (MIT) + Copyright (c) 2015 by Daniel Eichhorn + 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 COPYBR_DATUM 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. + See more at http://blog.squix.ch + + Adapted by Bodmer to use the faster TFT_eSPI library: + https://github.com/Bodmer/TFT_eSPI + + Plus: + Minor changes to text placement and auto-blanking out old text with background colour padding + Moon phase text added + Forecast text lines are automatically split onto two lines at a central space (some are long!) + Time is printed with colons aligned to tidy display + Min and max forecast temperatures spaced out + The ` character has been changed to a degree symbol in the 36 point font + New smart WU jpeg splash startup screen and updated progress messages + Display does not need to be blanked between updates + Icons nudged about slightly to add wind direction + speed +*/ + +#include + +#include +#include // Hardware-specific library + +// Additional UI functions +#include "GfxUi.h" + +// Fonts created by http://oleddisplay.squix.ch/ +#include "ArialRoundedMTBold_14.h" +#include "ArialRoundedMTBold_36.h" + +// Download helper +#include "WebResource.h" + +#include +#include +#include +#include +#include + +// Helps with connecting to internet +#include + +// check settings.h for adapting to your needs +#include "settings.h" +#include +#include +#include "TimeClient.h" + +// HOSTNAME for OTA update +#define HOSTNAME "ESP8266-OTA-" + +/***************************** + Important: see settings.h to configure your settings!!! + * ***************************/ + +TFT_eSPI tft = TFT_eSPI(); // Invoke custom library + +boolean booted = true; + +GfxUi ui = GfxUi(&tft); + +WebResource webResource; +TimeClient timeClient(UTC_OFFSET); + +// Set to false, if you prefere imperial/inches, Fahrenheit +WundergroundClient wunderground(IS_METRIC); + +//declaring prototypes +void configModeCallback (WiFiManager *myWiFiManager); +void downloadCallback(String filename, int16_t bytesDownloaded, int16_t bytesTotal); +ProgressCallback _downloadCallback = downloadCallback; +void downloadResources(); +void updateData(); +void drawProgress(uint8_t percentage, String text); +void drawTime(); +void drawCurrentWeather(); +void drawForecast(); +void drawForecastDetail(uint16_t x, uint16_t y, uint8_t dayIndex); +String getMeteoconIcon(String iconText); +void drawAstronomy(); +void drawSeparator(uint16_t y); + +long lastDownloadUpdate = millis(); + +void setup() { + Serial.begin(250000); + tft.begin(); + tft.fillScreen(TFT_BLACK); + + tft.setFreeFont(&ArialRoundedMTBold_14); + tft.setTextDatum(BC_DATUM); + tft.setTextColor(TFT_DARKGREY, TFT_BLACK); + tft.drawString("Original by: blog.squix.org", 120, 240); + tft.drawString("Adapted by: Bodmer", 120, 260); + tft.setTextColor(TFT_ORANGE, TFT_BLACK); + + SPIFFS.begin(); + //listFiles(); + //Uncomment next line if you want to erase SPIFFS and update all internet resources, this takes some time! + tft.drawString("Formatting SPIFFS, so wait!", 120, 200); SPIFFS.format(); + + if (SPIFFS.exists("/WU.jpg") == true) ui.drawJpeg("/WU.jpg", 0, 10); + if (SPIFFS.exists("/Earth.jpg") == true) ui.drawJpeg("/Earth.jpg", 0, 320-56); // Image is 56 pixels high + delay(1000); + tft.drawString("Connecting to WiFi", 120, 200); + tft.setTextPadding(240); // Pad next drawString() text to full width to over-write old text + + //WiFiManager + //Local intialization. Once its business is done, there is no need to keep it around + WiFiManager wifiManager; + // Uncomment for testing wifi manager + //wifiManager.resetSettings(); + wifiManager.setAPCallback(configModeCallback); + + //or use this for auto generated name ESP + ChipID + wifiManager.autoConnect(); + + //Manual Wifi + //WiFi.begin(WIFI_SSID, WIFI_PWD); + + // OTA Setup + String hostname(HOSTNAME); + hostname += String(ESP.getChipId(), HEX); + WiFi.hostname(hostname); + ArduinoOTA.setHostname((const char *)hostname.c_str()); + ArduinoOTA.begin(); + + // download images from the net. If images already exist don't download + tft.drawString("Downloading to SPIFFS...", 120, 200); + tft.drawString(" ", 120, 240); // Clear line + tft.drawString(" ", 120, 260); // Clear line + downloadResources(); + //listFiles(); + tft.drawString(" ", 120, 200); // Clear line above using set padding width + tft.drawString("Fetching weather data...", 120, 220); + //delay(500); + + // load the weather information + updateData(); +} + +long lastDrew = 0; +void loop() { + // Handle OTA update requests + ArduinoOTA.handle(); + + // Check if we should update the clock + if (millis() - lastDrew > 30000 && wunderground.getSeconds() == "00") { + drawTime(); + lastDrew = millis(); + } + + // Check if we should update weather information + if (millis() - lastDownloadUpdate > 1000 * UPDATE_INTERVAL_SECS) { + updateData(); + lastDownloadUpdate = millis(); + } +} + +// Called if WiFi has not been configured yet +void configModeCallback (WiFiManager *myWiFiManager) { + tft.setTextDatum(BC_DATUM); + tft.setFreeFont(&ArialRoundedMTBold_14); + tft.setTextColor(TFT_ORANGE); + tft.drawString("Wifi Manager", 120, 28); + tft.drawString("Please connect to AP", 120, 42); + tft.setTextColor(TFT_WHITE); + tft.drawString(myWiFiManager->getConfigPortalSSID(), 120, 56); + tft.setTextColor(TFT_ORANGE); + tft.drawString("To setup Wifi Configuration", 120, 70); +} + +// callback called during download of files. Updates progress bar +void downloadCallback(String filename, int16_t bytesDownloaded, int16_t bytesTotal) { + Serial.println(String(bytesDownloaded) + " / " + String(bytesTotal)); + + tft.setTextDatum(BC_DATUM); + tft.setTextColor(TFT_ORANGE, TFT_BLACK); + tft.setTextPadding(240); + + int percentage = 100 * bytesDownloaded / bytesTotal; + if (percentage == 0) { + tft.drawString(filename, 120, 220); + } + if (percentage % 5 == 0) { + tft.setTextDatum(TC_DATUM); + tft.setTextPadding(tft.textWidth(" 888% ")); + tft.drawString(String(percentage) + "%", 120, 245); + ui.drawProgressBar(10, 225, 240 - 20, 15, percentage, TFT_WHITE, TFT_BLUE); + } + +} + +// Download the bitmaps +void downloadResources() { + // tft.fillScreen(TFT_BLACK); + tft.setFreeFont(&ArialRoundedMTBold_14); + char id[5]; + + // Download WU graphic jpeg first and display it, then the Earth view + webResource.downloadFile((String)"http://i.imgur.com/njl1pMj.jpg", (String)"/WU.jpg", _downloadCallback); + if (SPIFFS.exists("/WU.jpg") == true) ui.drawJpeg("/WU.jpg", 0, 10); + + webResource.downloadFile((String)"http://i.imgur.com/v4eTLCC.jpg", (String)"/Earth.jpg", _downloadCallback); + if (SPIFFS.exists("/Earth.jpg") == true) ui.drawJpeg("/Earth.jpg", 0, 320-56); + + //webResource.downloadFile((String)"http://i.imgur.com/IY57GSv.jpg", (String)"/Horizon.jpg", _downloadCallback); + //if (SPIFFS.exists("/Horizon.jpg") == true) ui.drawJpeg("/Horizon.jpg", 0, 320-160); + + //webResource.downloadFile((String)"http://i.imgur.com/jZptbtY.jpg", (String)"/Rainbow.jpg", _downloadCallback); + //if (SPIFFS.exists("/Rainbow.jpg") == true) ui.drawJpeg("/Rainbow.jpg", 0, 0); + + for (int i = 0; i < 19; i++) { + sprintf(id, "%02d", i); + webResource.downloadFile("http://www.squix.org/blog/wunderground/" + wundergroundIcons[i] + ".bmp", wundergroundIcons[i] + ".bmp", _downloadCallback); + } + for (int i = 0; i < 19; i++) { + sprintf(id, "%02d", i); + webResource.downloadFile("http://www.squix.org/blog/wunderground/mini/" + wundergroundIcons[i] + ".bmp", "/mini/" + wundergroundIcons[i] + ".bmp", _downloadCallback); + } + for (int i = 0; i < 24; i++) { + webResource.downloadFile("http://www.squix.org/blog/moonphase_L" + String(i) + ".bmp", "/moon" + String(i) + ".bmp", _downloadCallback); + } +} + +// Update the internet based information and update screen +void updateData() { + // booted = true; // Test only + // booted = false; // Test only + + if (booted) ui.drawJpeg("/WU.jpg", 0, 10); // May have already drawn this but it does not take long + else tft.drawCircle(22, 22, 16, TFT_DARKGREY); // Outer ring - optional + + if (booted) drawProgress(20, "Updating time..."); + else fillSegment(22, 22, 0, (int) (20 * 3.6), 16, TFT_NAVY); + + timeClient.updateTime(); + if (booted) drawProgress(50, "Updating conditions..."); + else fillSegment(22, 22, 0, (int) (50 * 3.6), 16, TFT_NAVY); + + wunderground.updateConditions(WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY); + if (booted) drawProgress(70, "Updating forecasts..."); + else fillSegment(22, 22, 0, (int) (70 * 3.6), 16, TFT_NAVY); + + wunderground.updateForecast(WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY); + if (booted) drawProgress(90, "Updating astronomy..."); + else fillSegment(22, 22, 0, (int) (90 * 3.6), 16, TFT_NAVY); + + wunderground.updateAstronomy(WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY); + // lastUpdate = timeClient.getFormattedTime(); + // readyForWeatherUpdate = false; + if (booted) drawProgress(100, "Done..."); + else fillSegment(22, 22, 0, 360, 16, TFT_NAVY); + + if (booted) delay(2000); + + if (booted) tft.fillScreen(TFT_BLACK); + else fillSegment(22, 22, 0, 360, 22, TFT_BLACK); + + //tft.fillScreen(TFT_CYAN); // For text padding and update graphics over-write checking only + drawTime(); + drawCurrentWeather(); + drawForecast(); + drawAstronomy(); + + //if (booted) screenshotToConsole(); // No supporting function in this sketch, documentation support only! + booted = false; +} + +// Progress bar helper +void drawProgress(uint8_t percentage, String text) { + tft.setFreeFont(&ArialRoundedMTBold_14); + + tft.setTextDatum(BC_DATUM); + tft.setTextColor(TFT_ORANGE, TFT_BLACK); + tft.setTextPadding(240); + tft.drawString(text, 120, 220); + + ui.drawProgressBar(10, 225, 240 - 20, 15, percentage, TFT_WHITE, TFT_BLUE); + + tft.setTextPadding(0); +} + +// draws the clock +void drawTime() { + tft.setFreeFont(&ArialRoundedMTBold_14); + + String date = wunderground.getDate(); + + tft.setTextDatum(BC_DATUM); + tft.setTextColor(TFT_WHITE, TFT_BLACK); + tft.setTextPadding(tft.textWidth(" Ddd, 44 Mmm 4444 ")); // String width + margin + tft.drawString(date, 120, 14); + + tft.setFreeFont(&ArialRoundedMTBold_36); + + String timeNow = timeClient.getHours() + ":" + timeClient.getMinutes(); + + tft.setTextDatum(BC_DATUM); + tft.setTextColor(TFT_YELLOW, TFT_BLACK); + tft.setTextPadding(tft.textWidth(" 44:44 ")); // String width + margin + tft.drawString(timeNow, 120, 50); + + drawSeparator(52); + + tft.setTextPadding(0); +} + +// draws current weather information +void drawCurrentWeather() { + // Weather Icon + String weatherIcon = getMeteoconIcon(wunderground.getTodayIcon()); + //uint32_t dt = millis(); + ui.drawBmp(weatherIcon + ".bmp", 0, 59); + //Serial.print("Icon draw time = "); Serial.println(millis()-dt); + + // Weather Text + + String weatherText = wunderground.getWeatherText(); + //weatherText = "Heavy Thunderstorms with Small Hail"; // Test line splitting with longest(?) string + + tft.setFreeFont(&ArialRoundedMTBold_14); + + tft.setTextDatum(BR_DATUM); + tft.setTextColor(TFT_ORANGE, TFT_BLACK); + + int splitPoint = 0; + int xpos = 230; + splitPoint = splitIndex(weatherText); + if (splitPoint > 16) xpos = 235; + + tft.setTextPadding(tft.textWidth("Heavy Thunderstorms")); // Max anticipated string width + if (splitPoint) tft.drawString(weatherText.substring(0, splitPoint), xpos, 72); + tft.setTextPadding(tft.textWidth(" with Small Hail")); // Max anticipated string width + margin + tft.drawString(weatherText.substring(splitPoint), xpos, 87); + + tft.setFreeFont(&ArialRoundedMTBold_36); + + tft.setTextDatum(TR_DATUM); + tft.setTextColor(TFT_ORANGE, TFT_BLACK); + + // Font ASCII code 96 (0x60) modified to make "`" a degree symbol + tft.setTextPadding(tft.textWidth("-88`")); // Max width of vales + + weatherText = wunderground.getCurrentTemp(); + if (weatherText.indexOf(".")) weatherText = weatherText.substring(0, weatherText.indexOf(".")); // Make it integer temperature + if (weatherText == "") weatherText = "?"; // Handle null return + tft.drawString(weatherText + "`", 221, 100); + + tft.setFreeFont(&ArialRoundedMTBold_14); + + tft.setTextDatum(TL_DATUM); + tft.setTextPadding(0); + if (IS_METRIC) tft.drawString("C ", 221, 100); + else tft.drawString("F ", 221, 100); + + weatherText = wunderground.getWindDir() + " "; + weatherText += String((int)(wunderground.getWindSpeed().toInt() * WIND_SPEED_SCALING)) + WIND_SPEED_UNITS; + + tft.setTextPadding(tft.textWidth("Variable 888 mph ")); // Max string length? + tft.drawString(weatherText, 114, 136); + + weatherText = wunderground.getWindDir(); + + int windAngle = 0; + String compassCardinal = ""; + switch (weatherText.length()) { + case 1: + compassCardinal = "N E S W "; // Not used, see default below + windAngle = 90 * compassCardinal.indexOf(weatherText) / 2; + break; + case 2: + compassCardinal = "NE SE SW NW"; + windAngle = 45 + 90 * compassCardinal.indexOf(weatherText) / 3; + break; + case 3: + compassCardinal = "NNE ENE ESE SSE SSW WSW WNW NNW"; + windAngle = 22 + 45 * compassCardinal.indexOf(weatherText) / 4; // 22 should be 22.5 but accuracy is not needed! + break; + default: + if (weatherText == "Variable") windAngle = -1; + else { + // v23456v23456v23456v23456 character ruler + compassCardinal = "North East South West"; // Possible strings + windAngle = 90 * compassCardinal.indexOf(weatherText) / 6; + } + break; + } + + tft.fillCircle(128, 110, 23, TFT_BLACK); // Erase old plot, radius + 1 to delete stray pixels + tft.drawCircle(128, 110, 22, TFT_DARKGREY); // Outer ring - optional + if ( windAngle >= 0 ) fillSegment(128, 110, windAngle - 15, 30, 22, TFT_GREEN); // Might replace this with a bigger rotating arrow + tft.drawCircle(128, 110, 6, TFT_RED); + + drawSeparator(153); + + tft.setTextPadding(0); // Reset padding width to none +} + +// draws the three forecast columns +void drawForecast() { + drawForecastDetail(10, 171, 0); + drawForecastDetail(95, 171, 2); + drawForecastDetail(180, 171, 4); + drawSeparator(171 + 69); +} + +// helper for the forecast columns +void drawForecastDetail(uint16_t x, uint16_t y, uint8_t dayIndex) { + tft.setFreeFont(&ArialRoundedMTBold_14); + + String day = wunderground.getForecastTitle(dayIndex).substring(0, 3); + day.toUpperCase(); + + tft.setTextDatum(BC_DATUM); + + tft.setTextColor(TFT_ORANGE, TFT_BLACK); + tft.setTextPadding(tft.textWidth("WWW")); + tft.drawString(day, x + 25, y); + + tft.setTextColor(TFT_WHITE, TFT_BLACK); + tft.setTextPadding(tft.textWidth("-88 -88")); + tft.drawString(wunderground.getForecastHighTemp(dayIndex) + " " + wunderground.getForecastLowTemp(dayIndex), x + 25, y + 14); + + String weatherIcon = getMeteoconIcon(wunderground.getForecastIcon(dayIndex)); + ui.drawBmp("/mini/" + weatherIcon + ".bmp", x, y + 15); + + tft.setTextPadding(0); // Reset padding width to none +} + +// draw moonphase and sunrise/set and moonrise/set +void drawAstronomy() { + tft.setFreeFont(&ArialRoundedMTBold_14); + + tft.setTextDatum(BC_DATUM); + tft.setTextColor(TFT_ORANGE, TFT_BLACK); + tft.setTextPadding(tft.textWidth(" Waxing Crescent ")); + tft.drawString(wunderground.getMoonPhase(), 120, 260 - 2); + + int moonAgeImage = 24 * wunderground.getMoonAge().toInt() / 30.0; + ui.drawBmp("/moon" + String(moonAgeImage) + ".bmp", 120 - 30, 260); + + tft.setTextDatum(BC_DATUM); + tft.setTextColor(TFT_ORANGE, TFT_BLACK); + tft.setTextPadding(0); // Reset padding width to none + tft.drawString("Sun", 40, 280); + + tft.setTextDatum(BR_DATUM); + tft.setTextColor(TFT_WHITE, TFT_BLACK); + tft.setTextPadding(tft.textWidth(" 88:88 ")); + int dt = rightOffset(wunderground.getSunriseTime(), ":"); // Draw relative to colon to them aligned + tft.drawString(wunderground.getSunriseTime(), 40 + dt, 300); + + dt = rightOffset(wunderground.getSunsetTime(), ":"); + tft.drawString(wunderground.getSunsetTime(), 40 + dt, 315); + + tft.setTextDatum(BC_DATUM); + tft.setTextColor(TFT_ORANGE, TFT_BLACK); + tft.setTextPadding(0); // Reset padding width to none + tft.drawString("Moon", 200, 280); + + tft.setTextDatum(BR_DATUM); + tft.setTextColor(TFT_WHITE, TFT_BLACK); + tft.setTextPadding(tft.textWidth(" 88:88 ")); + dt = rightOffset(wunderground.getMoonriseTime(), ":"); // Draw relative to colon to them aligned + tft.drawString(wunderground.getMoonriseTime(), 200 + dt, 300); + + dt = rightOffset(wunderground.getMoonsetTime(), ":"); + tft.drawString(wunderground.getMoonsetTime(), 200 + dt, 315); + + tft.setTextPadding(0); // Reset padding width to none +} + +// Helper function, should be part of the weather station library and should disappear soon +String getMeteoconIcon(String iconText) { + if (iconText == "F") return "chanceflurries"; + if (iconText == "Q") return "chancerain"; + if (iconText == "W") return "chancesleet"; + if (iconText == "V") return "chancesnow"; + if (iconText == "S") return "chancetstorms"; + if (iconText == "B") return "clear"; + if (iconText == "Y") return "cloudy"; + if (iconText == "F") return "flurries"; + if (iconText == "M") return "fog"; + if (iconText == "E") return "hazy"; + if (iconText == "Y") return "mostlycloudy"; + if (iconText == "H") return "mostlysunny"; + if (iconText == "H") return "partlycloudy"; + if (iconText == "J") return "partlysunny"; + if (iconText == "W") return "sleet"; + if (iconText == "R") return "rain"; + if (iconText == "W") return "snow"; + if (iconText == "B") return "sunny"; + if (iconText == "0") return "tstorms"; + + + return "unknown"; +} + +// if you want separators, uncomment the tft-line +void drawSeparator(uint16_t y) { + tft.drawFastHLine(10, y, 240 - 2 * 10, 0x4228); +} + +// determine the "space" split point in a long string +int splitIndex(String text) +{ + int index = 0; + while ( (text.indexOf(' ', index) >= 0) && ( index <= text.length() / 2 ) ) { + index = text.indexOf(' ', index) + 1; + } + if (index) index--; + return index; +} + +// Calculate coord delta from start of text String to start of sub String contained within that text +// Can be used to vertically right align text so for example a colon ":" in the time value is always +// plotted at same point on the screen irrespective of different proportional character widths, +// could also be used to align decimal points for neat formatting +int rightOffset(String text, String sub) +{ + int index = text.indexOf(sub); + return tft.textWidth(text.substring(index)); +} + +// Calculate coord delta from start of text String to start of sub String contained within that text +// Can be used to vertically left align text so for example a colon ":" in the time value is always +// plotted at same point on the screen irrespective of different proportional character widths, +// could also be used to align decimal points for neat formatting +int leftOffset(String text, String sub) +{ + int index = text.indexOf(sub); + return tft.textWidth(text.substring(0, index)); +} + +// Draw a segment of a circle, centred on x,y with defined start_angle and subtended sub_angle +// Angles are defined in a clockwise direction with 0 at top +// Segment has radius r and it is plotted in defined colour +// Can be used for pie charts etc, in this sketch it is used for wind direction +#define DEG2RAD 0.0174532925 // Degrees to Radians conversion factor +#define INC 2 // Minimum segment subtended angle and plotting angle increment (in degrees) +void fillSegment(int x, int y, int start_angle, int sub_angle, int r, unsigned int colour) +{ + // Calculate first pair of coordinates for segment start + float sx = cos((start_angle - 90) * DEG2RAD); + float sy = sin((start_angle - 90) * DEG2RAD); + uint16_t x1 = sx * r + x; + uint16_t y1 = sy * r + y; + + // Draw colour blocks every INC degrees + for (int i = start_angle; i < start_angle + sub_angle; i += INC) { + + // Calculate pair of coordinates for segment end + int x2 = cos((i + 1 - 90) * DEG2RAD) * r + x; + int y2 = sin((i + 1 - 90) * DEG2RAD) * r + y; + + tft.fillTriangle(x1, y1, x2, y2, x, y, colour); + + // Copy segment end to sgement start for next segment + x1 = x2; + y1 = y2; + } +}