Initial project setup

This commit is contained in:
Thomas Kolb 2024-06-16 16:00:19 +02:00
commit 2b9870fb29
11 changed files with 1236 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
.pio
.cache
compile_commands.json

475
include/Font_din1451e.h Normal file
View file

@ -0,0 +1,475 @@
const uint8_t din1451e24pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0x79, 0xE7, 0x9E, 0x79, 0xE7,
0x9E, 0x79, 0xC7, 0x1C, 0x70, 0xC3, 0x0C, 0x00, 0x00, 0x1E, 0x79, 0xE7,
0x80, 0xF8, 0xFF, 0xC7, 0xFE, 0x3F, 0xF1, 0xFF, 0x8F, 0xFC, 0x7D, 0xE3,
0xCF, 0x1E, 0x78, 0xF3, 0xC7, 0x9E, 0x3C, 0xF1, 0xE0, 0x00, 0x0F, 0x0F,
0x00, 0x03, 0xC3, 0xC0, 0x00, 0x78, 0x78, 0x00, 0x1F, 0x1F, 0x00, 0x03,
0xC3, 0xC0, 0x00, 0x78, 0x78, 0x01, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF,
0x0F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xF8, 0x03, 0xC3, 0xC0, 0x00, 0xF8,
0xF8, 0x00, 0x1E, 0x1E, 0x00, 0x03, 0xC3, 0xC0, 0x1F, 0xFF, 0xFF, 0xC3,
0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0x80, 0x1E, 0x1E,
0x00, 0x07, 0xC7, 0xC0, 0x00, 0xF0, 0xF0, 0x00, 0x1E, 0x1E, 0x00, 0x07,
0x87, 0xC0, 0x00, 0x01, 0x80, 0x03, 0x00, 0x06, 0x00, 0x3F, 0x01, 0xFF,
0x07, 0xFF, 0x1F, 0xFF, 0x3E, 0x1E, 0xF8, 0x3F, 0xE0, 0x3F, 0xC0, 0x7F,
0x80, 0xFF, 0x00, 0x1E, 0x00, 0x3E, 0x00, 0x3F, 0x80, 0x7F, 0xC0, 0x7F,
0xE0, 0x7F, 0xE0, 0x3F, 0xE0, 0x0F, 0xC0, 0x07, 0xC0, 0x07, 0x80, 0x0F,
0x00, 0x1F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xEF, 0x0F, 0x9F,
0xFF, 0x1F, 0xFC, 0x1F, 0xF0, 0x0F, 0xC0, 0x06, 0x00, 0x0C, 0x00, 0x18,
0x00, 0x3E, 0x00, 0x38, 0xFE, 0x00, 0xE3, 0xFC, 0x01, 0xC7, 0x1C, 0x07,
0x0E, 0x38, 0x0E, 0x1C, 0x70, 0x38, 0x38, 0xE0, 0xE0, 0x71, 0xC1, 0xC0,
0xE3, 0x87, 0x01, 0xC7, 0x0E, 0x03, 0x8E, 0x38, 0x07, 0x1C, 0x70, 0x0E,
0x39, 0xC0, 0x1F, 0xE3, 0x80, 0x1F, 0xCE, 0x00, 0x1F, 0x3C, 0x7C, 0x00,
0x71, 0xFC, 0x01, 0xC7, 0xF8, 0x03, 0x8E, 0x38, 0x0E, 0x1C, 0x70, 0x1C,
0x38, 0xE0, 0x70, 0x71, 0xC0, 0xE0, 0xE3, 0x83, 0x81, 0xC7, 0x07, 0x03,
0x8E, 0x1C, 0x07, 0x1C, 0x70, 0x0E, 0x38, 0xE0, 0x1C, 0x73, 0x80, 0x3F,
0xC7, 0x00, 0x3F, 0x9C, 0x00, 0x3E, 0x00, 0x01, 0xF8, 0x00, 0x3F, 0xC0,
0x07, 0xFE, 0x00, 0xFF, 0xF0, 0x0F, 0x9F, 0x00, 0xF0, 0xF0, 0x0F, 0x0F,
0x00, 0xF0, 0xF0, 0x0F, 0x9E, 0x00, 0x7F, 0xE0, 0x07, 0xFC, 0x00, 0x3F,
0x80, 0x03, 0xF0, 0x00, 0xFF, 0x1E, 0x1F, 0xF9, 0xE3, 0xEF, 0x9E, 0x3C,
0x79, 0xE7, 0x87, 0xDE, 0x78, 0x7F, 0xEF, 0x03, 0xFC, 0xF0, 0x3F, 0xCF,
0x01, 0xFC, 0xF0, 0x1F, 0xCF, 0x00, 0xF8, 0xF8, 0x0F, 0x87, 0x81, 0xF8,
0x7C, 0x3F, 0xC7, 0xFF, 0xFC, 0x3F, 0xFF, 0xE1, 0xFF, 0xBE, 0x07, 0xE3,
0xF0, 0xFF, 0xFF, 0xFF, 0xFD, 0xEF, 0x7B, 0xDE, 0xF0, 0x03, 0x07, 0x0E,
0x0E, 0x1E, 0x1E, 0x1C, 0x3C, 0x3C, 0x3C, 0x7C, 0x7C, 0x78, 0x78, 0xF8,
0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
0x78, 0x78, 0x7C, 0x7C, 0x3C, 0x3C, 0x3C, 0x1C, 0x1E, 0x1E, 0x0E, 0x0E,
0x07, 0x03, 0xC0, 0xE0, 0x70, 0x70, 0x78, 0x78, 0x38, 0x3C, 0x3C, 0x3C,
0x3E, 0x3E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x1F, 0x1F, 0x1E, 0x1E, 0x3E, 0x3E, 0x3C, 0x3C, 0x3C, 0x38,
0x78, 0x78, 0x70, 0x70, 0xE0, 0xC0, 0x0F, 0x06, 0xF2, 0xFF, 0x67, 0xFF,
0x3F, 0xC3, 0xFC, 0x7F, 0xEF, 0xFF, 0x6F, 0x64, 0xF2, 0x0F, 0x00, 0x00,
0x38, 0x00, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xC0, 0x00, 0x03,
0x80, 0x00, 0x07, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x38,
0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xC0, 0x00, 0x03, 0x80,
0x00, 0x07, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x38, 0x00,
0x00, 0x70, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xC0, 0x00, 0x03, 0x80, 0x00,
0xFF, 0xFF, 0xEC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFC, 0xFF, 0xFF, 0x07, 0x83, 0xC1, 0xE1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E,
0x0F, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x7C, 0x3C, 0x1E, 0x0F,
0x07, 0x83, 0xC1, 0xE1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x0F, 0x07,
0x83, 0xC0, 0x07, 0x00, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F,
0xE1, 0xFF, 0x0F, 0xF8, 0x7F, 0xC3, 0xFE, 0x1F, 0xF0, 0xFF, 0x87, 0xFC,
0x3F, 0xE1, 0xFF, 0x0F, 0xF8, 0x7F, 0xC3, 0xFE, 0x1F, 0xF0, 0xFF, 0x87,
0xFC, 0x3F, 0xE1, 0xFF, 0x0F, 0xF8, 0x7F, 0xC3, 0xFE, 0x1F, 0xFB, 0xF7,
0xFF, 0xBF, 0xF8, 0xFF, 0x81, 0xF8, 0x0F, 0x9F, 0xDF, 0xFF, 0xFF, 0x7F,
0x3E, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F,
0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1,
0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x81, 0xFF, 0x1F, 0xFC, 0xFF, 0xEF,
0x8F, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x78, 0x03, 0xC0, 0x1E, 0x01,
0xF0, 0x0F, 0x00, 0xF8, 0x07, 0x80, 0x7C, 0x07, 0xC0, 0x3E, 0x03, 0xF0,
0x1F, 0x01, 0xF8, 0x0F, 0x80, 0xFC, 0x07, 0xC0, 0x7E, 0x03, 0xE0, 0x3F,
0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x0F, 0x81, 0xFF, 0x1F,
0xFC, 0xFF, 0xEF, 0x8F, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x78, 0x03,
0xC0, 0x1E, 0x01, 0xF0, 0x7F, 0x03, 0xF0, 0x1F, 0x80, 0xFE, 0x00, 0xF8,
0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0,
0x7F, 0x83, 0xFE, 0x3E, 0xFF, 0xE7, 0xFE, 0x1F, 0xE0, 0x3E, 0x00, 0x01,
0xE0, 0x01, 0xE0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x07, 0x80, 0x07,
0x80, 0x07, 0x80, 0x0F, 0x80, 0x0F, 0x00, 0x0F, 0x00, 0x1F, 0x00, 0x1E,
0x00, 0x1E, 0x78, 0x1E, 0x78, 0x3E, 0x78, 0x3C, 0x78, 0x3C, 0x78, 0x7C,
0x78, 0x7C, 0x78, 0x78, 0x78, 0xF8, 0x78, 0xF8, 0x78, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00,
0x78, 0x7F, 0xFB, 0xFF, 0xDF, 0xFE, 0xFF, 0xF7, 0x80, 0x3C, 0x01, 0xE0,
0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF7, 0x87, 0xFF, 0x3F, 0xF9,
0xFF, 0xEF, 0x1F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80,
0x3C, 0x01, 0xFF, 0x0F, 0xF8, 0x7F, 0xC3, 0xFF, 0x3E, 0xFF, 0xE7, 0xFF,
0x1F, 0xF0, 0x3E, 0x00, 0x01, 0xF0, 0x0F, 0x00, 0xF8, 0x07, 0x80, 0x3C,
0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0F, 0x00, 0xF8, 0x07, 0x80, 0x7C, 0x03,
0xFC, 0x1F, 0xF9, 0xFF, 0xCF, 0xFF, 0xF8, 0xFF, 0x83, 0xFC, 0x1F, 0xE0,
0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFE, 0x3E,
0xFF, 0xE7, 0xFF, 0x1F, 0xF0, 0x3E, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x07, 0xF8, 0x3F, 0xC3, 0xDE, 0x1E, 0x00, 0xF0, 0x0F, 0x00,
0x78, 0x03, 0xC0, 0x3E, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x07, 0x80, 0x3C,
0x01, 0xE0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x7C, 0x03, 0xC0, 0x1E, 0x00,
0xF0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x3C, 0x01, 0xE0, 0x00, 0x0F, 0x81,
0xFF, 0x1F, 0xFC, 0xFF, 0xEF, 0x8F, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0,
0x7F, 0x83, 0xFC, 0x1F, 0xF1, 0xF7, 0xFF, 0x3F, 0xF9, 0xFF, 0xCF, 0xFE,
0xF8, 0xFF, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE,
0x0F, 0xF0, 0x7F, 0x83, 0xFE, 0x3E, 0xFF, 0xE7, 0xFF, 0x1F, 0xF0, 0x3E,
0x00, 0x0F, 0x81, 0xFF, 0x1F, 0xFC, 0xFF, 0xEF, 0x8F, 0xF8, 0x3F, 0xC1,
0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xFC, 0x7F,
0xFF, 0xEF, 0xFE, 0x7F, 0xF0, 0xEF, 0x00, 0xF8, 0x07, 0xC0, 0x3C, 0x03,
0xE0, 0x1E, 0x00, 0xF0, 0x0F, 0x80, 0x78, 0x03, 0xC0, 0x3C, 0x01, 0xE0,
0x0F, 0x00, 0xF0, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0,
0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0x80, 0x00, 0x00, 0x30, 0x00,
0x0F, 0x00, 0x01, 0xF0, 0x00, 0x7F, 0x00, 0x1F, 0xE0, 0x07, 0xF8, 0x01,
0xFE, 0x00, 0x7F, 0x80, 0x1F, 0xE0, 0x07, 0xFC, 0x00, 0xFF, 0x00, 0x0F,
0xC0, 0x00, 0xFC, 0x00, 0x0F, 0xF0, 0x00, 0x7F, 0xC0, 0x01, 0xFE, 0x00,
0x07, 0xF8, 0x00, 0x1F, 0xE0, 0x00, 0x7F, 0x80, 0x01, 0xFE, 0x00, 0x07,
0xF0, 0x00, 0x1F, 0x00, 0x00, 0x70, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x0E, 0x00, 0x00, 0xF8,
0x00, 0x0F, 0xE0, 0x00, 0x7F, 0x80, 0x01, 0xFE, 0x00, 0x07, 0xF8, 0x00,
0x1F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF0, 0x00, 0x3F,
0x00, 0x03, 0xF0, 0x00, 0xFF, 0x00, 0x3F, 0xE0, 0x0F, 0xF8, 0x01, 0xFE,
0x00, 0x7F, 0x80, 0x1F, 0xE0, 0x07, 0xF8, 0x00, 0xFE, 0x00, 0x0F, 0x80,
0x00, 0xE0, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x03, 0xFC, 0x7F, 0xE7, 0xFE,
0xF9, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xF0, 0x0F, 0x00, 0xF0, 0x1F,
0x01, 0xF0, 0x3E, 0x03, 0xE0, 0x7C, 0x07, 0xC0, 0xF8, 0x0F, 0x80, 0xF0,
0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
0x0F, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x0F, 0xFF,
0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xFF, 0xE0, 0x03, 0xFC,
0x03, 0xFC, 0x01, 0xFC, 0x00, 0x3F, 0x80, 0xFC, 0x00, 0x03, 0xF0, 0x7E,
0x1E, 0x78, 0x7C, 0x3F, 0x0F, 0xDE, 0x0F, 0x8F, 0x87, 0xFF, 0x81, 0xE7,
0xC1, 0xFF, 0xE0, 0x7D, 0xE0, 0x7C, 0xF8, 0x0F, 0x78, 0x1E, 0x1E, 0x03,
0xFE, 0x07, 0x87, 0x80, 0xFF, 0x01, 0xE1, 0xE0, 0x3F, 0xC0, 0x78, 0x78,
0x0F, 0xF0, 0x1E, 0x1E, 0x03, 0xFC, 0x07, 0x87, 0x81, 0xFF, 0x01, 0xE1,
0xE0, 0x7B, 0xC0, 0x78, 0x78, 0x3E, 0xF0, 0x1E, 0x1E, 0x0F, 0x1E, 0x07,
0x87, 0x87, 0x87, 0x81, 0xF3, 0xE7, 0xE1, 0xF0, 0x7F, 0xFF, 0xE0, 0x3C,
0x1F, 0xFF, 0xF0, 0x0F, 0x83, 0xFF, 0xF9, 0xE1, 0xF0, 0x78, 0xF0, 0xF0,
0x3E, 0x00, 0x00, 0xFC, 0x0F, 0xE0, 0x00, 0x7E, 0x01, 0xFF, 0x00, 0xFF,
0x00, 0x1F, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF,
0xC0, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x78, 0x00, 0x3F,
0x00, 0x0F, 0xC0, 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x7F, 0x00, 0x1F, 0xE0,
0x07, 0xF8, 0x01, 0xFE, 0x00, 0x7F, 0x80, 0x3F, 0xF0, 0x0F, 0x3C, 0x03,
0xCF, 0x00, 0xF3, 0xC0, 0x7C, 0xF8, 0x1F, 0x3E, 0x07, 0x87, 0x81, 0xE1,
0xE0, 0x78, 0x78, 0x3F, 0xFF, 0x0F, 0xFF, 0xC3, 0xFF, 0xF0, 0xFF, 0xFC,
0x78, 0x07, 0x9E, 0x01, 0xE7, 0x80, 0x79, 0xE0, 0x1E, 0x78, 0x07, 0xBC,
0x00, 0xFF, 0x00, 0x3C, 0xFF, 0xC3, 0xFF, 0x8F, 0xFF, 0x3F, 0xFE, 0xF0,
0x7F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC,
0x1F, 0xFF, 0xFB, 0xFF, 0xCF, 0xFF, 0x3F, 0xFE, 0xF0, 0x7B, 0xC0, 0xFF,
0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F,
0xC1, 0xFF, 0x07, 0xBF, 0xFE, 0xFF, 0xF3, 0xFF, 0x8F, 0xFC, 0x00, 0x0F,
0xC0, 0x7F, 0x83, 0xFF, 0x1F, 0xFE, 0xF8, 0x7B, 0xC0, 0xFF, 0x03, 0xFC,
0x0F, 0xF0, 0x3F, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F,
0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03,
0xC0, 0x0F, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x87, 0xDF, 0xFE,
0x3F, 0xF0, 0x7F, 0x80, 0xFC, 0x00, 0xFF, 0xC3, 0xFF, 0x8F, 0xFF, 0x3F,
0xFE, 0xF0, 0xFB, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF,
0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F,
0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F,
0xF0, 0x3F, 0xC0, 0xFF, 0x07, 0xBF, 0xFE, 0xFF, 0xF3, 0xFF, 0x8F, 0xF8,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xC0, 0x0F,
0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03,
0xFF, 0xEF, 0xFF, 0xBF, 0xFE, 0xFF, 0xFB, 0xC0, 0x0F, 0x00, 0x3C, 0x00,
0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00,
0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03,
0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xFF, 0xEF, 0xFF, 0xBF, 0xFE,
0xFF, 0xFB, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00,
0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0,
0x0F, 0x00, 0x00, 0x0F, 0xC0, 0x3F, 0xE0, 0xFF, 0xE3, 0xFF, 0xE7, 0x83,
0xFF, 0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x01, 0xE0, 0x03, 0xC0, 0x07,
0x80, 0x0F, 0x00, 0x1E, 0x3F, 0xFC, 0x7F, 0xF8, 0xFF, 0xF1, 0xFF, 0xE0,
0x3F, 0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFE, 0x03, 0xFC, 0x07, 0xF8, 0x0F,
0xF0, 0x1F, 0xF0, 0x7D, 0xE0, 0xF3, 0xFF, 0xE3, 0xFF, 0x83, 0xFE, 0x01,
0xF0, 0x00, 0xF0, 0x1F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFE,
0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80,
0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x3F,
0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFE, 0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0,
0x1F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFE, 0x03, 0xFC, 0x07,
0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0,
0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00,
0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E,
0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC4,
0x3C, 0xFF, 0xEF, 0xFE, 0x3F, 0xE0, 0x7C, 0x00, 0xF0, 0x0F, 0x78, 0x0F,
0x3C, 0x0F, 0x9E, 0x07, 0x8F, 0x07, 0xC7, 0x83, 0xC3, 0xC3, 0xE1, 0xE3,
0xE0, 0xF1, 0xF0, 0x79, 0xF0, 0x3C, 0xF0, 0x1E, 0xF8, 0x0F, 0xFC, 0x07,
0xFE, 0x03, 0xFF, 0x01, 0xFF, 0xC0, 0xFF, 0xE0, 0x7F, 0xF8, 0x3F, 0x3C,
0x1F, 0x1E, 0x0F, 0x8F, 0x87, 0x83, 0xC3, 0xC1, 0xF1, 0xE0, 0x78, 0xF0,
0x3C, 0x78, 0x0F, 0x3C, 0x07, 0x9E, 0x03, 0xEF, 0x00, 0xF7, 0x80, 0x7B,
0xC0, 0x1E, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0,
0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0,
0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C,
0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F,
0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xF0, 0x00, 0xFF,
0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F,
0xFC, 0x03, 0xFF, 0xE0, 0x7F, 0xFE, 0x07, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F,
0xFF, 0xF0, 0xFF, 0xF7, 0x9E, 0xFF, 0x79, 0xEF, 0xF7, 0xDE, 0xFF, 0x3F,
0xCF, 0xF3, 0xFC, 0xFF, 0x3F, 0xCF, 0xF1, 0xF8, 0xFF, 0x1F, 0x8F, 0xF1,
0xF8, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0x60, 0xFF,
0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F,
0xF0, 0x00, 0xF0, 0xF0, 0x1F, 0xE0, 0x3F, 0xE0, 0x7F, 0xC0, 0xFF, 0x81,
0xFF, 0x83, 0xFF, 0x07, 0xFF, 0x0F, 0xFE, 0x1F, 0xFC, 0x3F, 0xFC, 0x7F,
0xF8, 0xFF, 0xF1, 0xFE, 0xF3, 0xFD, 0xE7, 0xFB, 0xEF, 0xF3, 0xDF, 0xE7,
0xBF, 0xCF, 0xFF, 0x8F, 0xFF, 0x1F, 0xFE, 0x1F, 0xFC, 0x3F, 0xF8, 0x7F,
0xF0, 0x7F, 0xE0, 0xFF, 0xC1, 0xFF, 0x81, 0xFF, 0x03, 0xFE, 0x07, 0xFC,
0x07, 0x80, 0x07, 0xC0, 0x3F, 0xE0, 0xFF, 0xE3, 0xFF, 0xE7, 0xC7, 0xDF,
0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80,
0xFF, 0x01, 0xFE, 0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F,
0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFE, 0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0,
0x1F, 0xF0, 0x3D, 0xE1, 0xF3, 0xFF, 0xE3, 0xFF, 0x83, 0xFE, 0x01, 0xF0,
0x00, 0xFF, 0xC1, 0xFF, 0xE3, 0xFF, 0xE7, 0xFF, 0xEF, 0x03, 0xFE, 0x03,
0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80, 0xFF,
0x01, 0xFE, 0x07, 0xFF, 0xFF, 0x7F, 0xFC, 0xFF, 0xF1, 0xFF, 0x83, 0xC0,
0x07, 0x80, 0x0F, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x00, 0xF0, 0x01,
0xE0, 0x03, 0xC0, 0x07, 0x80, 0x0F, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0x00,
0x07, 0xC0, 0x0F, 0xF8, 0x0F, 0xFE, 0x0F, 0xFF, 0x87, 0xC7, 0xC7, 0xC1,
0xF3, 0xC0, 0x79, 0xE0, 0x3C, 0xF0, 0x1E, 0x78, 0x0F, 0x3C, 0x07, 0x9E,
0x03, 0xCF, 0x01, 0xE7, 0x80, 0xF3, 0xC0, 0x79, 0xE0, 0x3C, 0xF0, 0x1E,
0x78, 0x0F, 0x3C, 0x07, 0x9E, 0x03, 0xCF, 0x01, 0xE7, 0x80, 0xF3, 0xC1,
0x79, 0xE1, 0xFC, 0xF1, 0xFE, 0x7C, 0xFF, 0x1F, 0x1F, 0x8F, 0xFF, 0xE3,
0xFF, 0xF8, 0xFF, 0xF8, 0x1F, 0x80, 0xFF, 0xE0, 0xFF, 0xF0, 0xFF, 0xF8,
0xFF, 0xFC, 0xF0, 0x3E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E,
0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x3C, 0xFF, 0xFC, 0xFF, 0xF8,
0xFF, 0xF0, 0xFF, 0xE0, 0xF1, 0xE0, 0xF1, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0xF0, 0xF8, 0xF0, 0x78, 0xF0, 0x78, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x3C,
0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x0F, 0x07, 0xC0, 0x3F, 0xE0,
0xFF, 0xE3, 0xFF, 0xE7, 0xC3, 0xDF, 0x07, 0xFC, 0x07, 0xF8, 0x0F, 0xF0,
0x1F, 0xE0, 0x03, 0xC0, 0x07, 0xC0, 0x07, 0xF0, 0x0F, 0xF8, 0x0F, 0xFC,
0x0F, 0xFC, 0x07, 0xFC, 0x01, 0xF8, 0x00, 0xF8, 0x00, 0xF0, 0x01, 0xE0,
0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x3D, 0xE1, 0xF3, 0xFF,
0xE3, 0xFF, 0x83, 0xFE, 0x01, 0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E,
0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07,
0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x01,
0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00,
0x78, 0x00, 0xF0, 0x1F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFE,
0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80,
0xFF, 0x01, 0xFE, 0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F,
0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFE, 0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0,
0x1F, 0xE0, 0x3D, 0xE0, 0xF3, 0xFF, 0xE3, 0xFF, 0x83, 0xFE, 0x01, 0xF0,
0x00, 0xF0, 0x07, 0xF8, 0x03, 0xFC, 0x03, 0xCF, 0x01, 0xE7, 0x80, 0xF3,
0xC0, 0x79, 0xE0, 0x3C, 0xF0, 0x3C, 0x3C, 0x1E, 0x1E, 0x0F, 0x0F, 0x07,
0x87, 0x87, 0x83, 0xC3, 0xC0, 0xE1, 0xE0, 0x78, 0xF0, 0x3C, 0xF8, 0x1E,
0x78, 0x0F, 0x3C, 0x03, 0x9E, 0x01, 0xEF, 0x00, 0xFF, 0x00, 0x7F, 0x80,
0x3F, 0xC0, 0x0F, 0xE0, 0x07, 0xE0, 0x03, 0xF0, 0x01, 0xF8, 0x00, 0xFC,
0x00, 0x3E, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0xF0, 0x1E, 0x07, 0xF8, 0x0F,
0x03, 0xFC, 0x0F, 0x81, 0xEF, 0x07, 0xE1, 0xE7, 0x83, 0xF0, 0xF3, 0xC1,
0xF8, 0x79, 0xE0, 0xFC, 0x3C, 0xF0, 0xFE, 0x1E, 0x7C, 0x7F, 0x1F, 0x1E,
0x3F, 0x8F, 0x0F, 0x1F, 0xE7, 0x87, 0x8F, 0xF3, 0xC3, 0xCF, 0xF9, 0xE1,
0xF7, 0xFD, 0xF0, 0xFB, 0xCE, 0xF8, 0x3D, 0xE7, 0x7C, 0x1E, 0xF3, 0xBC,
0x0F, 0xF9, 0xDE, 0x07, 0xFC, 0xFF, 0x03, 0xFC, 0x7F, 0x81, 0xFE, 0x3F,
0xC0, 0xFF, 0x0F, 0xE0, 0x3F, 0x87, 0xE0, 0x1F, 0xC3, 0xF0, 0x0F, 0xC1,
0xF8, 0x07, 0xE0, 0xFC, 0x03, 0xF0, 0x7E, 0x01, 0xF8, 0x3F, 0x00, 0x7C,
0x0F, 0x00, 0x3C, 0x07, 0x80, 0x1E, 0x03, 0xC0, 0xF0, 0x0F, 0x78, 0x1E,
0x78, 0x1E, 0x7C, 0x3E, 0x3C, 0x3C, 0x3E, 0x7C, 0x1E, 0x78, 0x1F, 0xF8,
0x1F, 0xF8, 0x0F, 0xF0, 0x0F, 0xF0, 0x07, 0xE0, 0x07, 0xE0, 0x03, 0xC0,
0x03, 0xC0, 0x03, 0xC0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x0F, 0xF0,
0x0F, 0xF0, 0x1F, 0xF8, 0x1E, 0x78, 0x1E, 0x78, 0x3C, 0x3C, 0x3C, 0x3C,
0x3C, 0x3C, 0x78, 0x1E, 0x78, 0x1E, 0x78, 0x1E, 0xF0, 0x0F, 0xF0, 0x0F,
0x78, 0x1F, 0x78, 0x1E, 0x78, 0x1E, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x78, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0,
0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
0x7F, 0xFD, 0xFF, 0xF7, 0xFF, 0xDF, 0xFF, 0x00, 0x7C, 0x01, 0xE0, 0x07,
0x80, 0x3E, 0x00, 0xF0, 0x07, 0xC0, 0x1E, 0x00, 0x78, 0x03, 0xE0, 0x0F,
0x00, 0x7C, 0x01, 0xE0, 0x07, 0x80, 0x3E, 0x00, 0xF0, 0x07, 0xC0, 0x1E,
0x00, 0x78, 0x03, 0xE0, 0x0F, 0x00, 0x7C, 0x01, 0xE0, 0x07, 0x80, 0x3F,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x78, 0x3C,
0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x1E, 0x0F, 0x07, 0x83, 0xC1,
0xE0, 0xF0, 0x38, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x3C, 0x1E,
0x0F, 0x07, 0x83, 0xC1, 0xE0, 0x78, 0x3C, 0x1E, 0xFF, 0xFF, 0xFF, 0xFF,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xF8,
0x00, 0x0F, 0xE0, 0x00, 0xFF, 0x80, 0x07, 0xFC, 0x00, 0x7D, 0xF0, 0x03,
0xC7, 0x80, 0x3E, 0x3E, 0x03, 0xE0, 0xF8, 0x1E, 0x03, 0xC1, 0xF0, 0x1F,
0x0F, 0x00, 0x78, 0xF0, 0x01, 0xEF, 0x00, 0x07, 0x80, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0,
0x3C, 0x0F, 0x81, 0xFF, 0x1F, 0xFC, 0xFF, 0xEF, 0x8F, 0xF8, 0x3F, 0xC1,
0xE0, 0x0F, 0x00, 0x78, 0xFF, 0xCF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F,
0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFE, 0x3F, 0xFF, 0xF7, 0xFF, 0xBF,
0xFC, 0x79, 0xE0, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78,
0x03, 0xC0, 0x1E, 0x00, 0xF3, 0xE7, 0xBF, 0xBF, 0xFD, 0xFF, 0xFF, 0x8F,
0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF,
0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFE, 0x3F, 0xFF,
0xFF, 0xFF, 0x7B, 0xFB, 0xCF, 0x80, 0x0F, 0x81, 0xFF, 0x0F, 0xF8, 0xFF,
0xEF, 0x8F, 0xF8, 0x3F, 0xC1, 0xFE, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01,
0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x7F, 0x83, 0xFE,
0x3E, 0xFF, 0xE7, 0xFF, 0x1F, 0xF0, 0x3E, 0x00, 0x00, 0x78, 0x03, 0xC0,
0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x1E, 0x7B, 0xFB,
0xDF, 0xFF, 0xFF, 0xFF, 0x8F, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F,
0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0,
0x7F, 0x83, 0xFE, 0x3F, 0xFF, 0xF7, 0xFF, 0xBF, 0xBC, 0xF9, 0xE0, 0x0F,
0x81, 0xFF, 0x0F, 0xFC, 0xFF, 0xEF, 0x8F, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F,
0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xC0, 0x1E,
0x00, 0xF0, 0x7F, 0x83, 0xFE, 0x3E, 0xFF, 0xE7, 0xFE, 0x1F, 0xF0, 0x3E,
0x00, 0x07, 0x8F, 0xC7, 0xE7, 0xF3, 0xC1, 0xE0, 0xF0, 0x78, 0xFF, 0xFF,
0xFF, 0xFF, 0xF3, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83,
0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0,
0x1F, 0x3D, 0xFE, 0xF7, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xC0, 0xFF, 0x03,
0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0,
0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x87, 0xFF, 0xFF, 0x7F,
0xFD, 0xFE, 0xF1, 0xF3, 0xC0, 0x0F, 0x00, 0x3F, 0xC0, 0xFF, 0x03, 0xFE,
0x1F, 0x7F, 0xF8, 0xFF, 0xC1, 0xFE, 0x03, 0xF0, 0xF0, 0x07, 0x80, 0x3C,
0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF3, 0xC7, 0xBF,
0xBF, 0xFD, 0xFF, 0xFF, 0x8F, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F,
0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0,
0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xE0, 0xFF,
0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xF0, 0x1E, 0x3C, 0x78, 0xF0, 0x00, 0x00, 0x00, 0x1E, 0x3C,
0x78, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC7, 0x8F,
0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x79, 0xFF, 0xDF,
0xBE, 0x70, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00,
0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x1E, 0xF0, 0x3C, 0xF0, 0x78,
0xF0, 0xF8, 0xF0, 0xF0, 0xF1, 0xE0, 0xF3, 0xE0, 0xF3, 0xC0, 0xF7, 0x80,
0xFF, 0x80, 0xFF, 0xC0, 0xFF, 0xC0, 0xFF, 0xE0, 0xFF, 0xE0, 0xFD, 0xF0,
0xF8, 0xF0, 0xF0, 0xF8, 0xF0, 0x78, 0xF0, 0x7C, 0xF0, 0x3C, 0xF0, 0x1E,
0xF0, 0x1E, 0xF0, 0x0F, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1,
0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C,
0x78, 0xF1, 0xE3, 0xC7, 0xF7, 0xEF, 0xC7, 0x80, 0xF3, 0xC3, 0xE3, 0xDF,
0xDF, 0xCF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xF8, 0xFC, 0x7F, 0xC1, 0xE0,
0xFF, 0x07, 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0, 0xFF,
0x07, 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0, 0xFF, 0x07,
0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0, 0xFF, 0x07, 0x83,
0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0, 0xFF, 0x07, 0x83, 0xC0,
0xF3, 0xC7, 0xBF, 0xBF, 0xFD, 0xFF, 0xFF, 0x8F, 0xF8, 0x3F, 0xC1, 0xFE,
0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1,
0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F,
0xC1, 0xE0, 0x0F, 0x81, 0xFF, 0x1F, 0xFC, 0xFF, 0xEF, 0x8F, 0xF8, 0x3F,
0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8,
0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFE, 0x3E, 0xFF, 0xE7, 0xFE,
0x1F, 0xE0, 0x3E, 0x00, 0xF3, 0xC7, 0xBF, 0xBF, 0xFD, 0xFF, 0xFF, 0x8F,
0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF,
0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFE, 0x3F, 0xFF,
0xFF, 0xFF, 0x7B, 0xFB, 0xCF, 0x9E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01,
0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0x1E, 0x7B, 0xFB, 0xDF,
0xFF, 0xFF, 0xFF, 0x8F, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83,
0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F,
0x83, 0xFE, 0x3F, 0xFF, 0xF7, 0xFF, 0xBF, 0xBC, 0x79, 0xE0, 0x0F, 0x00,
0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F,
0xF1, 0xFD, 0xFF, 0xFF, 0xFF, 0xFC, 0x3E, 0x0F, 0x83, 0xC0, 0xF0, 0x3C,
0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03,
0xC0, 0xF0, 0x3C, 0x0F, 0x00, 0x0F, 0x81, 0xFF, 0x1F, 0xFC, 0xFF, 0xEF,
0x8F, 0xF8, 0x3F, 0xC0, 0x1E, 0x00, 0xF8, 0x07, 0xF8, 0x1F, 0xF0, 0x7F,
0xC1, 0xFF, 0x01, 0xF8, 0x03, 0xE0, 0x0F, 0xF0, 0x7F, 0x83, 0xFE, 0x3E,
0xFF, 0xE7, 0xFE, 0x1F, 0xF0, 0x3E, 0x00, 0x3C, 0x1E, 0x0F, 0x07, 0x83,
0xC1, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0x07, 0x83, 0xC1, 0xE0, 0xF0,
0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1F,
0xC7, 0xE3, 0xF0, 0x78, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07,
0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF,
0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFE, 0x3F, 0xFF,
0xF7, 0xFF, 0xBF, 0xFC, 0x79, 0xE0, 0xF0, 0x0F, 0xF0, 0x0F, 0x78, 0x1E,
0x78, 0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
0x3E, 0x7C, 0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x78, 0x0F, 0xF0, 0x0F, 0xF0,
0x0F, 0xF0, 0x0F, 0xF0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0,
0x03, 0xC0, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0xF0, 0x3C, 0x0F, 0x78, 0x7C,
0x1E, 0x78, 0x7C, 0x1E, 0x78, 0x7C, 0x1E, 0x78, 0x7E, 0x1E, 0x38, 0x7E,
0x3C, 0x3C, 0xFE, 0x3C, 0x3C, 0xFE, 0x3C, 0x3C, 0xFF, 0x3C, 0x1C, 0xFF,
0x38, 0x1E, 0xEF, 0x78, 0x1F, 0xEF, 0x78, 0x1F, 0xE7, 0x78, 0x1F, 0xE7,
0xF8, 0x0F, 0xE7, 0xF0, 0x0F, 0xE7, 0xF0, 0x0F, 0xC7, 0xF0, 0x0F, 0xC3,
0xF0, 0x07, 0xC3, 0xE0, 0x07, 0xC3, 0xE0, 0x07, 0xC3, 0xE0, 0x07, 0xC3,
0xE0, 0x78, 0x1E, 0x78, 0x78, 0xF0, 0xF0, 0xE3, 0xC1, 0xE7, 0x83, 0xCF,
0x03, 0xFC, 0x07, 0xF8, 0x07, 0xE0, 0x0F, 0xC0, 0x0F, 0x00, 0x1E, 0x00,
0x7E, 0x00, 0xFC, 0x03, 0xF8, 0x07, 0xF8, 0x1F, 0xF0, 0x3C, 0xF0, 0xF9,
0xE1, 0xE3, 0xE7, 0x83, 0xCF, 0x07, 0xBC, 0x07, 0x80, 0xF0, 0x0F, 0xF0,
0x0F, 0x78, 0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x3C, 0x3E, 0x3C, 0x3C, 0x3C,
0x3C, 0x3C, 0x3C, 0x1E, 0x7C, 0x1E, 0x78, 0x1E, 0x78, 0x0F, 0xF8, 0x0F,
0xF8, 0x0F, 0xF0, 0x0F, 0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x07, 0xE0, 0x03,
0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x07,
0xC0, 0x07, 0x80, 0x0F, 0x80, 0x7F, 0x80, 0x7F, 0x00, 0x7E, 0x00, 0x78,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0x1E, 0x01, 0xC0,
0x3C, 0x03, 0x80, 0x78, 0x07, 0x00, 0xF0, 0x0E, 0x01, 0xE0, 0x1C, 0x03,
0xC0, 0x38, 0x07, 0x80, 0x70, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
0x03, 0xE1, 0xFC, 0x3F, 0x8F, 0xF1, 0xF0, 0x3C, 0x07, 0x80, 0xF0, 0x1E,
0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x81, 0xF0, 0x7E, 0x1F,
0x83, 0xE0, 0x7C, 0x0F, 0xC0, 0xF8, 0x0F, 0x80, 0xF0, 0x1E, 0x03, 0xC0,
0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78,
0x0F, 0x81, 0xFE, 0x1F, 0xC3, 0xF8, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xF8, 0x1F, 0xC3, 0xF8, 0x7F, 0x81, 0xF0, 0x1E, 0x03, 0xC0,
0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78,
0x0F, 0x80, 0xF8, 0x1F, 0x81, 0xF0, 0x3E, 0x0F, 0xC3, 0xF0, 0x7C, 0x0F,
0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01,
0xE0, 0x3C, 0x0F, 0x8F, 0xF1, 0xFC, 0x3F, 0x87, 0xC0, 0x07, 0x80, 0x08,
0x3F, 0xC0, 0x1C, 0xFF, 0xE0, 0x79, 0xFF, 0xF1, 0xE7, 0x8F, 0xFF, 0xCE,
0x07, 0xFF, 0x1C, 0x03, 0xFC, 0x10, 0x01, 0xF0 };
const GFXglyph din1451e24pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 8, 0, 0 }, // 0x20 ' '
{ 1, 6, 31, 10, 2, -30 }, // 0x21 '!'
{ 25, 13, 12, 17, 2, -30 }, // 0x22 '"'
{ 45, 27, 23, 24, -2, -26 }, // 0x23 '#'
{ 123, 15, 37, 24, 3, -33 }, // 0x24 '$'
{ 193, 23, 31, 26, 1, -30 }, // 0x25 '%'
{ 283, 20, 31, 23, 2, -30 }, // 0x26 '&'
{ 361, 5, 12, 9, 2, -30 }, // 0x27 '''
{ 369, 8, 41, 12, 2, -38 }, // 0x28 '('
{ 410, 8, 40, 11, 2, -37 }, // 0x29 ')'
{ 450, 12, 11, 16, 2, -30 }, // 0x2A '*'
{ 467, 23, 21, 24, 1, -26 }, // 0x2B '+'
{ 528, 4, 7, 9, 2, -3 }, // 0x2C ','
{ 532, 14, 5, 18, 2, -14 }, // 0x2D '-'
{ 541, 4, 4, 9, 2, -3 }, // 0x2E '.'
{ 543, 9, 31, 15, 3, -30 }, // 0x2F '/'
{ 578, 13, 32, 15, 1, -31 }, // 0x30 '0'
{ 630, 9, 31, 17, 2, -30 }, // 0x31 '1'
{ 665, 13, 31, 17, 1, -30 }, // 0x32 '2'
{ 716, 13, 31, 17, 2, -30 }, // 0x33 '3'
{ 767, 16, 31, 17, 1, -30 }, // 0x34 '4'
{ 829, 13, 31, 17, 1, -30 }, // 0x35 '5'
{ 880, 13, 31, 17, 1, -30 }, // 0x36 '6'
{ 931, 13, 31, 17, 1, -30 }, // 0x37 '7'
{ 982, 13, 31, 17, 1, -30 }, // 0x38 '8'
{ 1033, 13, 31, 17, 1, -30 }, // 0x39 '9'
{ 1084, 4, 15, 15, 5, -18 }, // 0x3A ':'
{ 1092, 4, 16, 16, 5, -12 }, // 0x3B ';'
{ 1100, 20, 24, 24, 1, -27 }, // 0x3C '<'
{ 1160, 22, 8, 24, 1, -20 }, // 0x3D '='
{ 1182, 20, 24, 24, 1, -27 }, // 0x3E '>'
{ 1242, 12, 31, 18, 2, -30 }, // 0x3F '?'
{ 1289, 34, 34, 38, 2, -31 }, // 0x40 '@'
{ 1434, 18, 31, 18, 0, -30 }, // 0x41 'A'
{ 1504, 14, 31, 19, 2, -30 }, // 0x42 'B'
{ 1559, 14, 31, 18, 2, -30 }, // 0x43 'C'
{ 1614, 14, 31, 19, 2, -30 }, // 0x44 'D'
{ 1669, 14, 31, 18, 2, -30 }, // 0x45 'E'
{ 1724, 14, 31, 17, 2, -30 }, // 0x46 'F'
{ 1779, 15, 31, 19, 2, -30 }, // 0x47 'G'
{ 1838, 15, 31, 19, 2, -30 }, // 0x48 'H'
{ 1897, 4, 31, 9, 2, -30 }, // 0x49 'I'
{ 1913, 13, 31, 15, 0, -30 }, // 0x4A 'J'
{ 1964, 17, 31, 20, 2, -30 }, // 0x4B 'K'
{ 2030, 14, 31, 17, 2, -30 }, // 0x4C 'L'
{ 2085, 20, 31, 25, 2, -30 }, // 0x4D 'M'
{ 2163, 15, 31, 21, 4, -30 }, // 0x4E 'N'
{ 2222, 15, 31, 19, 2, -30 }, // 0x4F 'O'
{ 2281, 15, 31, 18, 2, -30 }, // 0x50 'P'
{ 2340, 17, 31, 19, 2, -30 }, // 0x51 'Q'
{ 2406, 16, 31, 19, 2, -30 }, // 0x52 'R'
{ 2468, 15, 31, 18, 1, -30 }, // 0x53 'S'
{ 2527, 14, 31, 17, 1, -30 }, // 0x54 'T'
{ 2582, 15, 31, 19, 2, -30 }, // 0x55 'U'
{ 2641, 17, 31, 17, 0, -30 }, // 0x56 'V'
{ 2707, 25, 31, 25, 0, -30 }, // 0x57 'W'
{ 2804, 16, 31, 18, 0, -30 }, // 0x58 'X'
{ 2866, 16, 31, 16, 0, -30 }, // 0x59 'Y'
{ 2928, 14, 31, 16, 0, -30 }, // 0x5A 'Z'
{ 2983, 8, 38, 13, 2, -30 }, // 0x5B '['
{ 3021, 9, 31, 15, 3, -30 }, // 0x5C '\'
{ 3056, 8, 38, 13, 2, -30 }, // 0x5D ']'
{ 3094, 21, 13, 24, 1, -30 }, // 0x5E '^'
{ 3129, 24, 3, 24, 0, 4 }, // 0x5F '_'
{ 3138, 9, 6, 24, 5, -31 }, // 0x60 '`'
{ 3145, 13, 23, 17, 1, -22 }, // 0x61 'a'
{ 3183, 13, 31, 17, 2, -30 }, // 0x62 'b'
{ 3234, 13, 23, 16, 1, -22 }, // 0x63 'c'
{ 3272, 13, 31, 17, 2, -30 }, // 0x64 'd'
{ 3323, 13, 23, 17, 1, -22 }, // 0x65 'e'
{ 3361, 9, 31, 11, 1, -30 }, // 0x66 'f'
{ 3396, 14, 32, 17, 1, -22 }, // 0x67 'g'
{ 3452, 13, 31, 17, 2, -30 }, // 0x68 'h'
{ 3503, 4, 31, 8, 2, -30 }, // 0x69 'i'
{ 3519, 7, 40, 9, 0, -30 }, // 0x6A 'j'
{ 3554, 16, 31, 18, 2, -30 }, // 0x6B 'k'
{ 3616, 7, 31, 10, 2, -30 }, // 0x6C 'l'
{ 3644, 22, 23, 26, 2, -22 }, // 0x6D 'm'
{ 3708, 13, 23, 17, 2, -22 }, // 0x6E 'n'
{ 3746, 13, 23, 17, 1, -22 }, // 0x6F 'o'
{ 3784, 13, 32, 17, 2, -22 }, // 0x70 'p'
{ 3836, 13, 32, 17, 2, -22 }, // 0x71 'q'
{ 3888, 10, 23, 13, 2, -22 }, // 0x72 'r'
{ 3917, 13, 23, 16, 1, -22 }, // 0x73 's'
{ 3955, 9, 29, 11, 0, -28 }, // 0x74 't'
{ 3988, 13, 23, 17, 2, -22 }, // 0x75 'u'
{ 4026, 16, 23, 15, 0, -22 }, // 0x76 'v'
{ 4072, 24, 23, 24, 0, -22 }, // 0x77 'w'
{ 4141, 15, 23, 15, 0, -22 }, // 0x78 'x'
{ 4185, 16, 32, 16, 0, -22 }, // 0x79 'y'
{ 4249, 12, 23, 14, 1, -22 }, // 0x7A 'z'
{ 4284, 11, 40, 15, 1, -30 }, // 0x7B '{'
{ 4339, 4, 38, 10, 2, -30 }, // 0x7C '|'
{ 4358, 11, 40, 15, 2, -30 }, // 0x7D '}'
{ 4413, 23, 8, 31, 4, -20 } }; // 0x7E '~'
const GFXfont din1451e24pt7b PROGMEM = {
(uint8_t *)din1451e24pt7bBitmaps,
(GFXglyph *)din1451e24pt7bGlyphs,
0x20, 0x7E, 53 };
// Approx. 5108 bytes

View file

@ -0,0 +1,206 @@
// Display Library example for SPI e-paper panels from Dalian Good Display and boards from Waveshare.
// Requires HW SPI and Adafruit_GFX. Caution: the e-paper panels require 3.3V supply AND data lines!
//
// Display Library based on Demo Example from Good Display: http://www.e-paper-display.com/download_list/downloadcategoryid=34&isMode=false.html
//
// Author: Jean-Marc Zingg
//
// Version: see library.properties
//
// Library: https://github.com/ZinggJM/GxEPD2
// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
// Good Display ePaper for Arduino: https://forum.arduino.cc/index.php?topic=436411.0
// select the display class (only one), matching the kind of display panel
#define GxEPD2_DISPLAY_CLASS GxEPD2_BW
//#define GxEPD2_DISPLAY_CLASS GxEPD2_3C
//#define GxEPD2_DISPLAY_CLASS GxEPD2_7C
// select the display driver class (only one) for your panel
//#define GxEPD2_DRIVER_CLASS GxEPD2_102 // GxEPD2_102 80x128, UC8175
//#define GxEPD2_DRIVER_CLASS GxEPD2_154 // GDEP015OC1 200x200, IL3829, no longer available
//#define GxEPD2_DRIVER_CLASS GxEPD2_154_D67 // GDEH0154D67 200x200, SSD1681
//#define GxEPD2_DRIVER_CLASS GxEPD2_154_T8 // GDEW0154T8 152x152, UC8151 (IL0373)
//#define GxEPD2_DRIVER_CLASS GxEPD2_154_M09 // GDEW0154M09 200x200, JD79653A
//#define GxEPD2_DRIVER_CLASS GxEPD2_154_M10 // GDEW0154M10 152x152, UC8151D
//#define GxEPD2_DRIVER_CLASS GxEPD2_213 // GDE0213B1 128x250, IL3895, phased out
//#define GxEPD2_DRIVER_CLASS GxEPD2_213_B72 // GDEH0213B72 128x250, SSD1675A (IL3897)
//#define GxEPD2_DRIVER_CLASS GxEPD2_213_B73 // GDEH0213B73 128x250, SSD1675B
//#define GxEPD2_DRIVER_CLASS GxEPD2_213_B74 // GDEM0213B74 128x250, SSD1680
//#define GxEPD2_DRIVER_CLASS GxEPD2_213_flex // GDEW0213I5F 104x212, UC8151 (IL0373)
//#define GxEPD2_DRIVER_CLASS GxEPD2_213_M21 // GDEW0213M21 104x212, UC8151 (IL0373)
//#define GxEPD2_DRIVER_CLASS GxEPD2_213_T5D // GDEW0213T5D 104x212, UC8151D
//#define GxEPD2_DRIVER_CLASS GxEPD2_290 // GDEH029A1 128x296, SSD1608 (IL3820)
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_T5 // GDEW029T5 128x296, UC8151 (IL0373)
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_T5D // GDEW029T5D 128x296, UC8151D
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_T94 // GDEM029T94 128x296, SSD1680
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_T94_V2 // GDEM029T94 128x296, SSD1680, Waveshare 2.9" V2 variant
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_M06 // GDEW029M06 128x296, UC8151 (IL0373)
//#define GxEPD2_DRIVER_CLASS GxEPD2_260 // GDEW026T0 152x296, UC8151 (IL0373)
//#define GxEPD2_DRIVER_CLASS GxEPD2_260_M01 // GDEW026M01 152x296, UC8151 (IL0373)
//#define GxEPD2_DRIVER_CLASS GxEPD2_270 // GDEW027W3 176x264, EK79652 (IL91874)
//#define GxEPD2_DRIVER_CLASS GxEPD2_371 // GDEW0371W7 240x416, UC8171 (IL0324)
#define GxEPD2_DRIVER_CLASS GxEPD2_420 // GDEW042T2 400x300, UC8176 (IL0398)
//#define GxEPD2_DRIVER_CLASS GxEPD2_420_M01 // GDEW042M01 400x300, UC8176 (IL0398)
//#define GxEPD2_DRIVER_CLASS GxEPD2_583 // GDEW0583T7 600x448, UC8179 (IL0371)
//#define GxEPD2_DRIVER_CLASS GxEPD2_583_T8 // GDEW0583T8 648x480, GD7965
//#define GxEPD2_DRIVER_CLASS GxEPD2_750 // GDEW075T8 640x384, UC8179 (IL0371)
//#define GxEPD2_DRIVER_CLASS GxEPD2_750_T7 // GDEW075T7 800x480, GD7965
//#define GxEPD2_DRIVER_CLASS GxEPD2_1160_T91 // GDEH116T91 960x640, SSD1677
// 3-color e-papers
//#define GxEPD2_DRIVER_CLASS GxEPD2_154c // GDEW0154Z04 200x200, IL0376F, no longer available
//#define GxEPD2_DRIVER_CLASS GxEPD2_154_Z90c // GDEH0154Z90 200x200, SSD1682
//#define GxEPD2_DRIVER_CLASS GxEPD2_213c // GDEW0213Z16 104x212, UC8151 (IL0373)
//#define GxEPD2_DRIVER_CLASS GxEPD2_213_Z19c // GDEW0213Z19 104x212, UC8151D
//#define GxEPD2_DRIVER_CLASS GxEPD2_290c // GDEW029Z10 128x296, UC8151 (IL0373)
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_Z13c // GDEH029Z13 128x296, UC8151D
//#define GxEPD2_DRIVER_CLASS GxEPD2_290_C90c // GDEM029C90 128x296, SSD1680
//#define GxEPD2_DRIVER_CLASS GxEPD2_270c // GDEW027C44 176x264, IL91874
//#define GxEPD2_DRIVER_CLASS GxEPD2_420c // GDEW042Z15 400x300, UC8176 (IL0398)
//#define GxEPD2_DRIVER_CLASS GxEPD2_583c // GDEW0583Z21 600x448, UC8179 (IL0371)
//#define GxEPD2_DRIVER_CLASS GxEPD2_750c // GDEW075Z09 640x384, UC8179 (IL0371)
//#define GxEPD2_DRIVER_CLASS GxEPD2_750c_Z08 // GDEW075Z08 800x480, GD7965
//#define GxEPD2_DRIVER_CLASS GxEPD2_750c_Z90 // GDEH075Z90 880x528, SSD1677
//#define GxEPD2_DRIVER_CLASS GxEPD2_1248 // GDEW1248T3 1303x984, UC8179
// 7-color e-paper
//#define GxEPD2_DRIVER_CLASS GxEPD2_565c // Waveshare 5.65" 7-color (3C graphics)
// grey levels parallel IF e-papers on Waveshare e-Paper IT8951 Driver HAT
//#define GxEPD2_DRIVER_CLASS GxEPD2_it60 // ED060SCT 800x600
//#define GxEPD2_DRIVER_CLASS GxEPD2_it60_1448x1072 // ED060KC1 1448x1072
//#define GxEPD2_DRIVER_CLASS GxEPD2_it78_1872x1404 // ED078KC2 1872x1404
// SS is usually used for CS. define here for easy change
#ifndef EPD_CS
#define EPD_CS SS
#endif
#if defined(GxEPD2_DISPLAY_CLASS) && defined(GxEPD2_DRIVER_CLASS)
// somehow there should be an easier way to do this
#define GxEPD2_BW_IS_GxEPD2_BW true
#define GxEPD2_3C_IS_GxEPD2_3C true
#define GxEPD2_7C_IS_GxEPD2_7C true
#define GxEPD2_1248_IS_GxEPD2_1248 true
#define IS_GxEPD(c, x) (c##x)
#define IS_GxEPD2_BW(x) IS_GxEPD(GxEPD2_BW_IS_, x)
#define IS_GxEPD2_3C(x) IS_GxEPD(GxEPD2_3C_IS_, x)
#define IS_GxEPD2_7C(x) IS_GxEPD(GxEPD2_7C_IS_, x)
#define IS_GxEPD2_1248(x) IS_GxEPD(GxEPD2_1248_IS_, x)
#include "GxEPD2_selection_check.h"
#if defined (ESP8266)
#define MAX_DISPLAY_BUFFER_SIZE (81920ul-34000ul-15000ul) // ~34000 base use, ~20000 application use
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
#endif
#endif
#if defined(ESP32)
#define MAX_DISPLAY_BUFFER_SIZE 65536ul // e.g.
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
#endif
// adapt the constructor parameters to your wiring
#if !IS_GxEPD2_1248(GxEPD2_DRIVER_CLASS)
#if defined(ARDUINO_LOLIN_D32_PRO)
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=5*/ EPD_CS, /*DC=*/ 0, /*RST=*/ 2, /*BUSY=*/ 15));
#elif defined(ARDUINO_ESP32_DEV) // e.g. TTGO T8 ESP32-WROVER
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=5*/ EPD_CS, /*DC=*/ 2, /*RST=*/ 0, /*BUSY=*/ 4));
#else
// moved to epaper.c because of multiple definitions when in header
//GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
#endif
#else // GxEPD2_1248
// Waveshare 12.48 b/w SPI display board and frame or Good Display 12.48 b/w panel GDEW1248T3
// general constructor for use with all parameters, e.g. for Waveshare ESP32 driver board mounted on connection board
GxEPD2_BW < GxEPD2_1248, GxEPD2_1248::HEIGHT / 4 > display(GxEPD2_1248(/*sck=*/ 13, /*miso=*/ 12, /*mosi=*/ 14,
/*cs_m1=*/ 23, /*cs_s1=*/ 22, /*cs_m2=*/ 16, /*cs_s2=*/ 19,
/*dc1=*/ 25, /*dc2=*/ 17, /*rst1=*/ 33, /*rst2=*/ 5,
/*busy_m1=*/ 32, /*busy_s1=*/ 26, /*busy_m2=*/ 18, /*busy_s2=*/ 4));
#endif
#endif
// can't use package "STMF1 Boards (STM32Duino.com)" (Roger Clark) anymore with Adafruit_GFX, use "STM32 Boards (selected from submenu)" (STMicroelectronics)
#if defined(ARDUINO_ARCH_STM32)
#define MAX_DISPLAY_BUFFER_SIZE 15000ul // ~15k is a good compromise
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
#endif
// adapt the constructor parameters to your wiring
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=4*/ EPD_CS, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1));
#endif
#if defined(__AVR)
#if defined (ARDUINO_AVR_MEGA2560) // Note: SS is on 53 on MEGA
#define MAX_DISPLAY_BUFFER_SIZE 5000 // e.g. full height for 200x200
#else // Note: SS is on 10 on UNO, NANO
#define MAX_DISPLAY_BUFFER_SIZE 800 //
#endif
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
#endif
// adapt the constructor parameters to your wiring
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/ EPD_CS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
#endif
#if defined(ARDUINO_ARCH_SAM)
#define MAX_DISPLAY_BUFFER_SIZE 32768ul // e.g., up to 96k
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
#endif
// adapt the constructor parameters to your wiring
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=77*/ EPD_CS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
#endif
#if defined(ARDUINO_ARCH_SAMD)
#define MAX_DISPLAY_BUFFER_SIZE 15000ul // ~15k is a good compromise
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
#endif
// adapt the constructor parameters to your wiring
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=4*/ 4, /*DC=*/ 7, /*RST=*/ 6, /*BUSY=*/ 5));
//GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=4*/ 4, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1)); // my Seed XIOA0
//GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=4*/ 3, /*DC=*/ 2, /*RST=*/ 1, /*BUSY=*/ 0)); // my other Seed XIOA0
#endif
#if defined(ARDUINO_ARCH_RP2040)
#define MAX_DISPLAY_BUFFER_SIZE 131072ul // e.g. half of available ram
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
#endif
// adapt the constructor parameters to your wiring
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=4*/ EPD_CS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
#endif
#endif

View file

@ -0,0 +1,75 @@
// Display Library example for SPI e-paper panels from Dalian Good Display and boards from Waveshare.
// Requires HW SPI and Adafruit_GFX. Caution: the e-paper panels require 3.3V supply AND data lines!
//
// Display Library based on Demo Example from Good Display: http://www.e-paper-display.com/download_list/downloadcategoryid=34&isMode=false.html
//
// Author: Jean-Marc Zingg
//
// Version: see library.properties
//
// Library: https://github.com/ZinggJM/GxEPD2
// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
// Good Display ePaper for Arduino: https://forum.arduino.cc/index.php?topic=436411.0
#define GxEPD2_102_IS_BW true
#define GxEPD2_154_IS_BW true
#define GxEPD2_154_D67_IS_BW true
#define GxEPD2_154_T8_IS_BW true
#define GxEPD2_154_M09_IS_BW true
#define GxEPD2_154_M10_IS_BW true
#define GxEPD2_213_IS_BW true
#define GxEPD2_213_B72_IS_BW true
#define GxEPD2_213_B73_IS_BW true
#define GxEPD2_213_B74_IS_BW true
#define GxEPD2_213_flex_IS_BW true
#define GxEPD2_213_M21_IS_BW true
#define GxEPD2_213_T5D_IS_BW true
#define GxEPD2_290_IS_BW true
#define GxEPD2_290_T5_IS_BW true
#define GxEPD2_290_T5D_IS_BW true
#define GxEPD2_290_T94_IS_BW true
#define GxEPD2_290_T94_V2_IS_BW true
#define GxEPD2_290_M06_IS_BW true
#define GxEPD2_260_IS_BW true
#define GxEPD2_260_M01_IS_BW true
#define GxEPD2_270_IS_BW true
#define GxEPD2_371_IS_BW true
#define GxEPD2_420_IS_BW true
#define GxEPD2_420_M01_IS_BW true
#define GxEPD2_583_IS_BW true
#define GxEPD2_583_T8_IS_BW true
#define GxEPD2_750_IS_BW true
#define GxEPD2_750_T7_IS_BW true
#define GxEPD2_1160_T91_IS_BW true
// 3-color e-papers
#define GxEPD2_154c_IS_3C true
#define GxEPD2_154_Z90c_IS_3C true
#define GxEPD2_213c_IS_3C true
#define GxEPD2_213_Z19c_IS_3C true
#define GxEPD2_290c_IS_3C true
#define GxEPD2_290_Z13c_IS_3C true
#define GxEPD2_290_C90c_IS_3C true
#define GxEPD2_270c_IS_3C true
#define GxEPD2_420c_IS_3C true
#define GxEPD2_583c_IS_3C true
#define GxEPD2_750c_IS_3C true
#define GxEPD2_750c_Z08_IS_3C true
#define GxEPD2_750c_Z90_IS_3C true
#define GxEPD2_1248_IS_3C true
// 7-color e-paper
#define GxEPD2_565c_IS_7C true
#if defined(GxEPD2_DISPLAY_CLASS) && defined(GxEPD2_DRIVER_CLASS)
#define IS_GxEPD2_DRIVER(c, x) (c##x)
#define IS_GxEPD2_DRIVER_BW(x) IS_GxEPD2_DRIVER(x, _IS_BW)
#define IS_GxEPD2_DRIVER_3C(x) IS_GxEPD2_DRIVER(x, _IS_3C)
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS) && IS_GxEPD2_DRIVER_3C(GxEPD2_DRIVER_CLASS)
#error "GxEPD2_BW used with 3-color driver class"
#endif
#if IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS) && IS_GxEPD2_DRIVER_BW(GxEPD2_DRIVER_CLASS)
#error "GxEPD2_3C used with b/w driver class"
#endif
#endif

39
include/README Normal file
View file

@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

16
include/epaper.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef EPAPER_H
#define EPAPER_H
#include <GxEPD2_BW.h>
#include "GxEPD2_display_selection_new_style.h"
typedef void (*epaper_callback)(GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> *display);
void epaper_init(void);
void epaper_test(void);
//void epaper_plot(uint16_t x, uint16_t y, uint16_t w, uint16_t h, timeseries_t *timeseries, uint32_t time_tick_interval);
void epaper_draw_and_hibernate(epaper_callback cb);
#endif

46
lib/README Normal file
View file

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

26
platformio.ini Normal file
View file

@ -0,0 +1,26 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp-wroom32]
platform = espressif32
board = nodemcu-32s
framework = arduino
monitor_speed = 115200
lib_deps =
zinggjm/GxEPD2@^1.5.7
adafruit/Adafruit SCD30@^1.0.11
SPI
Wire
#esp32_https_server
build_flags = -std=c++11

293
src/epaper.cpp Normal file
View file

@ -0,0 +1,293 @@
#include <algorithm>
#include <Adafruit_GFX.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Font_din1451e.h>
#include <Fonts/Org_01.h>
#include "epaper.h"
static GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)>
display(GxEPD2_DRIVER_CLASS(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));
void epaper_init(void)
{
display.init();
}
void epaper_test(void)
{
display.setRotation(0);
display.setFont(&FreeMonoBold9pt7b);
display.setTextColor(GxEPD_BLACK);
int16_t tbx, tby; uint16_t tbw, tbh;
display.getTextBounds("Hello World!", 0, 0, &tbx, &tby, &tbw, &tbh);
// center the bounding box by transposition of the origin:
uint16_t x = ((display.width() - tbw) / 2) - tbx;
uint16_t y = ((display.height() - tbh) / 2) - tby;
display.setFullWindow();
display.firstPage();
do
{
display.fillScreen(GxEPD_WHITE);
display.setCursor(x, y);
display.print("Hello World!");
for(int i = -1; i <= 1; i++) {
display.drawCircle(display.width()/2, display.height()/2, tbw*15/10/2+i, GxEPD_RED);
}
}
while (display.nextPage());
Serial.println(F("Init done. Display going to powersave…"));
display.hibernate();
}
void epaper_draw_and_hibernate(epaper_callback cb)
{
display.setRotation(0);
display.setFullWindow();
display.firstPage();
do {
cb(&display);
} while(display.nextPage());
display.hibernate();
}
#if 0
// find minimum and maximum values in a vector. NaN is ignored.
template<typename T>
void minmax(const std::vector<T> &vec, T *min, T *max)
{
bool first = true;
// fallback values: will be used if the vector is empty or only consists of NaNs
*min = 0;
*max = 1;
for(auto &v: vec) {
if(isnan(v)) {
continue;
}
if(first) {
*min = *max = v;
first = false;
continue;
}
if(v < *min) {
*min = v;
}
if(v > *max) {
*max = v;
}
}
}
void epaper_plot(uint16_t x, uint16_t y, uint16_t w, uint16_t h, timeseries_t *timeseries, uint32_t time_tick_interval)
{
char s[32];
uint32_t trange = timeseries->tend - timeseries->tstart;
uint32_t tstep = timeseries->interval;
if(trange == 0) {
trange = 3600;
}
float vmin, vmax;
minmax(timeseries->data, &vmin, &vmax);
float vrange = vmax - vmin;
Serial.print(F("Value range: "));
Serial.print(vrange);
Serial.print(F(" Min: "));
Serial.print(vmin);
Serial.print(F(" Max: "));
Serial.println(vmax);
if(vrange == 0.0f) {
vrange = 1.0f;
}
// add some margin
vmax += vrange * 0.05f;
vmin -= vrange * 0.05f;
vrange = vmax - vmin;
bool firstpoint = true;
uint16_t last_x;
uint16_t last_y;
// set font for axis labels
display.setFont(&Org_01);
display.setTextColor(GxEPD_BLACK);
int16_t tbx, tby; uint16_t tbw, tbh;
display.getTextBounds("20:48", 0, 0, &tbx, &tby, &tbw, &tbh);
uint16_t label_height = tbh;
// actual graph area
uint16_t plot_x = x + 150;
uint16_t plot_y = y;
uint16_t plot_w = w - 150;
uint16_t plot_h = h - label_height - 5;
// determine vertical tick interval
uint16_t max_vert_tick_count = plot_h / (label_height + 5);
float min_vert_tick_step = vrange / (float)max_vert_tick_count;
static const PROGMEM float TEST_FACTORS[] = {1.0f, 0.5f, 0.25f, 0.1f};
float scale = 1e3f;
float accepted_scale = scale;
bool scale_found = false;
while((scale > 1e-3f) && !scale_found) {
float tmp_scale;
for(auto factor: TEST_FACTORS) {
tmp_scale = scale * factor;
if(tmp_scale < min_vert_tick_step) {
scale_found = true;
break;
}
accepted_scale = tmp_scale;
}
scale = tmp_scale;
}
/* Start drawing */
display.drawRect(plot_x, plot_y, plot_w, plot_h, GxEPD_BLACK);
// draw vertical grid lines
for(uint64_t reltime = ((timeseries->tstart / time_tick_interval) + 1) * time_tick_interval - timeseries->tstart;
reltime < trange;
reltime += time_tick_interval) {
uint16_t px = plot_x + plot_w * reltime / trange;
uint16_t py = plot_y;
uint16_t ph = plot_h + 2;
display.drawFastVLine(px, py, ph, GxEPD_BLACK);
time_t t = reltime + timeseries->tstart;
tm *gmt = gmtime(&t);
if(t % 86400 == 0) {
strftime(s, sizeof(s), "%d.%m.", gmt);
} else {
strftime(s, sizeof(s), "%H:%M", gmt);
}
display.getTextBounds(s, 0, 0, &tbx, &tby, &tbw, &tbh);
display.setCursor(px - tbw/2, y+h + tby);
display.print(s);
}
// draw horizontal grid lines
for(float tick_val = (float)((int)(vmin / accepted_scale) + 1) * accepted_scale;
tick_val < vmax;
tick_val += accepted_scale) {
uint16_t py = plot_y - (float)plot_h * (tick_val - vmax) / vrange;
uint16_t px = plot_x - 3;
uint16_t pw = plot_w + 3;
display.drawFastHLine(px, py, pw, GxEPD_BLACK);
snprintf(s, sizeof(s), timeseries->format, tick_val);
display.getTextBounds(s, 0, 0, &tbx, &tby, &tbw, &tbh);
display.setCursor(px - tbw - 2, py + tby + tbh);
display.print(s);
}
size_t i = 0;
for(uint32_t reltime = 0; reltime < trange; reltime += tstep) {
if(i >= timeseries->data.size()) {
Serial.println(F("Index out of range! Time range does not match data points."));
break;
}
/*Serial.print(F("Processing data point at dt="));
Serial.print(reltime);
Serial.print(F(""));*/
float val = timeseries->data[i++];
if(isnan(val)) {
//Serial.println(F("Skipping NaN!"));
firstpoint = true;
continue;
}
uint16_t px = plot_x + plot_w * reltime / trange;
uint16_t py = plot_y - (float)plot_h * (val - vmax) / vrange;
if(!firstpoint) {
/*Serial.print(F("Line from ("));
Serial.print(last_x);
Serial.print(F(","));
Serial.print(last_y);
Serial.print(F(") to ("));
Serial.print(px);
Serial.print(F(","));
Serial.print(py);
Serial.println(F(")."));*/
display.drawLine(last_x, last_y, px, py, GxEPD_RED);
// draw it again, 1px below, to give it more weight
display.drawLine(last_x, last_y+1, px, py+1, GxEPD_RED);
} else {
//Serial.println(F("First point, not drawn."));
firstpoint = false;
}
last_x = px;
last_y = py;
}
/* Draw large current value + unit */
size_t cur_val_idx = timeseries->data.size() - 1;
while((cur_val_idx > 0) && isnan(timeseries->data[cur_val_idx])) {
cur_val_idx--;
}
float current_value = timeseries->data[cur_val_idx];
display.setFont(&din1451e24pt7b);
display.setTextColor(GxEPD_RED);
char fmt[16];
snprintf(fmt, sizeof(fmt), "%s %%s", timeseries->format);
snprintf(s, sizeof(s), fmt, current_value, timeseries->unit);
display.getTextBounds(s, 0, 0, &tbx, &tby, &tbw, &tbh);
display.setCursor(plot_x - tbw - 35, plot_y + plot_h/2 - tby - tbh/2 - 5);
display.print(s);
uint16_t large_text_height = tbh;
time_t t = timeseries->tstart + trange * cur_val_idx / timeseries->data.size();
tm *gmt = gmtime(&t);
strftime(s, sizeof(s), "%Y-%m-%d %H:%M", gmt);
display.setFont(&Org_01);
display.getTextBounds(s, 0, 0, &tbx, &tby, &tbw, &tbh);
display.setCursor(plot_x - tbw - 35, plot_y + plot_h/2 - tby + large_text_height/2 + 5);
display.print(s);
}
#endif

46
src/main.cpp Normal file
View file

@ -0,0 +1,46 @@
#include <Arduino.h>
#include <Adafruit_SCD30.h>
#include <epaper.h>
Adafruit_SCD30 scd30;
void initSCD30(void)
{
// Try to initialize!
if (!scd30.begin()) {
Serial.println("Failed to find SCD30 chip");
while (1) { delay(10); }
}
Serial.println("SCD30 Found!");
if (!scd30.setMeasurementInterval(2)){
Serial.println("Failed to set measurement interval");
while(1) {delay(10);}
}
Serial.print("Measurement Interval: ");
Serial.print(scd30.getMeasurementInterval());
Serial.println(" seconds");
}
void setup(void)
{
initSCD30();
epaper_init();
epaper_test();
}
void loop(void)
{
if (!scd30.read()) {
Serial.println("Error reading sensor data");
return;
}
Serial.print("CO2: ");
Serial.print(scd30.CO2, 3);
Serial.println(" ppm");
Serial.println("");
}

11
test/README Normal file
View file

@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html