From 2b9870fb299950b64097b6dda2190c30daa1cbb0 Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Sun, 16 Jun 2024 16:00:19 +0200 Subject: [PATCH] Initial project setup --- .gitignore | 3 + include/Font_din1451e.h | 475 +++++++++++++++++++ include/GxEPD2_display_selection_new_style.h | 206 ++++++++ include/GxEPD2_selection_check.h | 75 +++ include/README | 39 ++ include/epaper.h | 16 + lib/README | 46 ++ platformio.ini | 26 + src/epaper.cpp | 293 ++++++++++++ src/main.cpp | 46 ++ test/README | 11 + 11 files changed, 1236 insertions(+) create mode 100644 .gitignore create mode 100644 include/Font_din1451e.h create mode 100644 include/GxEPD2_display_selection_new_style.h create mode 100644 include/GxEPD2_selection_check.h create mode 100644 include/README create mode 100644 include/epaper.h create mode 100644 lib/README create mode 100644 platformio.ini create mode 100644 src/epaper.cpp create mode 100644 src/main.cpp create mode 100644 test/README diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e7c7fed --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.pio +.cache +compile_commands.json diff --git a/include/Font_din1451e.h b/include/Font_din1451e.h new file mode 100644 index 0000000..10ae9ff --- /dev/null +++ b/include/Font_din1451e.h @@ -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 diff --git a/include/GxEPD2_display_selection_new_style.h b/include/GxEPD2_display_selection_new_style.h new file mode 100644 index 0000000..1b878ba --- /dev/null +++ b/include/GxEPD2_display_selection_new_style.h @@ -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 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 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 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 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 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 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 display(GxEPD2_DRIVER_CLASS(/*CS=4*/ 4, /*DC=*/ 7, /*RST=*/ 6, /*BUSY=*/ 5)); +//GxEPD2_DISPLAY_CLASS display(GxEPD2_DRIVER_CLASS(/*CS=4*/ 4, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1)); // my Seed XIOA0 +//GxEPD2_DISPLAY_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 display(GxEPD2_DRIVER_CLASS(/*CS=4*/ EPD_CS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7)); +#endif + +#endif diff --git a/include/GxEPD2_selection_check.h b/include/GxEPD2_selection_check.h new file mode 100644 index 0000000..3a499bc --- /dev/null +++ b/include/GxEPD2_selection_check.h @@ -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 diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -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 diff --git a/include/epaper.h b/include/epaper.h new file mode 100644 index 0000000..6aebb62 --- /dev/null +++ b/include/epaper.h @@ -0,0 +1,16 @@ +#ifndef EPAPER_H +#define EPAPER_H + +#include +#include "GxEPD2_display_selection_new_style.h" + +typedef void (*epaper_callback)(GxEPD2_DISPLAY_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 diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..2593a33 --- /dev/null +++ b/lib/README @@ -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 +#include + +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 diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..aa3e1b2 --- /dev/null +++ b/platformio.ini @@ -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 diff --git a/src/epaper.cpp b/src/epaper.cpp new file mode 100644 index 0000000..e37a4ba --- /dev/null +++ b/src/epaper.cpp @@ -0,0 +1,293 @@ +#include + +#include +#include +#include +#include + +#include "epaper.h" + +static GxEPD2_DISPLAY_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 +void minmax(const std::vector &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 diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..37436f1 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,46 @@ +#include +#include + +#include + +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(""); +} diff --git a/test/README b/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/test/README @@ -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