├── DecodeMode.jpg ├── ESP32_METAR_Reader_E-Paper_v1.0.ino ├── Licence.txt ├── README.md ├── Schematic.JPG ├── SummaryMode.jpg ├── credentials.h └── fonts.h /DecodeMode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G6EJD/ESP32-METAR-Display-For-E-Paper/9a3c0dc561b5b837682e64d1e826aa3955ec8a81/DecodeMode.jpg -------------------------------------------------------------------------------- /ESP32_METAR_Reader_E-Paper_v1.0.ino: -------------------------------------------------------------------------------- 1 | // ################################################################################################################# 2 | // This software, the ideas and concepts is Copyright (c) David Bird 2021 and beyond. 3 | // All rights to this software are reserved. 4 | // It is prohibited to redistribute or reproduce of any part or all of the software contents in any form other than the following: 5 | // 1. You may print or download to a local hard disk extracts for your personal and non-commercial use only. 6 | // 2. You may copy the content to individual third parties for their personal use, but 7 | // *** only if you acknowledge the author David Bird as the source of the material. *** 8 | // 3. You may not, except with my express written permission, distribute or commercially exploit the content. 9 | // 4. You may not transmit it or store it in any other website or other form of electronic retrieval system for commercial purposes. 10 | // 5. You *** MUST *** include all of this copyright and permission notice ('as annotated') and this shall be included 11 | // 6. IF YOU DON'T LIKE THESE LICENCE CONDITIONS DONT USE THE SOFTWARE 12 | // in all copies or substantial portions of the software and where the software use is visible to an end-user. 13 | // THE SOFTWARE IS PROVIDED "AS IS" FOR PRIVATE USE ONLY, IT IS NOT FOR COMMERCIAL USE IN WHOLE OR PART OR CONCEPT. 14 | // FOR PERSONAL USE IT IS SUPPLIED WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, OR FITNESS 15 | // FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 16 | // IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | // ################################################################################################################# 19 | 20 | #include // In-built 21 | WiFiClientSecure client; 22 | 23 | #include // In-built 24 | #include // In-built 25 | #include // In-built 26 | #include // In-built 27 | #include // Built-in 28 | #include // GxEPD2 from Sketch, Include Library, Manage Libraries, search for GxEDP2 29 | #include 30 | #include "credentials.h" 31 | 32 | #define ENABLE_GxEPD2_display 0 33 | #define SCREEN_WIDTH 400 34 | #define SCREEN_HEIGHT 300 35 | 36 | enum alignment {LEFT, RIGHT, CENTRE}; 37 | 38 | // Connections for e.g. LOLIN D32 39 | static const uint8_t EPD_BUSY = 4; // to EPD BUSY 40 | static const uint8_t EPD_CS = 5; // to EPD CS 41 | static const uint8_t EPD_RST = 16; // to EPD RST 42 | static const uint8_t EPD_DC = 17; // to EPD DC 43 | static const uint8_t EPD_SCK = 18; // to EPD CLK 44 | static const uint8_t EPD_MISO = 19; // Master-In Slave-Out not used, as no data from display 45 | static const uint8_t EPD_MOSI = 23; // to EPD DIN 46 | 47 | // Connections for e.g. Waveshare ESP32 e-Paper Driver Board 48 | //static const uint8_t EPD_BUSY = 25; 49 | //static const uint8_t EPD_CS = 15; 50 | //static const uint8_t EPD_RST = 26; 51 | //static const uint8_t EPD_DC = 27; 52 | //static const uint8_t EPD_SCK = 13; 53 | //static const uint8_t EPD_MISO = 12; // Master-In Slave-Out not used, as no data from display 54 | //static const uint8_t EPD_MOSI = 14; 55 | 56 | //GxEPD2_BW display(GxEPD2_154_M09(/*CS*/ EPD_CS, /*DC*/ EPD_DC, /*RST*/ EPD_RST, /*BUSY*/ EPD_BUSY)); // GDEW0154M09 200x200 57 | GxEPD2_BW display(GxEPD2_420(/*CS=5*/ EPD_CS, /*DC=*/ EPD_DC, /*RST=*/ EPD_RST, /*BUSY=*/ EPD_BUSY)); // GDEW042T2 58 | 59 | U8G2_FOR_ADAFRUIT_GFX u8g2Fonts; // Select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall 60 | // Using fonts: 61 | // u8g2_font_helvB08_tf 62 | // u8g2_font_helvB10_tf 63 | // u8g2_font_helvB12_tf 64 | // u8g2_font_helvB14_tf 65 | // u8g2_font_helvB18_tf 66 | // u8g2_font_helvB24_tf 67 | 68 | typedef struct { 69 | String Metar = ""; 70 | String Station = ""; 71 | String StationMode = ""; 72 | String Date = ""; 73 | String Time = ""; 74 | String Description = ""; 75 | float Temperature = 0; 76 | float DewPoint = 0; 77 | float WindChill = 0; 78 | float Humidity = 0; 79 | int Pressure = 0; 80 | int WindSpeed = 0; 81 | int WindDirection = 0; 82 | int Gusting = 0; 83 | String Units = ""; 84 | String Visibility = ""; 85 | String Veering = ""; 86 | int StartV = 0; 87 | int EndV = 0; 88 | String CloudsL1 = ""; 89 | String CloudsL2 = ""; 90 | String CloudsL3 = ""; 91 | String CloudsL4 = ""; 92 | String Conditions = ""; 93 | String Report1 = ""; 94 | String Report2 = ""; 95 | } metar_type; 96 | 97 | const int maximumMETAR = 6; // (actually -1 !!) 98 | metar_type METAR[maximumMETAR]; 99 | 100 | //################ VERSION ################################################## 101 | String version = "(v1.0)"; // for EPAPER Display Unit 102 | //################ PROGRAM VARIABLES and OBJECTS ########################################## 103 | long SleepDuration = 30; // Sleep time in minutes, aligned to the nearest minute boundary, so if 30 will always update at 00 or 30 past the hour 104 | const int time_delay = 20000; // 20-secs between METAR displays in decode mode 105 | int count = 0; 106 | int displayLine = 0; 107 | 108 | void setup() { 109 | Serial.begin(115200); 110 | delay(200); 111 | Serial.println("Starting..."); 112 | StartWiFi(); 113 | InitialiseSystem(); 114 | Serial.println("Starting..."); 115 | ReceiveMETAR(); 116 | StopWiFi(); 117 | if (!summaryMode) display.display(false); // Full screen update mode 118 | BeginSleep(); 119 | } 120 | 121 | void loop() { 122 | // Nothing to do here 123 | } 124 | 125 | void ReceiveMETAR() { 126 | // Change these METAR Stations to suit your needs see: Use this URL address = ftp://tgftp.nws.noaa.gov/data/observations/metar/decoded/ 127 | // to establish your list of sites to retrieve (you must know the 4-letter site dentification) 128 | display.fillScreen(GxEPD_WHITE); 129 | drawString(5, 10, "Receiving METAR data...", LEFT); 130 | display.display(false); 131 | GET_METAR("EGLL", "EGLL London Heathrow", true); 132 | GET_METAR("KIAD", "KIAD Washington, DC", true); // METAR Code, Description, Clear the screen (true) after display or not 133 | GET_METAR("LFPO", "LFPO Paris/Orly", true); 134 | GET_METAR("YSSY", "YSSY Sydney", true); 135 | GET_METAR("FACT", "FACT Cape Town", true); 136 | GET_METAR("GMMX", "GMMX Marakesh", false); 137 | if (summaryMode) { 138 | display.fillScreen(GxEPD_WHITE); 139 | u8g2Fonts.setFont(u8g2_font_helvB08_tf); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall 140 | for (int displayMetar = 0; displayMetar < count; displayMetar++) DisplayMetarSummary(displayMetar); 141 | display.display(false); 142 | } 143 | } 144 | 145 | void GET_METAR(String Station, String Name, bool displayRefresh) { //client function to send/receive GET request data. 146 | String metar, raw_metar; 147 | // https://aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&stationString=EGLL&hoursBeforeNow=1 148 | String url = "/cgi-bin/data/metar.php?dataSource=metars&requestType=retrieve&format=xml&ids=" + station + "&hoursBeforeNow=1"; 149 | //String url = "/adds/dataserver_current/httpparam?datasource=metars&requestType=retrieve&format=xml&mostRecentForEachStation=constraint&hoursBeforeNow=1.25&stationString=" + Station; 150 | Serial.println("Connected, \nRequesting data for : " + Name); 151 | HTTPClient http; 152 | http.begin(host + url); 153 | int httpCode = http.GET(); // Start connection and send HTTP header 154 | if (httpCode > 0) { // HTTP header has been sent and Server response header has been handled 155 | if (httpCode == HTTP_CODE_OK) raw_metar = http.getString(); 156 | http.end(); 157 | } 158 | else 159 | { 160 | http.end(); 161 | Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); 162 | } 163 | metar = raw_metar.substring(raw_metar.indexOf("", 0) + 10, raw_metar.indexOf("", 0)); 164 | Serial.println(metar); 165 | client.stop(); 166 | if (metar.length() > 0) { 167 | if (!summaryMode) { 168 | display.fillScreen(GxEPD_WHITE); 169 | display_metar(metar, Name); 170 | display.display(false); 171 | delay(time_delay); 172 | if (displayRefresh) display.fillScreen(GxEPD_WHITE); 173 | } 174 | else 175 | { 176 | METAR[count].Metar = metar; 177 | count++; 178 | } 179 | } 180 | else 181 | { 182 | drawString(5, 0, Station + " - Station off-air", LEFT); // Now decode METAR 183 | } 184 | } 185 | 186 | void display_metar(String metar, String Station) { 187 | Serial.println("Displaying Metar : " + metar); 188 | int temperature = 0; 189 | int dew_point = 0; 190 | int wind_speedKTS = 0; 191 | char str[130] = ""; 192 | char *parameter; 193 | String conditions_start = " "; 194 | String temp_strA = ""; 195 | String temp_strB = ""; 196 | String conditions_test = "+-BDFGHIMPRSTUV"; // Test for light or heavy (+/-) BR - Mist, RA - Rain SH-Showers VC - Vicinity, etc 197 | // Test metar exercises all decoder functions on screen, uncomment to invoke 198 | //metar = "EGDM 261550Z AUTO 26517G23KT 250V290 6999 R04/1200 4200SW -SH SN NCD SCT002TCU SCT090 FEW222/// 12/M15 Q1001 RERA NOSIG BLU"; 199 | metar.toCharArray(str, 130); 200 | parameter = strtok(str, " "); // Find tokens that are seperated by SPACE 201 | while (parameter != NULL) { 202 | METAR[count].Metar = metar; 203 | u8g2Fonts.setFont(u8g2_font_helvB08_tf); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall 204 | int line_length = 62; 205 | if (metar.length() > line_length) { 206 | drawString(5, 275, metar.substring(0, line_length), LEFT); 207 | drawString(5, 290, metar.substring(line_length), LEFT); 208 | } 209 | else drawString(5, 270, metar, LEFT); 210 | u8g2Fonts.setFont(u8g2_font_helvB12_tf); 211 | temp_strA = strtok(NULL, " "); 212 | METAR[count].Metar = metar; 213 | METAR[count].Station = Station; 214 | METAR[count].Date = temp_strA.substring(0, 2); 215 | METAR[count].Time = temp_strA.substring(2, 6); 216 | drawString(5, 10, Station + " Date:" + METAR[count].Date + " @ " + METAR[count].Time + "Hr", LEFT); 217 | temp_strA = strtok(NULL, " "); 218 | Serial.println(temp_strA); 219 | if (temp_strA == "AUTO") { 220 | METAR[count].StationMode = temp_strA; 221 | temp_strA = strtok(NULL, " "); 222 | } 223 | METAR[count].WindSpeed = temp_strA.substring(3, 5).toInt(); 224 | if (temp_strA.endsWith("KT")) METAR[count].Units = "kts"; 225 | if (temp_strA.endsWith("MPS")) METAR[count].Units = "mps"; 226 | if (temp_strA.endsWith("MPH")) METAR[count].Units = "mph"; 227 | if (temp_strA.endsWith("KPH")) METAR[count].Units = "kph"; 228 | int windDirection = 0; 229 | if (temp_strA.indexOf('G') >= 0) { 230 | if (temp_strA.endsWith("KT")) METAR[count].Gusting = temp_strA.substring(temp_strA.indexOf('G') + 1, temp_strA.indexOf("KT")).toInt(); 231 | if (temp_strA.endsWith("MPS")) METAR[count].Gusting = temp_strA.substring(temp_strA.indexOf('G') + 1, temp_strA.indexOf("MPS")).toInt(); 232 | if (temp_strA.endsWith("MPH")) METAR[count].Gusting = temp_strA.substring(temp_strA.indexOf('G') + 1, temp_strA.indexOf("MPH")).toInt(); 233 | if (temp_strA.endsWith("KPH")) METAR[count].Gusting = temp_strA.substring(temp_strA.indexOf('G') + 1, temp_strA.indexOf("KPH")).toInt(); 234 | } 235 | else temp_strB = temp_strA.substring(5); 236 | if (temp_strA.substring(0, 3) == "VRB") { 237 | METAR[count].Veering = "VRB"; 238 | drawString(275, 30, "VRB", LEFT); 239 | } 240 | else { 241 | METAR[count].WindDirection = temp_strA.substring(0, 3).toInt(); 242 | windDirection = temp_strA.substring(0, 3).toInt(); 243 | } 244 | temp_strA = strtok(NULL, " "); 245 | int startV = -1; 246 | int endV = -1; 247 | if (temp_strA.indexOf('V') >= 0 && temp_strA != "CAVOK") { // Check for variable wind direction 248 | startV = temp_strA.substring(0, 3).toInt(); 249 | endV = temp_strA.substring(4, 7).toInt(); 250 | METAR[count].StartV = startV; 251 | METAR[count].EndV = endV; 252 | // Minimum angle is either ABS(AngleA- AngleB) or (360-ABS(AngleA-AngleB)) 253 | temp_strA = strtok(NULL, " "); // Move to the next token/item 254 | } 255 | DisplayDisplayWindSection(330, 85, windDirection, METAR[count].WindSpeed, startV, endV, 50); 256 | if (temp_strA == "////") { 257 | temp_strB = "No Visibility Rep."; 258 | METAR[count].Visibility = temp_strB.toInt(); 259 | } 260 | else { 261 | temp_strB = ""; 262 | METAR[count].Visibility = temp_strB.toInt(); 263 | } 264 | if (temp_strA == "CAVOK") { 265 | drawString(5, 33, "Visibility and Conditions good", LEFT); 266 | METAR[count].Conditions = "Visibility and Conditions good"; 267 | } 268 | else { 269 | if (temp_strA != "////") { 270 | if (temp_strA == "9999") { 271 | temp_strB = "Visibility excellent"; 272 | METAR[count].Conditions = "Visibility excellent"; 273 | } 274 | else 275 | { 276 | String vis = temp_strA; 277 | while (vis.startsWith("0")) vis = vis.substring(1); // trim leading '0' 278 | if (vis.endsWith("SM")) temp_strB = vis.substring(0, vis.indexOf("SM")) + " Statute Miles"; 279 | else temp_strB = vis + " Metres of visibility"; 280 | METAR[count].Visibility = temp_strB; 281 | } 282 | } 283 | } 284 | drawString(5, 28, temp_strB, LEFT); 285 | temp_strA = strtok(NULL, " "); 286 | if ( temp_strA.startsWith("R") && !temp_strA.startsWith("RA")) { // Ignore an RA for Rain weather report for now 287 | temp_strA = strtok(NULL, " "); // If there was a Variable report, move to the next item 288 | } 289 | if ( temp_strA.startsWith("R") && !temp_strA.startsWith("RA")) { // Ignore an RA for Rain weather report for now, there can be two 290 | temp_strA = strtok(NULL, " "); // If there was a Variable report, move to the next item 291 | } 292 | if (temp_strA.length() >= 5 && temp_strA.substring(0, 1) != "+" && temp_strA.substring(0, 1) != "-" && (temp_strA.endsWith("N") || temp_strA.endsWith("S") || temp_strA.endsWith("E") || temp_strA.endsWith("W")) ) { 293 | conditions_start = temp_strA.substring(4); 294 | conditions_start = conditions_start.substring(0, 1); 295 | if (conditions_start == "N" || conditions_start == "S" || conditions_start == "E" || conditions_start == "W") { 296 | drawString(5, 45, "/" + temp_strA + " Mts Visibility", LEFT); 297 | METAR[count].Visibility += "/" + temp_strA + " Mts Visibility"; 298 | } 299 | temp_strA = strtok(NULL, " "); 300 | } 301 | drawString(5, 60, "Additional Wx Reports:", LEFT); 302 | conditions_start = temp_strA.substring(0, 1); 303 | temp_strB = temp_strA.substring(0, 3); 304 | if ((temp_strA == "//" || conditions_test.indexOf(conditions_start) >= 0) 305 | && !(valid_cloud_report(temp_strB)) // Don't process a cloud report that starts with the same letter as a weather condition report 306 | && temp_strB != "NSC" 307 | && !temp_strA.startsWith("M0")) { 308 | temp_strB = ""; 309 | if (conditions_start == "-" || conditions_start == "+") { 310 | if (conditions_start == "-") { 311 | temp_strB = "Light "; 312 | } else { 313 | temp_strB = "Heavy "; 314 | } 315 | temp_strA = temp_strA.substring(1); // Remove leading + or - and can't modify same variable recursively 316 | } 317 | if (temp_strA.length() <= 3) { 318 | drawString(5, 75, temp_strB + display_conditions(temp_strA), LEFT); 319 | METAR[count].Conditions = temp_strB + display_conditions(temp_strA); 320 | } 321 | else { 322 | drawString(5, 90, temp_strB + display_conditions(temp_strA.substring(0, 2)) + "/" + display_conditions(temp_strA.substring(2, 4)), LEFT); 323 | if (temp_strA.length() >= 6) { // sometimes up to three cateries are reported 324 | drawString(50, 115, "/" + display_conditions(temp_strA.substring(4, 6)), LEFT); 325 | METAR[count].Conditions += "/" + display_conditions(temp_strA.substring(4, 6)); 326 | } 327 | } 328 | parameter = strtok(NULL, " "); 329 | temp_strA = parameter; 330 | } 331 | conditions_start = temp_strA.substring(0, 1); 332 | temp_strB = temp_strA.substring(0, 3); 333 | if ((temp_strA == "//" || conditions_test.indexOf(conditions_start) >= 0) 334 | && !(valid_cloud_report(temp_strB)) // Don't process a cloud report that starts with the same letter as a weather condition report 335 | && temp_strB != "NSC" 336 | && !temp_strA.startsWith("M0")) { 337 | temp_strB = ""; 338 | if (conditions_start == "-" || conditions_start == "+") { 339 | if (conditions_start == "-") { 340 | temp_strB = "Light "; 341 | } else { 342 | temp_strB = "Heavy "; 343 | } 344 | temp_strA = temp_strA.substring(1); // Remove leading + or - and can't modify same variable recursively 345 | } 346 | if (temp_strA.length() == 2) { 347 | drawString(5, 90, temp_strB + display_conditions(temp_strA), LEFT); 348 | METAR[count].Conditions = temp_strB + display_conditions(temp_strA); 349 | } 350 | else { 351 | if (temp_strA.length() >= 5) { // sometimes up to three cateries are reported 352 | drawString(5, 105, "Poor Vert Visibility", LEFT); 353 | METAR[count].Conditions = "Poor Vert Visibility"; 354 | } 355 | else { 356 | drawString(5, 105, temp_strB + display_conditions(temp_strA.substring(0, 2)), LEFT); 357 | METAR[count].Conditions = temp_strB + display_conditions(temp_strA.substring(0, 2)); 358 | } 359 | } 360 | parameter = strtok(NULL, " "); 361 | temp_strA = parameter; 362 | } 363 | display.drawLine(5, 20, 400, 20, GxEPD_BLACK); 364 | if (temp_strA == "///" || temp_strA == "////" || temp_strA == "/////" || temp_strA == "//////") { 365 | temp_strA = "No CC Rep."; 366 | METAR[count].CloudsL1 = "No Cloud Cover Report"; 367 | temp_strA = strtok(NULL, " "); 368 | } 369 | else 370 | { 371 | if (valid_cloud_report(temp_strA) || temp_strA.startsWith("VV/")) { 372 | temp_strA = convert_clouds(temp_strA); 373 | drawString(5, 125, temp_strA, LEFT); 374 | METAR[count].CloudsL1 = temp_strA; 375 | temp_strA = strtok(NULL, " "); 376 | } 377 | if (valid_cloud_report(temp_strA)) { 378 | temp_strA = convert_clouds(temp_strA); 379 | drawString(5, 145, temp_strA, LEFT); 380 | METAR[count].CloudsL2 = temp_strA; 381 | temp_strA = strtok(NULL, " "); 382 | } 383 | if (valid_cloud_report(temp_strA)) { 384 | temp_strA = convert_clouds(temp_strA); 385 | drawString(5, 165, temp_strA, LEFT); 386 | METAR[count].CloudsL3 = temp_strA; 387 | temp_strA = strtok(NULL, " "); 388 | } 389 | if (valid_cloud_report(temp_strA)) { 390 | temp_strA = convert_clouds(temp_strA); 391 | drawString(5, 185, temp_strA, LEFT); 392 | METAR[count].CloudsL4 = temp_strA; 393 | temp_strA = strtok(NULL, " "); 394 | } 395 | } 396 | if (temp_strA.indexOf("/") <= 0) { 397 | temp_strA = "00/00"; 398 | } 399 | String temp_sign = ""; 400 | if (temp_strA.startsWith("M")) { 401 | temperature = 0 - temp_strA.substring(1, 3).toInt(); 402 | if (temperature == 0) { 403 | temp_sign = "-"; // Reports of M00, meaning between -0.1 and -0.9C 404 | } 405 | } 406 | else { 407 | temperature = temp_strA.substring(0, 2).toInt(); 408 | if (temperature >= 0 && temperature < 10) { 409 | temp_sign = " "; // Aligns for 2-digit temperatures e.g. " 1'C" and "11'C" 410 | } 411 | } 412 | temp_strB = temp_strA.substring(temp_strA.indexOf('/') + 1); 413 | if (temp_strB.startsWith("M")) { 414 | dew_point = 0 - temp_strB.substring(1, 3).toInt(); 415 | } 416 | else { 417 | dew_point = temp_strB.substring(0, 2).toInt(); 418 | } 419 | METAR[count].DewPoint = dew_point; 420 | drawString(300, 225, "DewP " + String(METAR[count].DewPoint, 0) + "°", LEFT); 421 | u8g2Fonts.setFont(u8g2_font_helvB12_tf); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall 422 | if (wind_speedKTS > 3 && temperature <= 14) { 423 | temp_sign = ""; 424 | int wind_chill = int(calc_windchill(temperature, wind_speedKTS)); 425 | if (wind_chill >= 0 && wind_chill < 10) { 426 | temp_sign = " "; // Aligns for 2-digit temperatures e.g. " 1'C" and "11'C" 427 | } 428 | METAR[count].WindChill = wind_chill; 429 | drawString(300, 210, "WindC " + temp_sign + String(wind_chill) + "°", LEFT); 430 | } 431 | temp_sign = ""; 432 | if (dew_point >= 0 && dew_point < 10) { 433 | temp_sign = " "; // Aligns for 2-digit temperatures e.g. " 1'C" and "11'C" 434 | } 435 | int RH = calc_rh(temperature, dew_point); 436 | u8g2Fonts.setFont(u8g2_font_helvB18_tf); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall 437 | METAR[count].Temperature = temperature; 438 | METAR[count].Humidity = RH; 439 | drawString(315, 175, temp_sign + String(temperature) + "° " + String(RH) + "%", CENTRE); 440 | u8g2Fonts.setFont(u8g2_font_helvB12_tf); 441 | if (temperature >= 20) { 442 | float T = (temperature * 9 / 5) + 32; 443 | float RHx = RH; 444 | int tHI = (-42.379 + (2.04901523 * T) + (10.14333127 * RHx) - (0.22475541 * T * RHx) - (0.00683783 * T * T) - (0.05481717 * RHx * RHx) + (0.00122874 * T * T * RHx) + (0.00085282 * T * RHx * RHx) - (0.00000199 * T * T * RHx * RHx) - 32 ) * 5 / 9; 445 | drawString(295, 240, "HeatX " + String(tHI) + "°", LEFT); 446 | } 447 | temp_strA = strtok(NULL, " "); 448 | temp_strA.trim(); 449 | if (temp_strA.startsWith("Q")) { 450 | if (temp_strA.substring(1, 2) == "0") { 451 | temp_strA = " " + temp_strA.substring(2); 452 | } 453 | else { 454 | temp_strA = temp_strA.substring(1); 455 | } 456 | u8g2Fonts.setFont(u8g2_font_helvB14_tf); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall 457 | METAR[count].Pressure = temp_strA.toInt(); 458 | drawString(295, 195, String(METAR[count].Pressure) + " hPa", LEFT); 459 | u8g2Fonts.setFont(u8g2_font_helvB12_tf); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall 460 | } 461 | else 462 | { 463 | temp_strA = temp_strA.substring(1); 464 | METAR[count].Pressure = temp_strA.toInt(); 465 | u8g2Fonts.setFont(u8g2_font_helvB14_tf); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall 466 | drawString(300, 195, String(METAR[count].Pressure / 100.0, 2) + " in", LEFT); 467 | u8g2Fonts.setFont(u8g2_font_helvB12_tf); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall 468 | } 469 | temp_strA = strtok(NULL, " "); // Get last tokens, can be a secondary weather report 470 | METAR[count].Report1 = Process_secondary_reports(temp_strA); 471 | drawString(5, 210, METAR[count].Report1, LEFT); 472 | temp_strA = strtok(NULL, " "); // Get last tokens, can be a secondary weather report 473 | METAR[count].Report2 = Process_secondary_reports(temp_strA); 474 | drawString(5, 230, METAR[count].Report2, LEFT); 475 | parameter = NULL; // Reset the 'str' pointer, so end of report decoding 476 | } 477 | DisplayMetar(); 478 | if (!summaryMode) ClearVariables(); 479 | count++; 480 | } 481 | 482 | 483 | String convert_clouds(String source) { 484 | String height = source.substring(3, 6); 485 | String cloud = source.substring(0, 3); 486 | String warning = " "; 487 | while (height.startsWith("0")) height = height.substring(1); 488 | if (source.endsWith("TCU") || source.endsWith("CB")) { 489 | drawString(5, 105, "Warning - storm clouds detected", LEFT); 490 | warning = " (storm) "; 491 | } 492 | if (cloud != "SKC" && cloud != "CLR" && height != " ") { 493 | height = height + "00ft - "; 494 | } else height = ""; 495 | if (source == "VV///") return "No cloud reported"; 496 | if (cloud == "BKN") return height + "Broken" + warning + "clouds"; 497 | if (cloud == "SKC") return "Clear skies"; 498 | if (cloud == "FEW") return height + "Few" + warning + "clouds"; 499 | if (cloud == "NCD") return "No clouds detected"; 500 | if (cloud == "NSC") return "No signficiant clouds"; 501 | if (cloud == "OVC") return height + "Overcast" + warning; 502 | if (cloud == "SCT") return height + "Scattered" + warning + "clouds"; 503 | return ""; 504 | } 505 | 506 | int min_val(int num1, int num2) { 507 | if (num1 > num2) return num2; 508 | else return num1; 509 | } 510 | 511 | float calc_rh(int temp, int dewp) { 512 | return 100 * (exp((17.271 * dewp) / (237.7 + dewp))) / (exp((17.271 * temp) / (237.7 + temp))) + 0.5; 513 | } 514 | 515 | float calc_windchill(int temperature, int wind_speed) { 516 | float result; 517 | // Derived from wind_chill = 13.12 + 0.6215 * Tair - 11.37 * POWER(wind_speed,0.16)+0.3965 * Tair * POWER(wind_speed,0.16) 518 | wind_speed = wind_speed * 1.852; // Convert to Kph 519 | result = 13.12 + 0.6215 * temperature - 11.37 * pow(wind_speed, 0.16) + 0.3965 * temperature * pow(wind_speed, 0.16); 520 | if (result < 0 ) return result - 0.5; 521 | else return result + 0.5; 522 | } 523 | 524 | String Process_secondary_reports(String temp_strA) { 525 | temp_strA.trim(); 526 | if (temp_strA == "NOSIG") return "No significant change expected"; 527 | if (temp_strA == "TEMPO") return "Temporary conditions expected"; 528 | if (temp_strA == "RADZ") return "Recent Rain/Drizzle"; 529 | if (temp_strA == "RERA") return "Recent Moderate/Heavy Rain"; 530 | if (temp_strA == "REDZ") return "Recent Drizzle"; 531 | if (temp_strA == "RESN") return "Recent Moderate/Heavy Snow"; 532 | if (temp_strA == "RASN") return "Recent Moderate/Heavy Rain & Snow"; 533 | if (temp_strA == "RESG") return "Recent Moderate/Heavy Snow grains"; 534 | if (temp_strA == "REGR") return "Recent Moderate/Heavy Hail"; 535 | if (temp_strA == "RETS") return "Recent Thunder storms"; 536 | return ""; 537 | } 538 | 539 | String display_conditions(String WX_state) { 540 | if (WX_state == "//") return "No weather reported"; 541 | if (WX_state == "VC") return "Vicinity has"; 542 | if (WX_state == "BL") return "Blowing"; 543 | if (WX_state == "SH") return "Showers"; 544 | if (WX_state == "TS") return "Thunderstorms"; 545 | if (WX_state == "FZ") return "Freezing"; 546 | if (WX_state == "UP") return "Unknown"; 547 | if (WX_state == "MI") return "Shallow"; 548 | if (WX_state == "PR") return "Partial"; 549 | if (WX_state == "BC") return "Patches"; 550 | if (WX_state == "DR") return "Low drifting"; 551 | if (WX_state == "IC") return "Ice crystals"; 552 | if (WX_state == "PL") return "Ice pellets"; 553 | if (WX_state == "GR") return "Hail"; 554 | if (WX_state == "GS") return "Small hail"; 555 | if (WX_state == "DZ") return "Drizzle"; 556 | if (WX_state == "RA") return "Rain"; 557 | if (WX_state == "SN") return "Snow"; 558 | if (WX_state == "SG") return "Snow grains"; 559 | if (WX_state == "DU") return "Widespread dust"; 560 | if (WX_state == "SA") return "Sand"; 561 | if (WX_state == "HZ") return "Haze"; 562 | if (WX_state == "PY") return "Spray"; 563 | if (WX_state == "BR") return "Mist"; 564 | if (WX_state == "FG") return "Fog"; 565 | if (WX_state == "FU") return "Smoke"; 566 | if (WX_state == "VA") return "Volcanic ash"; 567 | if (WX_state == "DS") return "Dust storm"; 568 | if (WX_state == "PO") return "Well developed dust/sand swirls"; 569 | if (WX_state == "SQ") return "Squalls"; 570 | if (WX_state == "FC") return "Funnel clouds/Tornadoes"; 571 | if (WX_state == "SS") return "Sandstorm"; 572 | return ""; 573 | } 574 | 575 | boolean valid_cloud_report(String temp_strA) { 576 | if (temp_strA.startsWith("BKN") || 577 | temp_strA.startsWith("CLR") || 578 | temp_strA.startsWith("FEW") || 579 | temp_strA.startsWith("NCD") || 580 | temp_strA.startsWith("NSC") || 581 | temp_strA.startsWith("OVC") || 582 | temp_strA.startsWith("SCT") || 583 | temp_strA.startsWith("SKC") || 584 | temp_strA.endsWith("CB") || 585 | temp_strA.endsWith("TCU")) { 586 | return true; 587 | } 588 | else return false; 589 | } 590 | 591 | void DisplayMetar() { 592 | Serial.println(" Metar = " + METAR[count].Metar); 593 | Serial.println(" Station = " + METAR[count].Station); 594 | Serial.println(" Station Mode = " + METAR[count].StationMode); 595 | Serial.println(" Date = " + METAR[count].Date); 596 | Serial.println(" Time = " + METAR[count].Time); 597 | Serial.println(" Description = " + METAR[count].Description); 598 | Serial.println(" Temperature = " + String(METAR[count].Temperature)); 599 | Serial.println(" Dewpoint = " + String(METAR[count].DewPoint)); 600 | Serial.println(" WindChill = " + String(METAR[count].WindChill)); 601 | Serial.println(" Humidity = " + String(METAR[count].Humidity)); 602 | Serial.println(" Pressure = " + String(METAR[count].Pressure)); 603 | Serial.println(" WindSpeed = " + String(METAR[count].WindSpeed)); 604 | Serial.println("Wind Direction = " + String(METAR[count].WindDirection)); 605 | Serial.println(" Gusting = " + String(METAR[count].Gusting)); 606 | Serial.println(" Visibility = " + String(METAR[count].Visibility)); 607 | Serial.println(" VRB = " + METAR[count].Veering); 608 | Serial.println(" Veering Start = " + String(METAR[count].StartV)); 609 | Serial.println(" Veering End = " + String(METAR[count].EndV)); 610 | Serial.println(" Cloud Level-1 = " + METAR[count].CloudsL1); 611 | Serial.println(" Cloud Level-2 = " + METAR[count].CloudsL2); 612 | Serial.println(" Cloud Level-3 = " + METAR[count].CloudsL3); 613 | Serial.println(" Cloud Level-4 = " + METAR[count].CloudsL4); 614 | Serial.println(" Conditions = " + METAR[count].Conditions); 615 | Serial.println(" Report-1 = " + METAR[count].Report1); 616 | Serial.println(" Report-2 = " + METAR[count].Report2); 617 | Serial.println("---------------------------------------------"); 618 | } 619 | 620 | void ClearVariables() { 621 | METAR[count].Metar = ""; 622 | METAR[count].Station = ""; 623 | METAR[count].StationMode = ""; 624 | METAR[count].Date = ""; 625 | METAR[count].Time = ""; 626 | METAR[count].Description = ""; 627 | METAR[count].Temperature = 0; 628 | METAR[count].DewPoint = 0; 629 | METAR[count].WindChill = 0; 630 | METAR[count].Humidity = 0; 631 | METAR[count].Pressure = 0; 632 | METAR[count].WindSpeed = 0; 633 | METAR[count].WindDirection = 0; 634 | METAR[count].Gusting = 0; 635 | METAR[count].Visibility = ""; 636 | METAR[count].Veering = ""; 637 | METAR[count].StartV = 0; 638 | METAR[count].EndV = 0; 639 | METAR[count].CloudsL1 = ""; 640 | METAR[count].CloudsL2 = ""; 641 | METAR[count].CloudsL3 = ""; 642 | METAR[count].CloudsL4 = ""; 643 | METAR[count].Conditions = ""; 644 | METAR[count].Report1 = ""; 645 | METAR[count].Report2 = ""; 646 | } 647 | 648 | void DisplayMetarSummary(int count) { 649 | String Line1 = "", Line2 = ""; 650 | int lineLength = 62; 651 | if (METAR[count].Metar.length() > lineLength) { 652 | Line1 = METAR[count].Metar.substring(0, lineLength); 653 | Line2 = METAR[count].Metar.substring(lineLength + 1); 654 | } 655 | else Line1 = METAR[count].Metar; 656 | drawString(5, 10 + displayLine * 18, Line1, LEFT); 657 | if (Line2 != "") { 658 | displayLine++; 659 | drawString(5, 10 + displayLine * 18, Line2, LEFT); 660 | } 661 | displayLine++; 662 | if (count < maximumMETAR - 1) drawString(5, 10 + displayLine * 18, "~~~~~~~~~", LEFT); 663 | displayLine++; 664 | Serial.println("Metar = " + METAR[count].Metar); 665 | } 666 | 667 | void drawString(int x, int y, String text, alignment align) { 668 | int16_t x1, y1; //the bounds of x,y and w and h of the variable 'text' in pixels. 669 | uint16_t w, h; 670 | display.setTextWrap(false); 671 | display.getTextBounds(text, x, y, &x1, &y1, &w, &h); 672 | if (align == RIGHT) x = x - w; 673 | if (align == CENTRE) x = x - w / 2; 674 | u8g2Fonts.setCursor(x, y + h); 675 | u8g2Fonts.print(text); 676 | } 677 | 678 | void DisplayDisplayWindSection(int x, int y, float angle, float windspeed, int startV, int endV, int Cradius) { 679 | u8g2Fonts.setFont(u8g2_font_helvB08_tf); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall 680 | arrow(x, y, Cradius - 22, angle, 15, 20); // Awidth, Alength 681 | if (startV >= 0) arrow(x, y, Cradius - 24, startV, 8, 15); // Awidth, Alength Veering 1 682 | if (startV >= 0) arrow(x, y, Cradius - 24, endV, 8, 15); // Awidth, Alength Veering 2 683 | int dxo, dyo, dxi, dyi; 684 | display.drawCircle(x, y, Cradius, GxEPD_BLACK); // Draw compass circle 685 | display.drawCircle(x, y, Cradius + 1, GxEPD_BLACK); // Draw compass circle 686 | display.drawCircle(x, y, Cradius * 0.7, GxEPD_BLACK); // Draw compass inner circle 687 | for (float a = 0; a < 360; a = a + 22.5) { 688 | dxo = Cradius * cos((a - 90) * PI / 180); 689 | dyo = Cradius * sin((a - 90) * PI / 180); 690 | if (a == 45) drawString(dxo + x + 12, dyo + y - 5, "NE", CENTRE); 691 | if (a == 135) drawString(dxo + x + 5, dyo + y + 5, "SE", CENTRE); 692 | if (a == 225) drawString(dxo + x - 12, dyo + y + 3, "SW", CENTRE); 693 | if (a == 315) drawString(dxo + x - 15, dyo + y - 5, "NW", CENTRE); 694 | dxi = dxo * 0.9; 695 | dyi = dyo * 0.9; 696 | display.drawLine(dxo + x, dyo + y, dxi + x, dyi + y, GxEPD_BLACK); 697 | dxo = dxo * 0.7; 698 | dyo = dyo * 0.7; 699 | dxi = dxo * 0.9; 700 | dyi = dyo * 0.9; 701 | display.drawLine(dxo + x, dyo + y, dxi + x, dyi + y, GxEPD_BLACK); 702 | } 703 | drawString(x + 1, y - Cradius - 12, "N", CENTRE); 704 | drawString(x + 1, y + Cradius + 4, "S", CENTRE); 705 | drawString(x - Cradius - 10, y - 3, "W", CENTRE); 706 | drawString(x + Cradius + 8, y - 3, "E", CENTRE); 707 | u8g2Fonts.setFont(u8g2_font_helvB08_tf); 708 | drawString(x + 5, y + 20, String(angle, 0) + "°", CENTRE); 709 | drawString(x + 1, y + 9, METAR[count].Units, CENTRE); 710 | int veering = min_val(360 - abs(startV - endV), abs(startV - endV)); 711 | if (veering > 0 ) drawString(x + 5, y + Cradius + 15, "Veering: " + String(veering) + "*", CENTRE); 712 | u8g2Fonts.setFont(u8g2_font_helvB12_tf); 713 | drawString(x - (WindDegToOrdinalDirection(angle).length() < 3 ? 5 : 10), y - 19, WindDegToOrdinalDirection(angle), CENTRE); 714 | drawString(x - 5, y - 2, String(windspeed, (METAR[count].Gusting > 0 ? 0 : 1)) + (METAR[count].Gusting > 0 ? "/" + String(METAR[count].Gusting) : ""), CENTRE); 715 | } 716 | 717 | void arrow(int x, int y, int Asize, float Aangle, int Awidth, int Alength) { 718 | float dx = (Asize + 28) * cos((Aangle - 90) * PI / 180) + x; // calculate X position 719 | float dy = (Asize + 28) * sin((Aangle - 90) * PI / 180) + y; // calculate Y position 720 | float x1 = 0; float y1 = Alength; 721 | float x2 = Awidth / 2; float y2 = Awidth / 2; 722 | float x3 = -Awidth / 2; float y3 = Awidth / 2; 723 | float angle = Aangle * PI / 180; 724 | float xx1 = x1 * cos(angle) - y1 * sin(angle) + dx; 725 | float yy1 = y1 * cos(angle) + x1 * sin(angle) + dy; 726 | float xx2 = x2 * cos(angle) - y2 * sin(angle) + dx; 727 | float yy2 = y2 * cos(angle) + x2 * sin(angle) + dy; 728 | float xx3 = x3 * cos(angle) - y3 * sin(angle) + dx; 729 | float yy3 = y3 * cos(angle) + x3 * sin(angle) + dy; 730 | display.fillTriangle(xx1, yy1, xx2, yy2, xx3, yy3, GxEPD_BLACK); 731 | } 732 | 733 | String WindDegToOrdinalDirection(float winddirection) { 734 | if (winddirection >= 348.75 || winddirection < 11.25) return "N"; 735 | if (winddirection >= 11.25 && winddirection < 33.75) return "NNE"; 736 | if (winddirection >= 33.75 && winddirection < 56.25) return "NE"; 737 | if (winddirection >= 56.25 && winddirection < 78.75) return "ENE"; 738 | if (winddirection >= 78.75 && winddirection < 101.25) return "E"; 739 | if (winddirection >= 101.25 && winddirection < 123.75) return "ESE"; 740 | if (winddirection >= 123.75 && winddirection < 146.25) return "SE"; 741 | if (winddirection >= 146.25 && winddirection < 168.75) return "SSE"; 742 | if (winddirection >= 168.75 && winddirection < 191.25) return "S"; 743 | if (winddirection >= 191.25 && winddirection < 213.75) return "SSW"; 744 | if (winddirection >= 213.75 && winddirection < 236.25) return "SW"; 745 | if (winddirection >= 236.25 && winddirection < 258.75) return "WSW"; 746 | if (winddirection >= 258.75 && winddirection < 281.25) return "W"; 747 | if (winddirection >= 281.25 && winddirection < 303.75) return "WNW"; 748 | if (winddirection >= 303.75 && winddirection < 326.25) return "NW"; 749 | if (winddirection >= 326.25 && winddirection < 348.75) return "NNW"; 750 | return " ? "; 751 | } 752 | 753 | void BeginSleep() { 754 | esp_sleep_enable_timer_wakeup(SleepDuration * 60 * 1000000LL); // in Secs, 1000000LL converts to Secs 755 | Serial.println("Starting deep - sleep period..."); 756 | esp_deep_sleep_start(); // Sleep for e.g. 30 minutes 757 | } 758 | 759 | void StartWiFi() { 760 | Serial.println("\r\nConnecting to : " + String(ssid)); 761 | IPAddress dns(8, 8, 8, 8); // Use Google DNS 762 | WiFi.disconnect(); 763 | WiFi.mode(WIFI_STA); // switch off AP 764 | WiFi.setAutoConnect(true); 765 | WiFi.begin(ssid, password); 766 | while (WiFi.waitForConnectResult() != WL_CONNECTED) { 767 | Serial.printf("STA : Failed!\n"); 768 | WiFi.disconnect(false); 769 | delay(10000); 770 | WiFi.reconnect(); 771 | } 772 | if (WiFi.status() == WL_CONNECTED) { 773 | Serial.println("WiFi connected at : " + WiFi.localIP().toString()); 774 | } 775 | else Serial.println("WiFi connection *** FAILED ***"); 776 | } 777 | 778 | void StopWiFi() { 779 | WiFi.disconnect(); 780 | WiFi.mode(WIFI_OFF); 781 | Serial.println("WiFi switched Off"); 782 | } 783 | 784 | void InitialiseSystem() { 785 | Serial.begin(115200); 786 | while (!Serial); 787 | delay(1000); 788 | Serial.println(String(__FILE__) + "\nStarting..."); 789 | display.init(115200, true, 2, false); 790 | //// display.init(); for older Waveshare HAT's 791 | SPI.end(); 792 | SPI.begin(EPD_SCK, EPD_MISO, EPD_MOSI, EPD_CS); 793 | u8g2Fonts.begin(display); // connect u8g2 procedures to Adafruit GFX 794 | u8g2Fonts.setFontMode(1); // use u8g2 transparent mode (this is default) 795 | u8g2Fonts.setFontDirection(0); // left to right (this is default) 796 | u8g2Fonts.setForegroundColor(GxEPD_BLACK); // apply Adafruit GFX color 797 | u8g2Fonts.setBackgroundColor(GxEPD_WHITE); // apply Adafruit GFX color 798 | u8g2Fonts.setFont(u8g2_font_helvB10_tf); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall 799 | display.setRotation(0); 800 | display.fillScreen(GxEPD_WHITE); 801 | display.setFullWindow(); 802 | } 803 | // 775 lines of code 804 | -------------------------------------------------------------------------------- /Licence.txt: -------------------------------------------------------------------------------- 1 | This software, the ideas and concepts is Copyright (c) David Bird 2021 and beyond. 2 | All rights to this software are reserved. 3 | It is prohibited to redistribute or reproduce of any part or all of the software contents in any form other than the following: 4 | 1. You may print or download to a local hard disk extracts for your personal and non-commercial use only. 5 | 2. You may copy the content to individual third parties for their personal use, but only if you acknowledge the author David Bird as the source of the material. 6 | 3. You may not, except with my express written permission, distribute or commercially exploit the content. 7 | 4. You may not transmit it or store it in any other website or other form of electronic retrieval system for commercial purposes. 8 | 5. You MUST include all of this copyright and permission notice ('as annotated') and this shall be included in all copies or substantial portions of the software and where the software use is visible to an end-user. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS" FOR PRIVATE USE ONLY, IT IS NOT FOR COMMERCIAL USE IN WHOLE OR PART OR CONCEPT. 11 | 12 | FOR PERSONAL USE IT IS SUPPLIED WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 13 | 14 | IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDER 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. 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | *** DO-NOT USE THIS SOFTWARE UNLESS YOU WISH TO BE BOUND TO THE SOFTWARE LICENCE *** 2 | 3 | # ESP32 METAR Display For E-Paper Displays 4 | An ESP32 receives METAR Datagrams, then decodes and displays the result 5 | 6 | 1. Download all files into a sketch folder with the same name as the INO file 7 | 8 | 2. Open the IDE 9 | 10 | 3. Click on the 'creedentials.h' TAB 11 | 12 | 4. Edit your Wifi credentials accordingly 13 | 14 | 5. Choose between summary or full-decode mode 15 | 16 | 6. Click on the main INO TAB 17 | 18 | 7. Edit the station names you wish to receive and decode 19 | 20 | 8. Compile and upload 21 | 22 | Summary Mode 23 | ![alt_text, width="300"](/SummaryMode.jpg) 24 | 25 | Decode Mode 26 | ![alt_text, width="300"](/DecodeMode.jpg) 27 | 28 | Wiring Schematic for ALL Waveshare E-Paper Displays 29 | ![alt_text, width="300"](/Schematic.JPG) 30 | 31 | -------------------------------------------------------------------------------- /Schematic.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G6EJD/ESP32-METAR-Display-For-E-Paper/9a3c0dc561b5b837682e64d1e826aa3955ec8a81/Schematic.JPG -------------------------------------------------------------------------------- /SummaryMode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G6EJD/ESP32-METAR-Display-For-E-Paper/9a3c0dc561b5b837682e64d1e826aa3955ec8a81/SummaryMode.jpg -------------------------------------------------------------------------------- /credentials.h: -------------------------------------------------------------------------------- 1 | // Change to your WiFi credentials 2 | const char* ssid = "your-SSID"; 3 | const char* password = "your-PASSWORD"; 4 | const char* host = "https://aviationweather.gov"; 5 | String Units = "M"; 6 | bool summaryMode = false; // True for summary mode false for full decode 7 | -------------------------------------------------------------------------------- /fonts.h: -------------------------------------------------------------------------------- 1 | const uint8_t DejaVu_Sans_Bold_11Bitmaps[] PROGMEM = { 2 | 0x00, 0xDB, 0x6C, 0x36, 0xAA, 0xA0, 0x12, 0x0B, 0x05, 0x8F, 0xE2, 0x47, 3 | 0xF1, 0xA0, 0x90, 0x10, 0x7E, 0xD0, 0xF0, 0xFE, 0x1E, 0x16, 0xFC, 0x10, 4 | 0x10, 0x61, 0x12, 0x42, 0x58, 0x32, 0x00, 0x98, 0x34, 0x84, 0x91, 0x0C, 5 | 0x3C, 0x30, 0x18, 0x0E, 0x6D, 0xB6, 0x73, 0x18, 0xF6, 0x69, 0x96, 0x66, 6 | 0xCC, 0xCC, 0xCC, 0x66, 0xCC, 0x66, 0x66, 0x66, 0xCC, 0x64, 0xA4, 0xC0, 7 | 0x00, 0x10, 0x10, 0x10, 0xFE, 0x10, 0x10, 0x10, 0x66, 0x48, 0xEE, 0xD8, 8 | 0x11, 0x88, 0x46, 0x21, 0x18, 0x80, 0x79, 0x9B, 0x36, 0x6C, 0xD9, 0xB3, 9 | 0x3C, 0xF0, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x7E, 0xF8, 0x18, 0x30, 0xC3, 10 | 0x0C, 0x30, 0x7E, 0x79, 0x18, 0x33, 0xC0, 0xC1, 0xA3, 0x3C, 0x1C, 0x3C, 11 | 0x6C, 0x4C, 0x8C, 0xFE, 0x0C, 0x0C, 0xF9, 0x83, 0x07, 0xC0, 0xC1, 0x83, 12 | 0x7C, 0x78, 0xC3, 0x07, 0xCC, 0xD9, 0xB3, 0x3C, 0xFC, 0x18, 0x60, 0xC3, 13 | 0x06, 0x18, 0x30, 0x79, 0x9B, 0x31, 0x8C, 0xD9, 0xB3, 0x3C, 0x79, 0x9B, 14 | 0x36, 0x67, 0xC1, 0x86, 0x3C, 0xD8, 0x0D, 0x80, 0x66, 0x00, 0x66, 0x48, 15 | 0x02, 0x1C, 0xE0, 0xE0, 0x1C, 0x02, 0xFE, 0x00, 0xFE, 0x80, 0x70, 0x0E, 16 | 0x0E, 0x70, 0x80, 0xF0, 0x63, 0x9C, 0x60, 0x06, 0x18, 0x1E, 0x0C, 0x31, 17 | 0x7E, 0x59, 0xAA, 0x15, 0x42, 0xAC, 0xD2, 0xFC, 0x61, 0x03, 0xC0, 0x18, 18 | 0x1E, 0x0F, 0x04, 0x86, 0x63, 0xF1, 0x99, 0x86, 0xFC, 0xC6, 0xC6, 0xFC, 19 | 0xC6, 0xC6, 0xC6, 0xFC, 0x3E, 0x62, 0xC0, 0xC0, 0xC0, 0xC0, 0x62, 0x3E, 20 | 0xF8, 0xCC, 0xC6, 0xC6, 0xC6, 0xC6, 0xCC, 0xF8, 0xFD, 0x83, 0x07, 0xEC, 21 | 0x18, 0x30, 0x7E, 0xFD, 0x83, 0x07, 0xEC, 0x18, 0x30, 0x60, 0x3E, 0x62, 22 | 0xC0, 0xC0, 0xCE, 0xC6, 0x66, 0x3E, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 23 | 0xC6, 0xC6, 0xDB, 0x6D, 0xB6, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x37, 0x00, 24 | 0xC6, 0x66, 0x36, 0x1E, 0x0F, 0x06, 0xC3, 0x31, 0x8C, 0xC1, 0x83, 0x06, 25 | 0x0C, 0x18, 0x30, 0x7E, 0xE3, 0xB8, 0xEF, 0x7B, 0x56, 0xDD, 0xB2, 0x6C, 26 | 0x1B, 0x06, 0xE6, 0xE6, 0xE6, 0xD6, 0xD6, 0xCE, 0xCE, 0xCE, 0x3C, 0x33, 27 | 0x30, 0xD8, 0x6C, 0x36, 0x19, 0x98, 0x78, 0xFC, 0xC6, 0xC6, 0xC6, 0xFC, 28 | 0xC0, 0xC0, 0xC0, 0x3C, 0x33, 0x30, 0xD8, 0x6C, 0x36, 0x19, 0x98, 0x78, 29 | 0x0C, 0x03, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xF8, 0xCC, 0xCC, 0xC6, 0x79, 30 | 0x93, 0x07, 0x87, 0xC1, 0xA3, 0x7C, 0xFF, 0x0C, 0x06, 0x03, 0x01, 0x80, 31 | 0xC0, 0x60, 0x30, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC3, 32 | 0x33, 0x19, 0x8C, 0xC2, 0x41, 0xE0, 0xF0, 0x30, 0xC4, 0x6C, 0xE6, 0x6E, 33 | 0xC6, 0xAC, 0x7B, 0xC3, 0xB8, 0x31, 0x83, 0x18, 0xC3, 0x33, 0x19, 0x87, 34 | 0x83, 0xC3, 0x31, 0x99, 0x86, 0xC3, 0x33, 0x19, 0x87, 0x81, 0x80, 0xC0, 35 | 0x60, 0x30, 0xFE, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xFE, 0xF6, 0x31, 36 | 0x8C, 0x63, 0x18, 0xC7, 0x80, 0x86, 0x10, 0x86, 0x10, 0x86, 0x10, 0xF1, 37 | 0x8C, 0x63, 0x18, 0xC6, 0x37, 0x80, 0x38, 0x6C, 0xC6, 0xFC, 0xC6, 0x78, 38 | 0x19, 0xF6, 0x6C, 0xCF, 0x80, 0xC1, 0x83, 0x07, 0xCC, 0xD9, 0xB3, 0x66, 39 | 0xF8, 0x7B, 0x0C, 0x30, 0xC1, 0xE0, 0x0C, 0x18, 0x33, 0xEC, 0xD9, 0xB3, 40 | 0x66, 0x7C, 0x79, 0x9B, 0xF6, 0x0C, 0x0F, 0x80, 0x39, 0x86, 0x3E, 0x61, 41 | 0x86, 0x18, 0x60, 0x7D, 0x9B, 0x36, 0x6C, 0xCF, 0x83, 0x3C, 0xC1, 0x83, 42 | 0x07, 0xCC, 0xD9, 0xB3, 0x66, 0xCC, 0xD8, 0x6D, 0xB6, 0xC0, 0x66, 0x06, 43 | 0x66, 0x66, 0x66, 0xC0, 0xC0, 0xC0, 0xC0, 0xCC, 0xD8, 0xF0, 0xF0, 0xD8, 44 | 0xCC, 0xDB, 0x6D, 0xB6, 0xC0, 0xFF, 0x99, 0x9B, 0x33, 0x66, 0x6C, 0xCD, 45 | 0x99, 0x80, 0xF9, 0x9B, 0x36, 0x6C, 0xD9, 0x80, 0x79, 0x9B, 0x36, 0x6C, 46 | 0xCF, 0x00, 0xF9, 0x9B, 0x36, 0x6C, 0xDF, 0x30, 0x60, 0x7D, 0x9B, 0x36, 47 | 0x6C, 0xCF, 0x83, 0x06, 0xF6, 0x31, 0x8C, 0x60, 0x7B, 0x0F, 0x1E, 0x1B, 48 | 0xC0, 0x61, 0x8F, 0x98, 0x61, 0x86, 0x1E, 0xCD, 0x9B, 0x36, 0x6C, 0xCF, 49 | 0x80, 0xC6, 0xC6, 0x6C, 0x6C, 0x38, 0x38, 0xC9, 0xB7, 0x6D, 0x59, 0xDC, 50 | 0x63, 0x18, 0xC0, 0xC6, 0x6C, 0x38, 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 51 | 0x28, 0x38, 0x30, 0x30, 0x60, 0xF8, 0x63, 0x18, 0xC3, 0xE0, 0x3C, 0x60, 52 | 0xC1, 0x8E, 0x06, 0x0C, 0x18, 0x30, 0x38, 0xAA, 0xAA, 0xA8, 0xF0, 0x60, 53 | 0xC1, 0x81, 0xC6, 0x0C, 0x18, 0x31, 0xC0 54 | }; 55 | 56 | const GFXglyph DejaVu_Sans_Bold_11Glyphs[] PROGMEM = { 57 | { 0, 1, 1, 5, 0, 0 } // ' ' 58 | ,{ 1, 3, 8, 6, 2, -8 } // '!' 59 | ,{ 4, 4, 3, 7, 1, -8 } // '"' 60 | ,{ 6, 9, 8, 10, 1, -8 } // '#' 61 | ,{ 15, 8, 10, 9, 0, -8 } // '$' 62 | ,{ 25, 11, 8, 12, 1, -8 } // '%' 63 | ,{ 36, 9, 8, 11, 1, -8 } // '&' 64 | ,{ 45, 4, 4, 4, 0, -8 } // ''' 65 | ,{ 47, 4, 10, 6, 1, -9 } // '(' 66 | ,{ 52, 4, 10, 6, 1, -9 } // ')' 67 | ,{ 57, 5, 5, 7, 0, -8 } // '*' 68 | ,{ 61, 8, 7, 10, 1, -7 } // '+' 69 | ,{ 68, 4, 4, 5, 0, -2 } // ',' 70 | ,{ 70, 4, 2, 6, 1, -4 } // '-' 71 | ,{ 71, 3, 2, 5, 1, -2 } // '.' 72 | ,{ 72, 5, 9, 5, 0, -8 } // '/' 73 | ,{ 78, 7, 8, 9, 1, -8 } // '0' 74 | ,{ 85, 7, 8, 9, 1, -8 } // '1' 75 | ,{ 92, 7, 8, 9, 1, -8 } // '2' 76 | ,{ 99, 7, 8, 9, 1, -8 } // '3' 77 | ,{ 106, 8, 8, 9, 1, -8 } // '4' 78 | ,{ 114, 7, 8, 9, 1, -8 } // '5' 79 | ,{ 121, 7, 8, 9, 1, -8 } // '6' 80 | ,{ 128, 7, 8, 9, 1, -8 } // '7' 81 | ,{ 135, 7, 8, 9, 1, -8 } // '8' 82 | ,{ 142, 7, 8, 9, 1, -8 } // '9' 83 | ,{ 149, 3, 6, 5, 1, -6 } // ':' 84 | ,{ 152, 4, 8, 5, 0, -6 } // ';' 85 | ,{ 156, 8, 6, 10, 1, -7 } // '<' 86 | ,{ 162, 8, 3, 10, 1, -5 } // '=' 87 | ,{ 165, 8, 6, 10, 1, -7 } // '>' 88 | ,{ 171, 6, 8, 7, 1, -8 } // '?' 89 | ,{ 177, 11, 10, 12, 1, -8 } // '@' 90 | ,{ 191, 9, 8, 9, 0, -8 } // 'A' 91 | ,{ 200, 8, 8, 10, 1, -8 } // 'B' 92 | ,{ 208, 8, 8, 10, 1, -8 } // 'C' 93 | ,{ 216, 8, 8, 10, 1, -8 } // 'D' 94 | ,{ 224, 7, 8, 9, 1, -8 } // 'E' 95 | ,{ 231, 7, 8, 9, 1, -8 } // 'F' 96 | ,{ 238, 8, 8, 10, 1, -8 } // 'G' 97 | ,{ 246, 8, 8, 10, 1, -8 } // 'H' 98 | ,{ 254, 3, 8, 5, 1, -8 } // 'I' 99 | ,{ 257, 5, 10, 5, -1, -8 } // 'J' 100 | ,{ 264, 9, 8, 10, 1, -8 } // 'K' 101 | ,{ 273, 7, 8, 8, 1, -8 } // 'L' 102 | ,{ 280, 10, 8, 12, 1, -8 } // 'M' 103 | ,{ 290, 8, 8, 10, 1, -8 } // 'N' 104 | ,{ 298, 9, 8, 11, 1, -8 } // 'O' 105 | ,{ 307, 8, 8, 9, 1, -8 } // 'P' 106 | ,{ 315, 9, 10, 11, 1, -8 } // 'Q' 107 | ,{ 327, 8, 8, 9, 1, -8 } // 'R' 108 | ,{ 335, 7, 8, 9, 1, -8 } // 'S' 109 | ,{ 342, 9, 8, 9, 0, -8 } // 'T' 110 | ,{ 351, 8, 8, 10, 1, -8 } // 'U' 111 | ,{ 359, 9, 8, 9, 0, -8 } // 'V' 112 | ,{ 368, 12, 8, 14, 1, -8 } // 'W' 113 | ,{ 380, 9, 8, 9, 0, -8 } // 'X' 114 | ,{ 389, 9, 8, 9, 0, -8 } // 'Y' 115 | ,{ 398, 8, 8, 9, 1, -8 } // 'Z' 116 | ,{ 406, 5, 10, 6, 1, -9 } // '[' 117 | ,{ 413, 5, 9, 5, 0, -8 } // '\' 118 | ,{ 419, 5, 10, 6, 0, -9 } // ']' 119 | ,{ 426, 8, 3, 10, 1, -8 } // '^' 120 | ,{ 429, 7, 1, 7, 0, 2 } // '_' 121 | ,{ 430, 4, 2, 7, 1, -9 } // '`' 122 | ,{ 431, 7, 6, 9, 1, -6 } // 'a' 123 | ,{ 437, 7, 9, 9, 1, -9 } // 'b' 124 | ,{ 445, 6, 6, 8, 1, -6 } // 'c' 125 | ,{ 450, 7, 9, 9, 1, -9 } // 'd' 126 | ,{ 458, 7, 6, 9, 1, -6 } // 'e' 127 | ,{ 464, 6, 9, 6, 0, -9 } // 'f' 128 | ,{ 471, 7, 8, 9, 1, -6 } // 'g' 129 | ,{ 478, 7, 9, 9, 1, -9 } // 'h' 130 | ,{ 486, 3, 9, 5, 1, -9 } // 'i' 131 | ,{ 490, 4, 11, 5, 0, -9 } // 'j' 132 | ,{ 496, 8, 9, 8, 1, -9 } // 'k' 133 | ,{ 505, 3, 9, 5, 1, -9 } // 'l' 134 | ,{ 509, 11, 6, 12, 1, -6 } // 'm' 135 | ,{ 518, 7, 6, 9, 1, -6 } // 'n' 136 | ,{ 524, 7, 6, 9, 1, -6 } // 'o' 137 | ,{ 530, 7, 8, 9, 1, -6 } // 'p' 138 | ,{ 537, 7, 8, 9, 1, -6 } // 'q' 139 | ,{ 544, 5, 6, 6, 1, -6 } // 'r' 140 | ,{ 548, 6, 6, 8, 1, -6 } // 's' 141 | ,{ 553, 6, 8, 6, 0, -8 } // 't' 142 | ,{ 559, 7, 6, 9, 1, -6 } // 'u' 143 | ,{ 565, 8, 6, 8, 0, -6 } // 'v' 144 | ,{ 571, 10, 6, 12, 1, -6 } // 'w' 145 | ,{ 579, 8, 6, 8, 0, -6 } // 'x' 146 | ,{ 585, 8, 8, 8, 0, -6 } // 'y' 147 | ,{ 593, 6, 6, 8, 1, -6 } // 'z' 148 | ,{ 598, 7, 10, 9, 1, -9 } // '{' 149 | ,{ 607, 2, 11, 5, 1, -8 } // '|' 150 | ,{ 610, 7, 10, 9, 1, -9 } // '}' 151 | }; 152 | 153 | const GFXfont DejaVu_Sans_Bold_11 PROGMEM = { 154 | (uint8_t *)DejaVu_Sans_Bold_11Bitmaps, (GFXglyph *)DejaVu_Sans_Bold_11Glyphs, 0x20, 0x7E, 14 155 | }; 156 | 157 | const uint8_t DSEG7_Classic_Bold_21Bitmaps[] PROGMEM = { 158 | 0x00, 0x00, 0xFD, 0x0A, 0x14, 0x28, 0x50, 0xA1, 0x42, 0x85, 0x0A, 0x14, 159 | 0x28, 0x5F, 0x80, 0xFD, 0x0A, 0x14, 0x28, 0x50, 0xA1, 0x42, 0x85, 0x0A, 160 | 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 0x14, 0x28, 0x50, 0xA1, 0x42, 0x85, 161 | 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 0x14, 0x28, 0x50, 0xA1, 0x42, 162 | 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 0x14, 0x28, 0x50, 0xA1, 163 | 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0x79, 0x9A, 0x14, 0x2C, 0xCF, 164 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0A, 0x14, 0x28, 165 | 0x50, 0xA1, 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 0x14, 166 | 0x28, 0x50, 0xA1, 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 167 | 0x14, 0x28, 0x50, 0xA1, 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 168 | 0x0A, 0x14, 0x28, 0x50, 0xA1, 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 169 | 0xFD, 0x0A, 0x14, 0x28, 0x50, 0xA1, 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 170 | 0x80, 0x7F, 0x3F, 0xE7, 0xF0, 0xDB, 0x00, 0x06, 0x0C, 0x18, 0x60, 0xC1, 171 | 0x86, 0x0C, 0x18, 0x60, 0xC1, 0x86, 0x0C, 0x18, 0x60, 0xC1, 0x80, 0x00, 172 | 0x00, 0x7F, 0xF2, 0xFF, 0xAD, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 173 | 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x00, 0x60, 0x00, 0x30, 0x06, 0xE0, 0x3B, 174 | 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xED, 0xFD, 0xAF, 0xFA, 175 | 0x7F, 0xF0, 0x26, 0xEE, 0xEE, 0xEE, 0x60, 0x6E, 0xEE, 0xEE, 0xE6, 0x20, 176 | 0x7F, 0xF0, 0xFF, 0xA1, 0xFD, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 177 | 0x80, 0x0E, 0x00, 0x38, 0x7F, 0x63, 0xFE, 0x37, 0xF0, 0xE0, 0x03, 0x80, 178 | 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0D, 0xFC, 0x2F, 0xF8, 0x7F, 179 | 0xF0, 0xFF, 0xE3, 0xFE, 0x8F, 0xEC, 0x00, 0xE0, 0x07, 0x00, 0x38, 0x01, 180 | 0xC0, 0x0E, 0x00, 0x71, 0xFD, 0x9F, 0xF0, 0x7F, 0x60, 0x07, 0x00, 0x38, 181 | 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x8F, 0xEC, 0xFF, 0xAF, 0xFE, 0x00, 182 | 0x80, 0x0B, 0x00, 0x6E, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 183 | 0xB8, 0x0E, 0xDF, 0xD8, 0xFF, 0x81, 0xFD, 0x80, 0x0E, 0x00, 0x38, 0x00, 184 | 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0x60, 0x00, 0x80, 0x7F, 0xF2, 185 | 0xFF, 0x8D, 0xFC, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 186 | 0xE0, 0x03, 0x7F, 0x03, 0xFE, 0x07, 0xF6, 0x00, 0x38, 0x00, 0xE0, 0x03, 187 | 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE1, 0xFD, 0x8F, 0xFA, 0x7F, 0xF0, 0x7F, 188 | 0xF2, 0xFF, 0x8D, 0xFC, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 189 | 0x00, 0xE0, 0x03, 0x7F, 0x03, 0xFE, 0x37, 0xF6, 0xE0, 0x3B, 0x80, 0xEE, 190 | 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xED, 0xFD, 0xAF, 0xFA, 0x7F, 0xF0, 191 | 0x7F, 0xF2, 0xFF, 0xAD, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 192 | 0xB8, 0x0E, 0xE0, 0x3B, 0x00, 0x60, 0x00, 0x00, 0x06, 0x00, 0x38, 0x00, 193 | 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x01, 0x80, 0x02, 0x7F, 194 | 0xF2, 0xFF, 0xAD, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 195 | 0x0E, 0xE0, 0x3B, 0x7F, 0x63, 0xFE, 0x37, 0xF6, 0xE0, 0x3B, 0x80, 0xEE, 196 | 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xED, 0xFD, 0xAF, 0xFA, 0x7F, 0xF0, 197 | 0x7F, 0xF2, 0xFF, 0xAD, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 198 | 0xB8, 0x0E, 0xE0, 0x3B, 0x7F, 0x63, 0xFE, 0x07, 0xF6, 0x00, 0x38, 0x00, 199 | 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE1, 0xFD, 0x8F, 0xFA, 0x7F, 200 | 0xF0, 0xDB, 0x00, 0x00, 0x1B, 0x00, 0xFD, 0x0A, 0x14, 0x28, 0x50, 0xA1, 201 | 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 0x14, 0x28, 0x50, 202 | 0xA1, 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 0x14, 0x28, 203 | 0x50, 0xA1, 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 0x14, 204 | 0x28, 0x50, 0xA1, 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 205 | 0x14, 0x28, 0x50, 0xA1, 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 206 | 0x0A, 0x14, 0x28, 0x50, 0xA1, 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 207 | 0x7F, 0xF2, 0xFF, 0xAD, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 208 | 0xB8, 0x0E, 0xE0, 0x3B, 0x7F, 0x63, 0xFE, 0x37, 0xF6, 0xE0, 0x3B, 0x80, 209 | 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEC, 0x01, 0xA0, 0x02, 0x80, 210 | 0x03, 0x00, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 211 | 0x00, 0xDF, 0xC0, 0xFF, 0x8D, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 212 | 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x7F, 0x6B, 0xFE, 0x9F, 0xFC, 0x1F, 0xC1, 213 | 0xFF, 0x37, 0xF1, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 214 | 0x06, 0xFE, 0x2F, 0xF8, 0xFF, 0xE0, 0x00, 0x08, 0x00, 0x60, 0x03, 0x80, 215 | 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x1F, 0xD8, 0xFF, 0x8D, 216 | 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 217 | 0x7F, 0x6B, 0xFE, 0x9F, 0xFC, 0x7F, 0xF5, 0xFF, 0x37, 0xF1, 0xC0, 0x0E, 218 | 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x06, 0xFE, 0x0F, 0xF9, 0xBF, 219 | 0x8E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x37, 0xF1, 220 | 0x7F, 0xC7, 0xFF, 0x00, 0x7F, 0xF5, 0xFF, 0x37, 0xF1, 0xC0, 0x0E, 0x00, 221 | 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x06, 0xFE, 0x0F, 0xF9, 0xBF, 0x8E, 222 | 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x30, 0x01, 0x00, 223 | 0x00, 0x7F, 0xF2, 0xFF, 0x8D, 0xFC, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 224 | 0x00, 0x38, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x30, 0x06, 0xE0, 0x3B, 225 | 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xED, 0xFD, 0xAF, 0xFA, 226 | 0x7F, 0xF0, 0x80, 0x03, 0x00, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 227 | 0x0E, 0x00, 0x38, 0x00, 0xDF, 0xC0, 0xFF, 0x8D, 0xFD, 0xB8, 0x0E, 0xE0, 228 | 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x00, 0x68, 0x00, 0x80, 229 | 0x6E, 0xEE, 0xEE, 0xE6, 0x20, 0x00, 0x08, 0x00, 0x60, 0x03, 0x80, 0x0E, 230 | 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x18, 0x00, 0x0C, 0x01, 231 | 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x7F, 232 | 0x6B, 0xFE, 0x9F, 0xFC, 0x7F, 0xF2, 0xFF, 0x8D, 0xFC, 0x38, 0x00, 0xE0, 233 | 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x7F, 0x03, 0xFE, 0x37, 234 | 0xF6, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEC, 235 | 0x01, 0xA0, 0x02, 0x80, 0x06, 0x00, 0x38, 0x01, 0xC0, 0x0E, 0x00, 0x70, 236 | 0x03, 0x80, 0x1C, 0x00, 0xC0, 0x00, 0x00, 0x30, 0x01, 0xC0, 0x0E, 0x00, 237 | 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x06, 0xFE, 0x2F, 0xF8, 0xFF, 0xE0, 238 | 0x7F, 0xF2, 0xFF, 0xAD, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 239 | 0xB8, 0x0E, 0xE0, 0x3B, 0x00, 0x60, 0x00, 0x30, 0x06, 0xE0, 0x3B, 0x80, 240 | 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEC, 0x01, 0xA0, 0x02, 0x1F, 241 | 0xC0, 0xFF, 0x8D, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 242 | 0x0E, 0xE0, 0x3B, 0x00, 0x68, 0x00, 0x80, 0x1F, 0xC0, 0xFF, 0x8D, 0xFD, 243 | 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x7F, 244 | 0x6B, 0xFE, 0x9F, 0xFC, 0x7F, 0xF2, 0xFF, 0xAD, 0xFD, 0xB8, 0x0E, 0xE0, 245 | 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x7F, 0x63, 0xFE, 0x37, 246 | 0xF0, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0C, 247 | 0x00, 0x20, 0x00, 0x7F, 0xF2, 0xFF, 0xAD, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 248 | 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x7F, 0x63, 0xFE, 0x07, 0xF6, 249 | 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x01, 250 | 0x80, 0x02, 0x1F, 0xC3, 0xFE, 0xDF, 0xCE, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 251 | 0x0E, 0x00, 0xE0, 0x0C, 0x00, 0x80, 0x00, 0x80, 0x03, 0x00, 0x0E, 0x00, 252 | 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xDF, 0xC0, 0xFF, 253 | 0x81, 0xFD, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 254 | 0x38, 0x7F, 0x63, 0xFE, 0x9F, 0xFC, 0x80, 0x06, 0x00, 0x38, 0x01, 0xC0, 255 | 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xDF, 0xC1, 0xFF, 0x37, 0xF1, 256 | 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x06, 0xFE, 0x2F, 257 | 0xF8, 0xFF, 0xE0, 0xC0, 0x1B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 258 | 0x80, 0xEE, 0x03, 0xB7, 0xF6, 0xBF, 0xE9, 0xFF, 0xC0, 0x80, 0x0B, 0x00, 259 | 0x6E, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xC0, 260 | 0x18, 0x00, 0x0C, 0x01, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 261 | 0x0E, 0xE0, 0x3B, 0x7F, 0x6B, 0xFE, 0x9F, 0xFC, 0x80, 0x0B, 0x00, 0x6E, 262 | 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xDF, 0xD8, 263 | 0xFF, 0x8D, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 264 | 0xE0, 0x3B, 0x7F, 0x6B, 0xFE, 0x9F, 0xFC, 0x80, 0x0B, 0x00, 0x6E, 0x03, 265 | 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xDF, 0xD8, 0xFF, 266 | 0x8D, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 267 | 0x3B, 0x00, 0x68, 0x00, 0x80, 0x80, 0x0B, 0x00, 0x6E, 0x03, 0xB8, 0x0E, 268 | 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xDF, 0xD8, 0xFF, 0x81, 0xFD, 269 | 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x7F, 270 | 0x63, 0xFE, 0x9F, 0xFC, 0x7F, 0xF0, 0xFF, 0xA1, 0xFD, 0x80, 0x0E, 0x00, 271 | 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 272 | 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0D, 273 | 0xFC, 0x2F, 0xF8, 0x7F, 0xF0, 0xFD, 0x0A, 0x14, 0x28, 0x50, 0xA1, 0x42, 274 | 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 0x14, 0x28, 0x50, 0xA1, 275 | 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 0x14, 0x28, 0x50, 276 | 0xA1, 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 0x14, 0x28, 277 | 0x50, 0xA1, 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 0x14, 278 | 0x28, 0x50, 0xA1, 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 279 | 0x14, 0x28, 0x50, 0xA1, 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0x7F, 280 | 0xF2, 0xFF, 0xAD, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 281 | 0x0E, 0xE0, 0x3B, 0x7F, 0x63, 0xFE, 0x37, 0xF6, 0xE0, 0x3B, 0x80, 0xEE, 282 | 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEC, 0x01, 0xA0, 0x02, 0x80, 0x03, 283 | 0x00, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 284 | 0xDF, 0xC0, 0xFF, 0x8D, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 285 | 0xB8, 0x0E, 0xE0, 0x3B, 0x7F, 0x6B, 0xFE, 0x9F, 0xFC, 0x1F, 0xC1, 0xFF, 286 | 0x37, 0xF1, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x06, 287 | 0xFE, 0x2F, 0xF8, 0xFF, 0xE0, 0x00, 0x08, 0x00, 0x60, 0x03, 0x80, 0x0E, 288 | 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x1F, 0xD8, 0xFF, 0x8D, 0xFD, 289 | 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x7F, 290 | 0x6B, 0xFE, 0x9F, 0xFC, 0x7F, 0xF5, 0xFF, 0x37, 0xF1, 0xC0, 0x0E, 0x00, 291 | 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x06, 0xFE, 0x0F, 0xF9, 0xBF, 0x8E, 292 | 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x37, 0xF1, 0x7F, 293 | 0xC7, 0xFF, 0x00, 0x7F, 0xF5, 0xFF, 0x37, 0xF1, 0xC0, 0x0E, 0x00, 0x70, 294 | 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x06, 0xFE, 0x0F, 0xF9, 0xBF, 0x8E, 0x00, 295 | 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x30, 0x01, 0x00, 0x00, 296 | 0x7F, 0xF2, 0xFF, 0x8D, 0xFC, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 297 | 0x38, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x30, 0x06, 0xE0, 0x3B, 0x80, 298 | 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xED, 0xFD, 0xAF, 0xFA, 0x7F, 299 | 0xF0, 0x80, 0x03, 0x00, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 300 | 0x00, 0x38, 0x00, 0xDF, 0xC0, 0xFF, 0x8D, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 301 | 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x00, 0x68, 0x00, 0x80, 0x6E, 302 | 0xEE, 0xEE, 0xE6, 0x20, 0x00, 0x08, 0x00, 0x60, 0x03, 0x80, 0x0E, 0x00, 303 | 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x18, 0x00, 0x0C, 0x01, 0xB8, 304 | 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x7F, 0x6B, 305 | 0xFE, 0x9F, 0xFC, 0x7F, 0xF2, 0xFF, 0x8D, 0xFC, 0x38, 0x00, 0xE0, 0x03, 306 | 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x7F, 0x03, 0xFE, 0x37, 0xF6, 307 | 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEC, 0x01, 308 | 0xA0, 0x02, 0x80, 0x06, 0x00, 0x38, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x03, 309 | 0x80, 0x1C, 0x00, 0xC0, 0x00, 0x00, 0x30, 0x01, 0xC0, 0x0E, 0x00, 0x70, 310 | 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x06, 0xFE, 0x2F, 0xF8, 0xFF, 0xE0, 0x7F, 311 | 0xF2, 0xFF, 0xAD, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 312 | 0x0E, 0xE0, 0x3B, 0x00, 0x60, 0x00, 0x30, 0x06, 0xE0, 0x3B, 0x80, 0xEE, 313 | 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEC, 0x01, 0xA0, 0x02, 0x1F, 0xC0, 314 | 0xFF, 0x8D, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 315 | 0xE0, 0x3B, 0x00, 0x68, 0x00, 0x80, 0x1F, 0xC0, 0xFF, 0x8D, 0xFD, 0xB8, 316 | 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x7F, 0x6B, 317 | 0xFE, 0x9F, 0xFC, 0x7F, 0xF2, 0xFF, 0xAD, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 318 | 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x7F, 0x63, 0xFE, 0x37, 0xF0, 319 | 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0C, 0x00, 320 | 0x20, 0x00, 0x7F, 0xF2, 0xFF, 0xAD, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 321 | 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x7F, 0x63, 0xFE, 0x07, 0xF6, 0x00, 322 | 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x01, 0x80, 323 | 0x02, 0x1F, 0xC3, 0xFE, 0xDF, 0xCE, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 324 | 0x00, 0xE0, 0x0C, 0x00, 0x80, 0x00, 0x80, 0x03, 0x00, 0x0E, 0x00, 0x38, 325 | 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xDF, 0xC0, 0xFF, 0x81, 326 | 0xFD, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 327 | 0x7F, 0x63, 0xFE, 0x9F, 0xFC, 0x80, 0x06, 0x00, 0x38, 0x01, 0xC0, 0x0E, 328 | 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xDF, 0xC1, 0xFF, 0x37, 0xF1, 0xC0, 329 | 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x06, 0xFE, 0x2F, 0xF8, 330 | 0xFF, 0xE0, 0xC0, 0x1B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 331 | 0xEE, 0x03, 0xB7, 0xF6, 0xBF, 0xE9, 0xFF, 0xC0, 0x80, 0x0B, 0x00, 0x6E, 332 | 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xC0, 0x18, 333 | 0x00, 0x0C, 0x01, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 334 | 0xE0, 0x3B, 0x7F, 0x6B, 0xFE, 0x9F, 0xFC, 0x80, 0x0B, 0x00, 0x6E, 0x03, 335 | 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xDF, 0xD8, 0xFF, 336 | 0x8D, 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 337 | 0x3B, 0x7F, 0x6B, 0xFE, 0x9F, 0xFC, 0x80, 0x0B, 0x00, 0x6E, 0x03, 0xB8, 338 | 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xDF, 0xD8, 0xFF, 0x8D, 339 | 0xFD, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xE0, 0x3B, 340 | 0x00, 0x68, 0x00, 0x80, 0x80, 0x0B, 0x00, 0x6E, 0x03, 0xB8, 0x0E, 0xE0, 341 | 0x3B, 0x80, 0xEE, 0x03, 0xB8, 0x0E, 0xDF, 0xD8, 0xFF, 0x81, 0xFD, 0x80, 342 | 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x7F, 0x63, 343 | 0xFE, 0x9F, 0xFC, 0x7F, 0xF0, 0xFF, 0xA1, 0xFD, 0x80, 0x0E, 0x00, 0x38, 344 | 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 345 | 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0D, 0xFC, 346 | 0x2F, 0xF8, 0x7F, 0xF0, 0xFD, 0x0A, 0x14, 0x28, 0x50, 0xA1, 0x42, 0x85, 347 | 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 0x14, 0x28, 0x50, 0xA1, 0x42, 348 | 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80, 0xFD, 0x0A, 0x14, 0x28, 0x50, 0xA1, 349 | 0x42, 0x85, 0x0A, 0x14, 0x28, 0x5F, 0x80 350 | }; 351 | 352 | const GFXglyph DSEG7_Classic_Bold_21Glyphs[] PROGMEM = { 353 | { 0, 1, 1, 5, 0, 0 } // ' ' 354 | , { 1, 1, 1, 18, 0, 0 } // '!' 355 | , { 2, 7, 14, 9, 1, -14 } // '"' 356 | , { 15, 7, 14, 9, 1, -14 } // '#' 357 | , { 28, 7, 14, 9, 1, -14 } // '$' 358 | , { 41, 7, 14, 9, 1, -14 } // '%' 359 | , { 54, 7, 14, 9, 1, -14 } // '&' 360 | , { 67, 7, 14, 9, 1, -20 } // ''' 361 | , { 80, 7, 14, 9, 1, -14 } // '(' 362 | , { 93, 7, 14, 9, 1, -14 } // ')' 363 | , { 106, 7, 14, 9, 1, -14 } // '*' 364 | , { 119, 7, 14, 9, 1, -14 } // '+' 365 | , { 132, 7, 14, 9, 1, -14 } // ',' 366 | , { 145, 10, 3, 18, 4, -12 } // '-' 367 | , { 149, 3, 3, 1, -1, -3 } // '.' 368 | , { 151, 7, 19, 9, 1, -19 } // '/' 369 | , { 169, 14, 21, 18, 2, -21 } // '0' 370 | , { 206, 4, 19, 18, 12, -20 } // '1' 371 | , { 216, 14, 21, 18, 2, -21 } // '2' 372 | , { 253, 13, 21, 18, 3, -21 } // '3' 373 | , { 288, 14, 19, 18, 2, -20 } // '4' 374 | , { 322, 14, 21, 18, 2, -21 } // '5' 375 | , { 359, 14, 21, 18, 2, -21 } // '6' 376 | , { 396, 14, 20, 18, 2, -21 } // '7' 377 | , { 431, 14, 21, 18, 2, -21 } // '8' 378 | , { 468, 14, 21, 18, 2, -21 } // '9' 379 | , { 505, 3, 11, 5, 1, -16 } // ':' 380 | , { 510, 7, 14, 9, 1, -14 } // ';' 381 | , { 523, 7, 14, 9, 1, -14 } // '<' 382 | , { 536, 7, 14, 9, 1, -14 } // '=' 383 | , { 549, 7, 14, 9, 1, -14 } // '>' 384 | , { 562, 7, 14, 9, 1, -14 } // '?' 385 | , { 575, 7, 14, 9, 1, -14 } // '@' 386 | , { 588, 14, 20, 18, 2, -21 } // 'A' 387 | , { 623, 14, 20, 18, 2, -20 } // 'B' 388 | , { 658, 13, 12, 18, 2, -12 } // 'C' 389 | , { 678, 14, 20, 18, 2, -20 } // 'D' 390 | , { 713, 13, 21, 18, 2, -21 } // 'E' 391 | , { 748, 13, 20, 18, 2, -21 } // 'F' 392 | , { 781, 14, 21, 18, 2, -21 } // 'G' 393 | , { 818, 14, 19, 18, 2, -20 } // 'H' 394 | , { 852, 4, 9, 18, 12, -10 } // 'I' 395 | , { 857, 14, 20, 18, 2, -20 } // 'J' 396 | , { 892, 14, 20, 18, 2, -21 } // 'K' 397 | , { 927, 13, 20, 18, 2, -20 } // 'L' 398 | , { 960, 14, 20, 18, 2, -21 } // 'M' 399 | , { 995, 14, 11, 18, 2, -12 } // 'N' 400 | , { 1015, 14, 12, 18, 2, -12 } // 'O' 401 | , { 1036, 14, 20, 18, 2, -21 } // 'P' 402 | , { 1071, 14, 20, 18, 2, -21 } // 'Q' 403 | , { 1106, 12, 11, 18, 2, -12 } // 'R' 404 | , { 1123, 14, 20, 18, 2, -20 } // 'S' 405 | , { 1158, 13, 20, 18, 2, -20 } // 'T' 406 | , { 1191, 14, 10, 18, 2, -10 } // 'U' 407 | , { 1209, 14, 20, 18, 2, -20 } // 'V' 408 | , { 1244, 14, 20, 18, 2, -20 } // 'W' 409 | , { 1279, 14, 19, 18, 2, -20 } // 'X' 410 | , { 1313, 14, 20, 18, 2, -20 } // 'Y' 411 | , { 1348, 14, 21, 18, 2, -21 } // 'Z' 412 | , { 1385, 7, 14, 9, 1, -14 } // '[' 413 | , { 1398, 7, 14, 9, 1, -14 } // '\' 414 | , { 1411, 7, 14, 9, 1, -14 } // ']' 415 | , { 1424, 7, 14, 9, 1, -14 } // '^' 416 | , { 1437, 7, 14, 9, 1, -14 } // '_' 417 | , { 1450, 7, 14, 9, 1, -14 } // '`' 418 | , { 1463, 14, 20, 18, 2, -21 } // 'a' 419 | , { 1498, 14, 20, 18, 2, -20 } // 'b' 420 | , { 1533, 13, 12, 18, 2, -12 } // 'c' 421 | , { 1553, 14, 20, 18, 2, -20 } // 'd' 422 | , { 1588, 13, 21, 18, 2, -21 } // 'e' 423 | , { 1623, 13, 20, 18, 2, -21 } // 'f' 424 | , { 1656, 14, 21, 18, 2, -21 } // 'g' 425 | , { 1693, 14, 19, 18, 2, -20 } // 'h' 426 | , { 1727, 4, 9, 18, 12, -10 } // 'i' 427 | , { 1732, 14, 20, 18, 2, -20 } // 'j' 428 | , { 1767, 14, 20, 18, 2, -21 } // 'k' 429 | , { 1802, 13, 20, 18, 2, -20 } // 'l' 430 | , { 1835, 14, 20, 18, 2, -21 } // 'm' 431 | , { 1870, 14, 11, 18, 2, -12 } // 'n' 432 | , { 1890, 14, 12, 18, 2, -12 } // 'o' 433 | , { 1911, 14, 20, 18, 2, -21 } // 'p' 434 | , { 1946, 14, 20, 18, 2, -21 } // 'q' 435 | , { 1981, 12, 11, 18, 2, -12 } // 'r' 436 | , { 1998, 14, 20, 18, 2, -20 } // 's' 437 | , { 2033, 13, 20, 18, 2, -20 } // 't' 438 | , { 2066, 14, 10, 18, 2, -10 } // 'u' 439 | , { 2084, 14, 20, 18, 2, -20 } // 'v' 440 | , { 2119, 14, 20, 18, 2, -20 } // 'w' 441 | , { 2154, 14, 19, 18, 2, -20 } // 'x' 442 | , { 2188, 14, 20, 18, 2, -20 } // 'y' 443 | , { 2223, 14, 21, 18, 2, -21 } // 'z' 444 | , { 2260, 7, 14, 9, 1, -14 } // '{' 445 | , { 2273, 7, 14, 9, 1, -14 } // '|' 446 | , { 2286, 7, 14, 9, 1, -14 } // '}' 447 | }; 448 | 449 | const GFXfont DSEG7_Classic_Bold_21 PROGMEM = { 450 | (uint8_t *)DSEG7_Classic_Bold_21Bitmaps, (GFXglyph *)DSEG7_Classic_Bold_21Glyphs, 0x20, 0x7E, 23 451 | }; 452 | 453 | const uint8_t DSEG7_Classic_Bold_11Bitmaps[] PROGMEM = { 454 | 0x00, 0x00, 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 455 | 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 0xF4, 0xA5, 456 | 0x29, 0x4A, 0x5E, 0xF4, 0xA5, 0xE0, 0x00, 0x00, 0xF4, 0xA5, 0x29, 0x4A, 457 | 0x5E, 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 0xF4, 458 | 0xA5, 0x29, 0x4A, 0x5E, 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 0xF8, 0xC0, 0x10, 459 | 0x88, 0x44, 0x22, 0x10, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x00, 0x82, 0x82, 460 | 0x82, 0x82, 0x7C, 0x2A, 0x8A, 0xA0, 0x7C, 0x02, 0x02, 0x02, 0x02, 0x7C, 461 | 0x80, 0x80, 0x80, 0x80, 0x7C, 0xF8, 0x08, 0x10, 0x20, 0x5F, 0x01, 0x02, 462 | 0x04, 0x0B, 0xE0, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x02, 0x02, 0x02, 463 | 0x02, 0x7C, 0x80, 0x80, 0x80, 0x80, 0x7C, 0x02, 0x02, 0x02, 0x02, 0x7C, 464 | 0x7C, 0x80, 0x80, 0x80, 0x80, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x7C, 465 | 0x82, 0x82, 0x82, 0x82, 0x00, 0x02, 0x02, 0x02, 0x02, 0x7C, 0x82, 0x82, 466 | 0x82, 0x82, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x7C, 0x82, 0x82, 0x82, 467 | 0x82, 0x7C, 0x02, 0x02, 0x02, 0x02, 0x7C, 0xC0, 0x04, 0x00, 0xF4, 0xA5, 468 | 0x29, 0x4A, 0x5E, 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 0xF4, 0xA5, 0x29, 0x4A, 469 | 0x5E, 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 0xF4, 470 | 0xA5, 0x29, 0x4A, 0x5E, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x82, 0x82, 471 | 0x82, 0x82, 0x00, 0x80, 0x80, 0x80, 0x80, 0x7C, 0x82, 0x82, 0x82, 0x82, 472 | 0x7C, 0x7D, 0x02, 0x04, 0x08, 0x0F, 0x80, 0x00, 0x02, 0x02, 0x02, 0x02, 473 | 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x7D, 0x02, 0x04, 0x08, 0x0F, 0xA0, 474 | 0x40, 0x81, 0x01, 0xF0, 0x7D, 0x02, 0x04, 0x08, 0x0F, 0xA0, 0x40, 0x81, 475 | 0x00, 0x7C, 0x80, 0x80, 0x80, 0x80, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7C, 476 | 0x00, 0x80, 0x80, 0x80, 0x80, 0x7C, 0x82, 0x82, 0x82, 0x82, 0xAA, 0x00, 477 | 0x02, 0x02, 0x02, 0x02, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x7C, 0x80, 478 | 0x80, 0x80, 0x80, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x01, 0x02, 0x04, 0x08, 479 | 0x00, 0x20, 0x40, 0x81, 0x01, 0xF0, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x00, 480 | 0x82, 0x82, 0x82, 0x82, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x82, 0x82, 481 | 0x82, 0x82, 0x7C, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x80, 0x80, 0x80, 482 | 0x80, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x02, 0x02, 0x02, 0x02, 0x7D, 483 | 0x02, 0x04, 0x08, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x7C, 0x02, 0x02, 484 | 0x02, 0x02, 0x7C, 0x01, 0x02, 0x04, 0x08, 0x0F, 0xA0, 0x40, 0x81, 0x01, 485 | 0xF0, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x82, 0x82, 0x82, 0x82, 0x00, 486 | 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x82, 487 | 0x82, 0x82, 0x82, 0x7C, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x82, 0x82, 488 | 0x82, 0x82, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x02, 0x02, 0x02, 0x02, 489 | 0x7C, 0x7C, 0x02, 0x02, 0x02, 0x02, 0x00, 0x80, 0x80, 0x80, 0x80, 0x7C, 490 | 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 0xF4, 0xA5, 491 | 0x29, 0x4A, 0x5E, 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 0xF4, 0xA5, 0x29, 0x4A, 492 | 0x5E, 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 493 | 0x82, 0x82, 0x82, 0x82, 0x00, 0x80, 0x80, 0x80, 0x80, 0x7C, 0x82, 0x82, 494 | 0x82, 0x82, 0x7C, 0x7D, 0x02, 0x04, 0x08, 0x0F, 0x80, 0x00, 0x02, 0x02, 495 | 0x02, 0x02, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x7D, 0x02, 0x04, 0x08, 496 | 0x0F, 0xA0, 0x40, 0x81, 0x01, 0xF0, 0x7D, 0x02, 0x04, 0x08, 0x0F, 0xA0, 497 | 0x40, 0x81, 0x00, 0x7C, 0x80, 0x80, 0x80, 0x80, 0x00, 0x82, 0x82, 0x82, 498 | 0x82, 0x7C, 0x00, 0x80, 0x80, 0x80, 0x80, 0x7C, 0x82, 0x82, 0x82, 0x82, 499 | 0xAA, 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7C, 500 | 0x7C, 0x80, 0x80, 0x80, 0x80, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x01, 0x02, 501 | 0x04, 0x08, 0x00, 0x20, 0x40, 0x81, 0x01, 0xF0, 0x7C, 0x82, 0x82, 0x82, 502 | 0x82, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 503 | 0x82, 0x82, 0x82, 0x82, 0x7C, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x80, 504 | 0x80, 0x80, 0x80, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x02, 0x02, 0x02, 505 | 0x02, 0x7D, 0x02, 0x04, 0x08, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x7C, 506 | 0x02, 0x02, 0x02, 0x02, 0x7C, 0x01, 0x02, 0x04, 0x08, 0x0F, 0xA0, 0x40, 507 | 0x81, 0x01, 0xF0, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x82, 0x82, 0x82, 508 | 0x82, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x82, 0x82, 0x82, 0x82, 509 | 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7C, 510 | 0x82, 0x82, 0x82, 0x82, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x02, 0x02, 511 | 0x02, 0x02, 0x7C, 0x7C, 0x02, 0x02, 0x02, 0x02, 0x00, 0x80, 0x80, 0x80, 512 | 0x80, 0x7C, 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 0xF4, 0xA5, 0x29, 0x4A, 0x5E, 513 | 0xF4, 0xA5, 0x29, 0x4A, 0x5E 514 | }; 515 | 516 | const GFXglyph DSEG7_Classic_Bold_11Glyphs[] PROGMEM = { 517 | { 0, 1, 1, 3, 0, 0 } // ' ' 518 | , { 1, 1, 1, 10, 0, 0 } // '!' 519 | , { 2, 5, 8, 5, 0, -8 } // '"' 520 | , { 7, 5, 8, 5, 0, -8 } // '#' 521 | , { 12, 5, 8, 5, 0, -8 } // '$' 522 | , { 17, 5, 8, 5, 0, -8 } // '%' 523 | , { 22, 5, 8, 5, 0, -8 } // '&' 524 | , { 27, 5, 8, 5, 0, -11 } // ''' 525 | , { 32, 5, 8, 5, 0, -8 } // '(' 526 | , { 37, 5, 8, 5, 0, -8 } // ')' 527 | , { 42, 5, 8, 5, 0, -8 } // '*' 528 | , { 47, 5, 8, 5, 0, -8 } // '+' 529 | , { 52, 5, 8, 5, 0, -8 } // ',' 530 | , { 57, 6, 1, 10, 2, -6 } // '-' 531 | , { 58, 3, 1, 1, -1, -1 } // '.' 532 | , { 59, 5, 8, 5, 0, -8 } // '/' 533 | , { 64, 8, 11, 10, 1, -11 } // '0' 534 | , { 75, 2, 10, 10, 7, -11 } // '1' 535 | , { 78, 8, 11, 10, 1, -11 } // '2' 536 | , { 89, 7, 11, 10, 2, -11 } // '3' 537 | , { 99, 8, 10, 10, 1, -11 } // '4' 538 | , { 109, 8, 11, 10, 1, -11 } // '5' 539 | , { 120, 8, 11, 10, 1, -11 } // '6' 540 | , { 131, 8, 10, 10, 1, -11 } // '7' 541 | , { 141, 8, 11, 10, 1, -11 } // '8' 542 | , { 152, 8, 11, 10, 1, -11 } // '9' 543 | , { 163, 3, 6, 3, 0, -8 } // ':' 544 | , { 166, 5, 8, 5, 0, -8 } // ';' 545 | , { 171, 5, 8, 5, 0, -8 } // '<' 546 | , { 176, 5, 8, 5, 0, -8 } // '=' 547 | , { 181, 5, 8, 5, 0, -8 } // '>' 548 | , { 186, 5, 8, 5, 0, -8 } // '?' 549 | , { 191, 5, 8, 5, 0, -8 } // '@' 550 | , { 196, 8, 10, 10, 1, -11 } // 'A' 551 | , { 206, 8, 11, 10, 1, -11 } // 'B' 552 | , { 217, 7, 6, 10, 1, -6 } // 'C' 553 | , { 223, 8, 11, 10, 1, -11 } // 'D' 554 | , { 234, 7, 11, 10, 1, -11 } // 'E' 555 | , { 244, 7, 10, 10, 1, -11 } // 'F' 556 | , { 253, 8, 11, 10, 1, -11 } // 'G' 557 | , { 264, 8, 10, 10, 1, -11 } // 'H' 558 | , { 274, 2, 4, 10, 7, -5 } // 'I' 559 | , { 275, 8, 11, 10, 1, -11 } // 'J' 560 | , { 286, 8, 10, 10, 1, -11 } // 'K' 561 | , { 296, 7, 11, 10, 1, -11 } // 'L' 562 | , { 306, 8, 10, 10, 1, -11 } // 'M' 563 | , { 316, 8, 5, 10, 1, -6 } // 'N' 564 | , { 321, 8, 6, 10, 1, -6 } // 'O' 565 | , { 327, 8, 10, 10, 1, -11 } // 'P' 566 | , { 337, 8, 10, 10, 1, -11 } // 'Q' 567 | , { 347, 7, 5, 10, 1, -6 } // 'R' 568 | , { 352, 8, 11, 10, 1, -11 } // 'S' 569 | , { 363, 7, 11, 10, 1, -11 } // 'T' 570 | , { 373, 8, 5, 10, 1, -5 } // 'U' 571 | , { 378, 8, 11, 10, 1, -11 } // 'V' 572 | , { 389, 8, 11, 10, 1, -11 } // 'W' 573 | , { 400, 8, 10, 10, 1, -11 } // 'X' 574 | , { 410, 8, 11, 10, 1, -11 } // 'Y' 575 | , { 421, 8, 11, 10, 1, -11 } // 'Z' 576 | , { 432, 5, 8, 5, 0, -8 } // '[' 577 | , { 437, 5, 8, 5, 0, -8 } // '\' 578 | , { 442, 5, 8, 5, 0, -8 } // ']' 579 | , { 447, 5, 8, 5, 0, -8 } // '^' 580 | , { 452, 5, 8, 5, 0, -8 } // '_' 581 | , { 457, 5, 8, 5, 0, -8 } // '`' 582 | , { 462, 8, 10, 10, 1, -11 } // 'a' 583 | , { 472, 8, 11, 10, 1, -11 } // 'b' 584 | , { 483, 7, 6, 10, 1, -6 } // 'c' 585 | , { 489, 8, 11, 10, 1, -11 } // 'd' 586 | , { 500, 7, 11, 10, 1, -11 } // 'e' 587 | , { 510, 7, 10, 10, 1, -11 } // 'f' 588 | , { 519, 8, 11, 10, 1, -11 } // 'g' 589 | , { 530, 8, 10, 10, 1, -11 } // 'h' 590 | , { 540, 2, 4, 10, 7, -5 } // 'i' 591 | , { 541, 8, 11, 10, 1, -11 } // 'j' 592 | , { 552, 8, 10, 10, 1, -11 } // 'k' 593 | , { 562, 7, 11, 10, 1, -11 } // 'l' 594 | , { 572, 8, 10, 10, 1, -11 } // 'm' 595 | , { 582, 8, 5, 10, 1, -6 } // 'n' 596 | , { 587, 8, 6, 10, 1, -6 } // 'o' 597 | , { 593, 8, 10, 10, 1, -11 } // 'p' 598 | , { 603, 8, 10, 10, 1, -11 } // 'q' 599 | , { 613, 7, 5, 10, 1, -6 } // 'r' 600 | , { 618, 8, 11, 10, 1, -11 } // 's' 601 | , { 629, 7, 11, 10, 1, -11 } // 't' 602 | , { 639, 8, 5, 10, 1, -5 } // 'u' 603 | , { 644, 8, 11, 10, 1, -11 } // 'v' 604 | , { 655, 8, 11, 10, 1, -11 } // 'w' 605 | , { 666, 8, 10, 10, 1, -11 } // 'x' 606 | , { 676, 8, 11, 10, 1, -11 } // 'y' 607 | , { 687, 8, 11, 10, 1, -11 } // 'z' 608 | , { 698, 5, 8, 5, 0, -8 } // '{' 609 | , { 703, 5, 8, 5, 0, -8 } // '|' 610 | , { 708, 5, 8, 5, 0, -8 } // '}' 611 | }; 612 | 613 | const GFXfont DSEG7_Classic_Bold_11 PROGMEM = { 614 | (uint8_t *)DSEG7_Classic_Bold_11Bitmaps, (GFXglyph *)DSEG7_Classic_Bold_11Glyphs, 0x20, 0x7E, 12 615 | }; 616 | 617 | const uint8_t DSEG7_Classic_Bold_18Bitmaps[] PROGMEM = { 618 | 0x00, 0x00, 0xFA, 0x28, 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 0x28, 0xBE, 0xFA, 619 | 0x28, 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 0x28, 0xBE, 0xFA, 0x28, 0xA2, 0x8A, 620 | 0x28, 0xA2, 0x8A, 0x28, 0xBE, 0x00, 0xF3, 0x93, 0x97, 0xF6, 0x06, 0x0C, 621 | 0x0C, 0x18, 0x18, 0x30, 0x70, 0x60, 0xDE, 0xD2, 0xD2, 0x9E, 0x00, 0xFA, 622 | 0x28, 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 0x28, 0xBE, 0xF9, 0x9F, 0xFA, 0x28, 623 | 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 0x28, 0xBE, 0xFA, 0x28, 0xA2, 0x8A, 0x28, 624 | 0xA2, 0x8A, 0x28, 0xBE, 0xFA, 0x28, 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 0x28, 625 | 0xBE, 0xFA, 0x28, 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 0x28, 0xBE, 0xFA, 0x28, 626 | 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 0x28, 0xBE, 0x7F, 0x1F, 0xC0, 0xD8, 0x04, 627 | 0x30, 0xC3, 0x0C, 0x61, 0x86, 0x30, 0xC3, 0x18, 0x63, 0x8C, 0x20, 0x7F, 628 | 0xCB, 0xFA, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0x80, 629 | 0x28, 0x02, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xBF, 630 | 0xA7, 0xFC, 0x5B, 0x6D, 0xB2, 0x5B, 0x6D, 0xB2, 0x7F, 0xC3, 0xFA, 0x00, 631 | 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x3F, 0xAB, 0xF8, 0xC0, 632 | 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xBF, 0x87, 0xFC, 0xFF, 633 | 0x8F, 0xE8, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x7F, 0x4F, 634 | 0xE8, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x7F, 0x5F, 0xF0, 635 | 0x80, 0x2C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6B, 0xFA, 636 | 0x3F, 0xA0, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x02, 637 | 0x7F, 0xCB, 0xF8, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 638 | 0xBF, 0x83, 0xFA, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 639 | 0x3F, 0xA7, 0xFC, 0x7F, 0xCB, 0xF8, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 640 | 0xC0, 0x0C, 0x00, 0xBF, 0x8B, 0xFA, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 641 | 0xC0, 0x6C, 0x06, 0xBF, 0xA7, 0xFC, 0x7F, 0xCB, 0xFA, 0xC0, 0x6C, 0x06, 642 | 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0x80, 0x20, 0x02, 0x00, 0x60, 0x06, 643 | 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x20, 0x7F, 0xCB, 0xFA, 0xC0, 644 | 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xBF, 0xAB, 0xFA, 0xC0, 645 | 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xBF, 0xA7, 0xFC, 0x7F, 646 | 0xCB, 0xFA, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xBF, 647 | 0xA3, 0xFA, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x3F, 648 | 0xA7, 0xFC, 0x9A, 0x00, 0x00, 0xD8, 0xFA, 0x28, 0xA2, 0x8A, 0x28, 0xA2, 649 | 0x8A, 0x28, 0xBE, 0xFA, 0x28, 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 0x28, 0xBE, 650 | 0xFA, 0x28, 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 0x28, 0xBE, 0xFA, 0x28, 0xA2, 651 | 0x8A, 0x28, 0xA2, 0x8A, 0x28, 0xBE, 0xFA, 0x28, 0xA2, 0x8A, 0x28, 0xA2, 652 | 0x8A, 0x28, 0xBE, 0xFA, 0x28, 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 0x28, 0xBE, 653 | 0x7F, 0xCB, 0xFA, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 654 | 0xBF, 0xAB, 0xFA, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 655 | 0x80, 0x20, 0x80, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 656 | 0x0B, 0xF8, 0xBF, 0xAC, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 657 | 0x6B, 0xFA, 0x7F, 0xC0, 0x3F, 0x97, 0xF3, 0x00, 0x60, 0x0C, 0x01, 0x80, 658 | 0x30, 0x06, 0x00, 0xBF, 0x8F, 0xF8, 0x00, 0x20, 0x06, 0x00, 0x60, 0x06, 659 | 0x00, 0x60, 0x06, 0x00, 0x63, 0xFA, 0xBF, 0xAC, 0x06, 0xC0, 0x6C, 0x06, 660 | 0xC0, 0x6C, 0x06, 0xC0, 0x6B, 0xFA, 0x7F, 0xC0, 0x7F, 0xD7, 0xF3, 0x00, 661 | 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xBF, 0x97, 0xF3, 0x00, 0x60, 662 | 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xBF, 0x8F, 0xF8, 0x7F, 0xD7, 0xF3, 663 | 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xBF, 0x97, 0xF3, 0x00, 664 | 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0x80, 0x00, 0x7F, 0xCB, 0xF8, 665 | 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0x80, 0x08, 0x02, 666 | 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xBF, 0xA7, 0xFC, 667 | 0x80, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0B, 0xF8, 668 | 0xBF, 0xAC, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x68, 0x02, 669 | 0x5B, 0x6D, 0xB2, 0x00, 0x20, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 670 | 0x00, 0x60, 0x02, 0x80, 0x2C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 671 | 0xC0, 0x6B, 0xFA, 0x7F, 0xC0, 0x7F, 0xCB, 0xF8, 0xC0, 0x0C, 0x00, 0xC0, 672 | 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xBF, 0x8B, 0xFA, 0xC0, 0x6C, 0x06, 0xC0, 673 | 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0x80, 0x20, 0x80, 0x18, 0x03, 0x00, 0x60, 674 | 0x0C, 0x01, 0x80, 0x30, 0x04, 0x00, 0x80, 0x18, 0x03, 0x00, 0x60, 0x0C, 675 | 0x01, 0x80, 0x30, 0x05, 0xFC, 0x7F, 0xC0, 0x7F, 0xCB, 0xFA, 0xC0, 0x6C, 676 | 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0x80, 0x28, 0x02, 0xC0, 0x6C, 677 | 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0x80, 0x20, 0x3F, 0x8B, 0xFA, 678 | 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0x80, 0x20, 0x3F, 679 | 0x8B, 0xFA, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xBF, 680 | 0xA7, 0xFC, 0x7F, 0xCB, 0xFA, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 681 | 0x6C, 0x06, 0xBF, 0xAB, 0xF8, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 682 | 0x0C, 0x00, 0x80, 0x00, 0x7F, 0xCB, 0xFA, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 683 | 0x06, 0xC0, 0x6C, 0x06, 0xBF, 0xA3, 0xFA, 0x00, 0x60, 0x06, 0x00, 0x60, 684 | 0x06, 0x00, 0x60, 0x06, 0x00, 0x20, 0x3F, 0x97, 0xF3, 0x00, 0x60, 0x0C, 685 | 0x01, 0x80, 0x30, 0x06, 0x00, 0x80, 0x00, 0x80, 0x0C, 0x00, 0xC0, 0x0C, 686 | 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0B, 0xF8, 0x3F, 0xA0, 0x06, 0x00, 0x60, 687 | 0x06, 0x00, 0x60, 0x06, 0x00, 0x63, 0xFA, 0x7F, 0xC0, 0x80, 0x18, 0x03, 688 | 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x05, 0xFC, 0xBF, 0x98, 0x03, 0x00, 689 | 0x60, 0x0C, 0x01, 0x80, 0x30, 0x05, 0xFC, 0x7F, 0xC0, 0x80, 0x2C, 0x06, 690 | 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6B, 0xFA, 0x7F, 0xC0, 0x80, 691 | 0x2C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x68, 0x02, 0x80, 692 | 0x2C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6B, 0xFA, 0x7F, 693 | 0xC0, 0x80, 0x2C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6B, 694 | 0xFA, 0xBF, 0xAC, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6B, 695 | 0xFA, 0x7F, 0xC0, 0x80, 0x2C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 696 | 0xC0, 0x6B, 0xFA, 0xBF, 0xAC, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 697 | 0xC0, 0x68, 0x02, 0x80, 0x2C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 698 | 0xC0, 0x6B, 0xFA, 0x3F, 0xA0, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 699 | 0x00, 0x63, 0xFA, 0x7F, 0xC0, 0x7F, 0xC3, 0xFA, 0x00, 0x60, 0x06, 0x00, 700 | 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x28, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 701 | 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xBF, 0x87, 0xFC, 0xFA, 0x28, 0xA2, 0x8A, 702 | 0x28, 0xA2, 0x8A, 0x28, 0xBE, 0xFA, 0x28, 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 703 | 0x28, 0xBE, 0xFA, 0x28, 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 0x28, 0xBE, 0xFA, 704 | 0x28, 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 0x28, 0xBE, 0xFA, 0x28, 0xA2, 0x8A, 705 | 0x28, 0xA2, 0x8A, 0x28, 0xBE, 0xFA, 0x28, 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 706 | 0x28, 0xBE, 0x7F, 0xCB, 0xFA, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 707 | 0x6C, 0x06, 0xBF, 0xAB, 0xFA, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 708 | 0x6C, 0x06, 0x80, 0x20, 0x80, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 709 | 0x00, 0xC0, 0x0B, 0xF8, 0xBF, 0xAC, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 710 | 0x06, 0xC0, 0x6B, 0xFA, 0x7F, 0xC0, 0x3F, 0x97, 0xF3, 0x00, 0x60, 0x0C, 711 | 0x01, 0x80, 0x30, 0x06, 0x00, 0xBF, 0x8F, 0xF8, 0x00, 0x20, 0x06, 0x00, 712 | 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x63, 0xFA, 0xBF, 0xAC, 0x06, 0xC0, 713 | 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6B, 0xFA, 0x7F, 0xC0, 0x7F, 0xD7, 714 | 0xF3, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xBF, 0x97, 0xF3, 715 | 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xBF, 0x8F, 0xF8, 0x7F, 716 | 0xD7, 0xF3, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xBF, 0x97, 717 | 0xF3, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0x80, 0x00, 0x7F, 718 | 0xCB, 0xF8, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0x80, 719 | 0x08, 0x02, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xBF, 720 | 0xA7, 0xFC, 0x80, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 721 | 0x0B, 0xF8, 0xBF, 0xAC, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 722 | 0x68, 0x02, 0x5B, 0x6D, 0xB2, 0x00, 0x20, 0x06, 0x00, 0x60, 0x06, 0x00, 723 | 0x60, 0x06, 0x00, 0x60, 0x02, 0x80, 0x2C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 724 | 0x6C, 0x06, 0xC0, 0x6B, 0xFA, 0x7F, 0xC0, 0x7F, 0xCB, 0xF8, 0xC0, 0x0C, 725 | 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xBF, 0x8B, 0xFA, 0xC0, 0x6C, 726 | 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0x80, 0x20, 0x80, 0x18, 0x03, 727 | 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x04, 0x00, 0x80, 0x18, 0x03, 0x00, 728 | 0x60, 0x0C, 0x01, 0x80, 0x30, 0x05, 0xFC, 0x7F, 0xC0, 0x7F, 0xCB, 0xFA, 729 | 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0x80, 0x28, 0x02, 730 | 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0x80, 0x20, 0x3F, 731 | 0x8B, 0xFA, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0x80, 732 | 0x20, 0x3F, 0x8B, 0xFA, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 733 | 0x06, 0xBF, 0xA7, 0xFC, 0x7F, 0xCB, 0xFA, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 734 | 0x06, 0xC0, 0x6C, 0x06, 0xBF, 0xAB, 0xF8, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 735 | 0x00, 0xC0, 0x0C, 0x00, 0x80, 0x00, 0x7F, 0xCB, 0xFA, 0xC0, 0x6C, 0x06, 736 | 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xBF, 0xA3, 0xFA, 0x00, 0x60, 0x06, 737 | 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x20, 0x3F, 0x97, 0xF3, 0x00, 738 | 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0x80, 0x00, 0x80, 0x0C, 0x00, 739 | 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0B, 0xF8, 0x3F, 0xA0, 0x06, 740 | 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x63, 0xFA, 0x7F, 0xC0, 0x80, 741 | 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x05, 0xFC, 0xBF, 0x98, 742 | 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x05, 0xFC, 0x7F, 0xC0, 0x80, 743 | 0x2C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6B, 0xFA, 0x7F, 744 | 0xC0, 0x80, 0x2C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x68, 745 | 0x02, 0x80, 0x2C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6B, 746 | 0xFA, 0x7F, 0xC0, 0x80, 0x2C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 747 | 0xC0, 0x6B, 0xFA, 0xBF, 0xAC, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 748 | 0xC0, 0x6B, 0xFA, 0x7F, 0xC0, 0x80, 0x2C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 749 | 0x6C, 0x06, 0xC0, 0x6B, 0xFA, 0xBF, 0xAC, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 750 | 0x6C, 0x06, 0xC0, 0x68, 0x02, 0x80, 0x2C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 751 | 0x6C, 0x06, 0xC0, 0x6B, 0xFA, 0x3F, 0xA0, 0x06, 0x00, 0x60, 0x06, 0x00, 752 | 0x60, 0x06, 0x00, 0x63, 0xFA, 0x7F, 0xC0, 0x7F, 0xC3, 0xFA, 0x00, 0x60, 753 | 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x28, 0x00, 0xC0, 0x0C, 754 | 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xBF, 0x87, 0xFC, 0xFA, 0x28, 755 | 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 0x28, 0xBE, 0xFA, 0x28, 0xA2, 0x8A, 0x28, 756 | 0xA2, 0x8A, 0x28, 0xBE, 0xFA, 0x28, 0xA2, 0x8A, 0x28, 0xA2, 0x8A, 0x28, 757 | 0xBE 758 | }; 759 | 760 | const GFXglyph DSEG7_Classic_Bold_18Glyphs[] PROGMEM = { 761 | { 0, 1, 1, 5, 0, 0 } // ' ' 762 | ,{ 1, 1, 1, 16, 0, 0 } // '!' 763 | ,{ 2, 6, 12, 8, 1, -12 } // '"' 764 | ,{ 11, 6, 12, 8, 1, -12 } // '#' 765 | ,{ 20, 6, 12, 8, 1, -12 } // '$' 766 | ,{ 29, 8, 18, 8, 0, -17 } // '%' 767 | ,{ 47, 6, 12, 8, 1, -12 } // '&' 768 | ,{ 56, 4, 4, 8, 0, -18 } // ''' 769 | ,{ 58, 6, 12, 8, 1, -12 } // '(' 770 | ,{ 67, 6, 12, 8, 1, -12 } // ')' 771 | ,{ 76, 6, 12, 8, 1, -12 } // '*' 772 | ,{ 85, 6, 12, 8, 1, -12 } // '+' 773 | ,{ 94, 6, 12, 8, 1, -12 } // ',' 774 | ,{ 103, 10, 2, 16, 3, -10 } // '-' 775 | ,{ 106, 3, 2, 1, -1, -2 } // '.' 776 | ,{ 107, 6, 16, 8, 1, -16 } // '/' 777 | ,{ 119, 12, 18, 16, 2, -18 } // '0' 778 | ,{ 146, 3, 16, 16, 11, -17 } // '1' 779 | ,{ 152, 12, 18, 16, 2, -18 } // '2' 780 | ,{ 179, 11, 18, 16, 3, -18 } // '3' 781 | ,{ 204, 12, 16, 16, 2, -17 } // '4' 782 | ,{ 228, 12, 18, 16, 2, -18 } // '5' 783 | ,{ 255, 12, 18, 16, 2, -18 } // '6' 784 | ,{ 282, 12, 17, 16, 2, -18 } // '7' 785 | ,{ 308, 12, 18, 16, 2, -18 } // '8' 786 | ,{ 335, 12, 18, 16, 2, -18 } // '9' 787 | ,{ 362, 3, 10, 5, 1, -14 } // ':' 788 | ,{ 366, 6, 12, 8, 1, -12 } // ';' 789 | ,{ 375, 6, 12, 8, 1, -12 } // '<' 790 | ,{ 384, 6, 12, 8, 1, -12 } // '=' 791 | ,{ 393, 6, 12, 8, 1, -12 } // '>' 792 | ,{ 402, 6, 12, 8, 1, -12 } // '?' 793 | ,{ 411, 6, 12, 8, 1, -12 } // '@' 794 | ,{ 420, 12, 17, 16, 2, -18 } // 'A' 795 | ,{ 446, 12, 17, 16, 2, -17 } // 'B' 796 | ,{ 472, 11, 10, 16, 2, -10 } // 'C' 797 | ,{ 486, 12, 17, 16, 2, -17 } // 'D' 798 | ,{ 512, 11, 18, 16, 2, -18 } // 'E' 799 | ,{ 537, 11, 17, 16, 2, -18 } // 'F' 800 | ,{ 561, 12, 18, 16, 2, -18 } // 'G' 801 | ,{ 588, 12, 16, 16, 2, -17 } // 'H' 802 | ,{ 612, 3, 8, 16, 11, -9 } // 'I' 803 | ,{ 615, 12, 17, 16, 2, -17 } // 'J' 804 | ,{ 641, 12, 17, 16, 2, -18 } // 'K' 805 | ,{ 667, 11, 17, 16, 2, -17 } // 'L' 806 | ,{ 691, 12, 17, 16, 2, -18 } // 'M' 807 | ,{ 717, 12, 9, 16, 2, -10 } // 'N' 808 | ,{ 731, 12, 10, 16, 2, -10 } // 'O' 809 | ,{ 746, 12, 17, 16, 2, -18 } // 'P' 810 | ,{ 772, 12, 17, 16, 2, -18 } // 'Q' 811 | ,{ 798, 11, 9, 16, 2, -10 } // 'R' 812 | ,{ 811, 12, 17, 16, 2, -17 } // 'S' 813 | ,{ 837, 11, 17, 16, 2, -17 } // 'T' 814 | ,{ 861, 12, 9, 16, 2, -9 } // 'U' 815 | ,{ 875, 12, 17, 16, 2, -17 } // 'V' 816 | ,{ 901, 12, 17, 16, 2, -17 } // 'W' 817 | ,{ 927, 12, 16, 16, 2, -17 } // 'X' 818 | ,{ 951, 12, 17, 16, 2, -17 } // 'Y' 819 | ,{ 977, 12, 18, 16, 2, -18 } // 'Z' 820 | ,{ 1004, 6, 12, 8, 1, -12 } // '[' 821 | ,{ 1013, 6, 12, 8, 1, -12 } // '\' 822 | ,{ 1022, 6, 12, 8, 1, -12 } // ']' 823 | ,{ 1031, 6, 12, 8, 1, -12 } // '^' 824 | ,{ 1040, 6, 12, 8, 1, -12 } // '_' 825 | ,{ 1049, 6, 12, 8, 1, -12 } // '`' 826 | ,{ 1058, 12, 17, 16, 2, -18 } // 'a' 827 | ,{ 1084, 12, 17, 16, 2, -17 } // 'b' 828 | ,{ 1110, 11, 10, 16, 2, -10 } // 'c' 829 | ,{ 1124, 12, 17, 16, 2, -17 } // 'd' 830 | ,{ 1150, 11, 18, 16, 2, -18 } // 'e' 831 | ,{ 1175, 11, 17, 16, 2, -18 } // 'f' 832 | ,{ 1199, 12, 18, 16, 2, -18 } // 'g' 833 | ,{ 1226, 12, 16, 16, 2, -17 } // 'h' 834 | ,{ 1250, 3, 8, 16, 11, -9 } // 'i' 835 | ,{ 1253, 12, 17, 16, 2, -17 } // 'j' 836 | ,{ 1279, 12, 17, 16, 2, -18 } // 'k' 837 | ,{ 1305, 11, 17, 16, 2, -17 } // 'l' 838 | ,{ 1329, 12, 17, 16, 2, -18 } // 'm' 839 | ,{ 1355, 12, 9, 16, 2, -10 } // 'n' 840 | ,{ 1369, 12, 10, 16, 2, -10 } // 'o' 841 | ,{ 1384, 12, 17, 16, 2, -18 } // 'p' 842 | ,{ 1410, 12, 17, 16, 2, -18 } // 'q' 843 | ,{ 1436, 11, 9, 16, 2, -10 } // 'r' 844 | ,{ 1449, 12, 17, 16, 2, -17 } // 's' 845 | ,{ 1475, 11, 17, 16, 2, -17 } // 't' 846 | ,{ 1499, 12, 9, 16, 2, -9 } // 'u' 847 | ,{ 1513, 12, 17, 16, 2, -17 } // 'v' 848 | ,{ 1539, 12, 17, 16, 2, -17 } // 'w' 849 | ,{ 1565, 12, 16, 16, 2, -17 } // 'x' 850 | ,{ 1589, 12, 17, 16, 2, -17 } // 'y' 851 | ,{ 1615, 12, 18, 16, 2, -18 } // 'z' 852 | ,{ 1642, 6, 12, 8, 1, -12 } // '{' 853 | ,{ 1651, 6, 12, 8, 1, -12 } // '|' 854 | ,{ 1660, 6, 12, 8, 1, -12 } // '}' 855 | }; 856 | 857 | const GFXfont DSEG7_Classic_Bold_18 PROGMEM = { 858 | (uint8_t *)DSEG7_Classic_Bold_18Bitmaps, (GFXglyph *)DSEG7_Classic_Bold_18Glyphs, 0x20, 0x7E, 20 859 | }; 860 | --------------------------------------------------------------------------------