diff --git a/examples/320 x 240/weather-station/ArialRoundedMTBold_14.h b/examples/320 x 240/weather-station/ArialRoundedMTBold_14.h deleted file mode 100644 index b08d84f..0000000 --- a/examples/320 x 240/weather-station/ArialRoundedMTBold_14.h +++ /dev/null @@ -1,224 +0,0 @@ -/**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/320 x 240/weather-station/ArialRoundedMTBold_36.h b/examples/320 x 240/weather-station/ArialRoundedMTBold_36.h deleted file mode 100644 index a171dbe..0000000 --- a/examples/320 x 240/weather-station/ArialRoundedMTBold_36.h +++ /dev/null @@ -1,226 +0,0 @@ -/**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 printed - -// 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/320 x 240/weather-station/GfxUi.cpp b/examples/320 x 240/weather-station/GfxUi.cpp deleted file mode 100644 index c425abb..0000000 --- a/examples/320 x 240/weather-station/GfxUi.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/**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.print(F("BMP format not recognised. File:")); - Serial.println(filename); - } - else - _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 edge - if (mcu_x + mcu_w <= max_x) win_w = mcu_w; - else win_w = min_w; - - // check if the image block size needs to be changed for the bottom edge - if (mcu_y + mcu_h <= max_y) win_h = mcu_h; - else win_h = min_h; - - // copy pixels into a contiguous block - if (win_w != mcu_w) - { - uint16_t *cImg; - int p = 0; - cImg = pImg + win_w; - for (int h = 1; h < win_h; h++) - { - p += mcu_w; - for (int w = 0; w < win_w; w++) - { - *cImg = *(pImg + w + p); - cImg++; - } - } - } - - // 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()) - { - _tft->pushImage(mcu_x, mcu_y, win_w, win_h, pImg); - } - - 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/320 x 240/weather-station/GfxUi.h b/examples/320 x 240/weather-station/GfxUi.h deleted file mode 100644 index f381129..0000000 --- a/examples/320 x 240/weather-station/GfxUi.h +++ /dev/null @@ -1,60 +0,0 @@ -/**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/320 x 240/weather-station/SPIFFS_Support.ino b/examples/320 x 240/weather-station/SPIFFS_Support.ino deleted file mode 100644 index 37eefe1..0000000 --- a/examples/320 x 240/weather-station/SPIFFS_Support.ino +++ /dev/null @@ -1,42 +0,0 @@ -/*==================================================================================== - 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/320 x 240/weather-station/WebResource.cpp b/examples/320 x 240/weather-station/WebResource.cpp deleted file mode 100644 index 2020fd1..0000000 --- a/examples/320 x 240/weather-station/WebResource.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/**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/320 x 240/weather-station/WebResource.h b/examples/320 x 240/weather-station/WebResource.h deleted file mode 100644 index acff084..0000000 --- a/examples/320 x 240/weather-station/WebResource.h +++ /dev/null @@ -1,46 +0,0 @@ -/**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/320 x 240/weather-station/settings.h b/examples/320 x 240/weather-station/settings.h deleted file mode 100644 index d4d97c2..0000000 --- a/examples/320 x 240/weather-station/settings.h +++ /dev/null @@ -1,72 +0,0 @@ -/**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_eSPI - -Version 9 -*/ - -// *************************************************************************************** -// WARNING - READ THIS -// -// 3M Flash Size MUST be allocated to SPIFFS using the IDE Tools menu option or else the -// ESP8266 may crash or do strange things (due to lack of error checks in SPIFFS library?) -// *************************************************************************************** -// -// Setup -const int UPDATE_INTERVAL_SECS = 10 * 60; // Update every 10 minutes - -// Pins for the TFT interface are defined in the User_Config.h file inside the TFT_eSPI library - -// TimeClient settings -const float UTC_OFFSET = 1; - -// Wunderground Settings, EDIT to suit your Wunderground key and location -const boolean IS_METRIC = true; // Temperature only? Wind speed units appear to stay in mph. To do: investigate <<<<<<<<<<<<<<<<<<<<<<<<< -//const String WUNDERGRROUND_API_KEY = "WUNDERGROUND KEY HERE"; - const String WUNDERGRROUND_API_KEY = "1c265fajf48s0a82"; // Random key example showing how the above line should look - -// 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 = "Base_Naval"; // 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 = "CHANNEL_ID_HERE"; -const String THINGSPEAK_API_READ_KEY = "API_READ_KEY_HERE"; - -// 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/320 x 240/weather-station/weather-station.ino b/examples/320 x 240/weather-station/weather-station.ino deleted file mode 100644 index ab3cfad..0000000 --- a/examples/320 x 240/weather-station/weather-station.ino +++ /dev/null @@ -1,595 +0,0 @@ -/**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 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 - Barometric pressure added -*/ - -#define SERIAL_MESSAGES - -#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() { -#ifdef SERIAL_MESSAGES - Serial.begin(250000); -#endif - 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 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.setTextDatum(BC_DATUM); - tft.setTextPadding(240); // Pad next drawString() text to full width to over-write old text - tft.drawString(" ", 120, 200); // Clear line above using set padding width - tft.drawString("Fetching weather data...", 120, 200); - //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, 18, 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(); - 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_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, 53); - - 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, 16); - - drawSeparator(54); - - 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); - - //tft.drawString(wunderground.getPressure(), 180, 30); - - weatherText = ""; //wunderground.getWindDir() + " "; - weatherText += String((int)(wunderground.getWindSpeed().toInt() * WIND_SPEED_SCALING)) + WIND_SPEED_UNITS; - - tft.setTextDatum(TC_DATUM); - tft.setTextPadding(tft.textWidth(" 888 mph")); // Max string length? - tft.drawString(weatherText, 128, 136); - - weatherText = wunderground.getPressure(); - - tft.setTextDatum(TR_DATUM); - tft.setTextPadding(tft.textWidth(" 8888mb")); // Max string length? - tft.drawString(weatherText, 230, 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.setTextDatum(TL_DATUM); // Reset datum to normal - 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; - } -}