first commit

This commit is contained in:
Jérôme Delacotte
2025-03-06 11:15:32 +01:00
commit 7b30d6e298
5276 changed files with 2108927 additions and 0 deletions

View File

@@ -0,0 +1,812 @@
// GxEPD_Example : test example for e-Paper displays from Waveshare and from Dalian Good Display Inc.
//
// Created by Jean-Marc Zingg based on demo code from Good Display,
// available on http://www.e-paper-display.com/download_list/downloadcategoryid=34&isMode=false.html
//
// The e-paper displays are available from:
//
// https://www.aliexpress.com/store/product/Wholesale-1-54inch-E-Ink-display-module-with-embedded-controller-200x200-Communicate-via-SPI-interface-Supports/216233_32824535312.html
//
// http://www.buy-lcd.com/index.php?route=product/product&path=2897_8363&product_id=35120
// or https://www.aliexpress.com/store/product/E001-1-54-inch-partial-refresh-Small-size-dot-matrix-e-paper-display/600281_32815089163.html
//
// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
// Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0
// mapping suggestion from Waveshare SPI e-Paper to Wemos D1 mini
// BUSY -> D2, RST -> D4, DC -> D3, CS -> D8, CLK -> D5, DIN -> D7, GND -> GND, 3.3V -> 3.3V
// mapping suggestion from Waveshare SPI e-Paper to generic ESP8266
// BUSY -> GPIO4, RST -> GPIO2, DC -> GPIO0, CS -> GPIO15, CLK -> GPIO14, DIN -> GPIO13, GND -> GND, 3.3V -> 3.3V
// mapping suggestion for ESP32, e.g. LOLIN32, see .../variants/.../pins_arduino.h for your board
// NOTE: there are variants with different pins for SPI ! CHECK SPI PINS OF YOUR BOARD
// BUSY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V
// new mapping suggestion for STM32F1, e.g. STM32F103C8T6 "BluePill"
// BUSY -> A1, RST -> A2, DC -> A3, CS-> A4, CLK -> A5, DIN -> A7
// mapping suggestion for AVR, UNO, NANO etc.
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 10, CLK -> 13, DIN -> 11
// mapping suggestion for Arduino MEGA
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 53, CLK -> 52, DIN -> 51
// mapping suggestion for Arduino DUE
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 77, CLK -> 76, DIN -> 75
// SPI pins are also on 6 pin 2x3 SPI header
// include library, include base class, make path known
#include <GxEPD.h>
// select the display class to use, only one
//#include <GxDEPG0150BN/GxDEPG0150BN.h> // 1.50" b/w
//#include <GxGDEP015OC1/GxGDEP015OC1.h> // 1.54" b/w
//#include <GxGDEH0154D67/GxGDEH0154D67.h> // 1.54" b/w 200x200, SSD1681
//#include <GxGDEW0154T8/GxGDEW0154T8.h> // 1.54" b/w 152x152 UC8151 (IL0373)
//#include <GxGDEW0154M09/GxGDEW0154M09.h> // 1.54" b/w 200x200 JD79653A
//#include <GxGDEW0154M10/GxGDEW0154M10.h> // 1.54" b/w 152x152 UC8151D
//#include <GxGDEW0154Z04/GxGDEW0154Z04.h> // 1.54" b/w/r 200x200
//#include <GxGDEW0154Z17/GxGDEW0154Z17.h> // 1.54" b/w/r 152x152
//#include <GxGDEH0154Z90/GxGDEH0154Z90.h> // 1.54" b/w/r 200x200 SSD1681
//#include <GxGDEW0213I5F/GxGDEW0213I5F.h> // 2.13" b/w 104x212 flexible
//#include <GxGDE0213B1/GxGDE0213B1.h> // 2.13" b/w
//#include <GxGDEH0213B72/GxGDEH0213B72.h> // 2.13" b/w new panel
//#include <GxGDEH0213B73/GxGDEH0213B73.h> // 2.13" b/w newer panel
//#include <GxGDEM0213B74/GxGDEM0213B74.h> // 2.13" b/w 128x250 SSD1680
//#include <GxGDEW0213Z16/GxGDEW0213Z16.h> // 2.13" b/w/r
//#include <GxGDEH0213Z19/GxGDEH0213Z19.h> // 2.13" b/w/r UC8151D
//#include <GxGDEW0213T5D/GxGDEW0213T5D.h> // 2.13" b/w 104x212 UC8151D
//#include <GxDEPG0213BN/GxDEPG0213BN.h> // 2.13" b/w 128x250, SSD1680, TTGO T5 V2.4.1, V2.3.1
//#include <GxGDEH029A1/GxGDEH029A1.h> // 2.9" b/w
//#include <GxGDEW029T5/GxGDEW029T5.h> // 2.9" b/w UC8151 (IL0373)
//#include <GxGDEW029T5D/GxGDEW029T5D.h> // 2.9" b/w UC8151D
//#include <GxGDEM029T94/GxGDEM029T94.h> // 2.9" b/w
//#include <GxDEPG0290BS/GxDEPG0290BS.h> // 2.9" b/w Waveshare variant, TTGO T5 V2.4.1 2.9"
//#include <GxGDEW029Z10/GxGDEW029Z10.h> // 2.9" b/w/r
//#include <GxGDEH029Z13/GxGDEH029Z13.h> // 2.9" b/w/r UC8151D
//#include <GxGDEW026T0/GxGDEW026T0.h> // 2.6" b/w
//#include <GxDEPG0266BN/GxDEPG0266BN.h> // 2.66" b/w 152x296, SSD1680, TTGO T5 V2.66, TTGO T5 V2.4.1
//#include <GxGDEW027C44/GxGDEW027C44.h> // 2.7" b/w/r
//#include <GxGDEW027W3/GxGDEW027W3.h> // 2.7" b/w
//#include <GxGDEY027T91/GxGDEY027T91.h> // 2.7" b/w
//#include <GxGDEW0371W7/GxGDEW0371W7.h> // 3.7" b/w
//#include <GxGDEW042T2/GxGDEW042T2.h> // 4.2" b/w
//#include <GxGDEW042Z15/GxGDEW042Z15.h> // 4.2" b/w/r
//#include <GxGDEW0583T7/GxGDEW0583T7.h> // 5.83" b/w
//#include <GxGDEW075T8/GxGDEW075T8.h> // 7.5" b/w
//#include <GxGDEW075T7/GxGDEW075T7.h> // 7.5" b/w 800x480
//#include <GxGDEW075Z09/GxGDEW075Z09.h> // 7.5" b/w/r
//#include <GxGDEW075Z08/GxGDEW075Z08.h> // 7.5" b/w/r 800x480
#include GxEPD_BitmapExamples
// FreeFonts from Adafruit_GFX
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>
#include <Fonts/FreeMonoBold24pt7b.h>
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
#if defined(ESP8266)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.2\variants\generic\common.h
GxIO_Class io(SPI, /*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2); // arbitrary selection of D3(=0), D4(=2), selected for default of GxEPD_Class
GxEPD_Class display(io, /*RST=D4*/ 2, /*BUSY=D2*/ 4); // default selection of D4(=2), D2(=4)
// Heltec E-Paper 1.54" b/w without RST, BUSY
//GxEPD_Class display(io, /*RST=D4*/ -1, /*BUSY=D2*/ -1); // no RST, no BUSY
// Waveshare e-Paper ESP8266 Driver Board
//GxIO_Class io(SPI, 15, 4, 5);
//GxEPD_Class display(io, 5, 16);
#elif defined(ESP32)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\espressif\esp32\variants\lolin32\pins_arduino.h
GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16); // arbitrary selection of 17, 16
GxEPD_Class display(io, /*RST=*/ 16, /*BUSY=*/ 4); // arbitrary selection of (16), 4
// for LILYGO® TTGO T5 2.66 board uncomment next two lines instead of previous two lines
//GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 19, /*RST=*/ 4); // LILYGO® TTGO T5 2.66
//GxEPD_Class display(io, /*RST=*/ 4, /*BUSY=*/ 34); // LILYGO® TTGO T5 2.66
#elif defined(ARDUINO_ARCH_SAMD)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.19\variants\mkr1000\variant.h
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.19\variants\mkrzero\variant.h
GxIO_Class io(SPI, /*CS=*/ 4, /*DC=*/ 7, /*RST=*/ 6);
GxEPD_Class display(io, /*RST=*/ 6, /*BUSY=*/ 5);
#elif defined(ARDUINO_GENERIC_STM32F103C) && defined(MCU_STM32F103C8)
// STM32 Boards(STM32duino.com) Generic STM32F103C series STM32F103C8
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\variant.h
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\board\board.h
// new mapping suggestion for STM32F1, e.g. STM32F103C8T6 "BluePill"
// BUSY -> A1, RST -> A2, DC -> A3, CS-> A4, CLK -> A5, DIN -> A7
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 3, /*RST=*/ 2);
GxEPD_Class display(io, /*RST=*/ 2, /*BUSY=*/ 1);
#elif defined(ARDUINO_GENERIC_STM32F103V) && defined(MCU_STM32F103VB)
// STM32 Boards(STM32duino.com) Generic STM32F103V series STM32F103VB
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103vb\variant.h
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103vb\board\board.h
// Good Display DESPI-M01
// note: needs jumper wires from SS=PA4->CS, SCK=PA5->SCK, MOSI=PA7->SDI
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ PE15, /*RST=*/ PE14); // DC, RST as wired by DESPI-M01
GxEPD_Class display(io, /*RST=*/ PE14, /*BUSY=*/ PE13); // RST, BUSY as wired by DESPI-M01
#elif defined(ARDUINO_AVR_MEGA2560)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\mega\pins_arduino.h
// select one, depending on your CS connection
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
//GxIO_Class io(SPI, /*CS=*/ 10, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9, CS on 10 (for CS same as on UNO, for SPI on ICSP use)
GxEPD_Class display(io, /*RST=*/ 9, /*BUSY=*/ 7); // default selection of (9), 7
#else
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\standard\pins_arduino.h
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
GxEPD_Class display(io, /*RST=*/ 9, /*BUSY=*/ 7); // default selection of (9), 7
#endif
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println("setup");
display.init(115200); // enable diagnostic output on Serial
Serial.println("setup done");
}
void loop()
{
showBitmapExample();
delay(2000);
#if !defined(__AVR)
//drawCornerTest();
showFont("FreeMonoBold9pt7b", &FreeMonoBold9pt7b);
showFont("FreeMonoBold12pt7b", &FreeMonoBold12pt7b);
//showFont("FreeMonoBold18pt7b", &FreeMonoBold18pt7b);
//showFont("FreeMonoBold24pt7b", &FreeMonoBold24pt7b);
#else
display.drawCornerTest();
delay(2000);
display.drawPaged(showFontCallback);
#endif
display.powerDown();
delay(10000);
}
#if defined(_GxGDEP015OC1_H_)
void showBitmapExample()
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
delay(5000);
showBoat();
}
#endif
#if defined(_GxGDEH0154D67_H_) || defined(_GxDEPG0150BN_H_)
void showBitmapExample()
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
delay(5000);
showBoat();
}
#endif
#if defined(_GxGDEW0154T8_H_) || defined(_GxGDEW0154M10_H_)
void showBitmapExample()
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
display.drawExampleBitmap(BitmapExample3, sizeof(BitmapExample3));
delay(5000);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
delay(5000);
}
#endif
#if defined(_GxGDEW0154M09_H_)
void showBitmapExample()
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
#if !defined(__AVR)
display.drawExampleBitmap(BitmapExample3, sizeof(BitmapExample3));
delay(5000);
#endif
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
delay(5000);
}
#endif
#if defined(_GxGDEW0154Z04_H_)
#define HAS_RED_COLOR
void showBitmapExample()
{
#if !defined(__AVR)
display.drawPicture(BitmapWaveshare_black, BitmapWaveshare_red, sizeof(BitmapWaveshare_black), sizeof(BitmapWaveshare_red), GxEPD::bm_normal);
delay(5000);
#endif
display.drawExamplePicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
delay(5000);
}
#endif
#if defined(_GxGDEW0154Z17_H_)
#define HAS_RED_COLOR
void showBitmapExample()
{
display.drawExamplePicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
delay(5000);
display.drawExamplePicture(BitmapExample3, BitmapExample4, sizeof(BitmapExample1), sizeof(BitmapExample2));
delay(5000);
//display.drawBitmap(BitmapExample2, sizeof(BitmapExample2));
}
#endif
#if defined(_GxGDEH0154Z90_H_)
#define HAS_RED_COLOR
void showBitmapExample()
{
display.drawExamplePicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
delay(5000);
//display.drawBitmap(BitmapExample2, sizeof(BitmapExample2));
}
#endif
#if defined(_GxGDE0213B1_H_)
void showBitmapExample()
{
display.drawBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
#if !defined(__AVR)
display.drawBitmap(first, sizeof(first));
delay(5000);
display.drawBitmap(second, sizeof(second));
delay(5000);
display.drawBitmap(third, sizeof(third));
delay(5000);
#endif
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
delay(5000);
showBoat();
}
#endif
#if defined(_GxGDEH0213B72_H_) || defined(_GxGDEH0213B73_H_) || defined(_GxGDEM0213B74_H_) || defined(_GxDEPG0213BN_H_)
void showBitmapExample()
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
#if !defined(__AVR)
display.drawExampleBitmap(BitmapExample3, sizeof(BitmapExample3));
delay(5000);
display.drawExampleBitmap(logo, sizeof(logo));
delay(5000);
display.drawExampleBitmap(first, sizeof(first));
delay(5000);
display.drawExampleBitmap(second, sizeof(second));
delay(5000);
display.drawExampleBitmap(third, sizeof(third));
delay(5000);
#endif
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
delay(5000);
showBoat();
}
#endif
#if defined(_GxGDEW0213I5F_H_)
void showBitmapExample()
{
display.drawBitmap(BitmapExample1, sizeof(BitmapExample1), GxEPD::bm_invert);
delay(5000);
display.drawBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
#if !defined(__AVR)
display.drawBitmap(BitmapExample3, sizeof(BitmapExample3));
delay(5000);
display.drawBitmap(BitmapExample4, sizeof(BitmapExample4));
delay(5000);
#endif
display.fillScreen(GxEPD_WHITE);
display.drawBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
delay(5000);
}
#endif
#if defined(_GxGDEW0213T5D_H_)
void showBitmapExample()
{
display.drawBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(5000);
display.drawBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
display.fillScreen(GxEPD_WHITE);
display.drawBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
delay(5000);
}
#endif
#if defined(_GxGDEW0213Z16_H_)
#define HAS_RED_COLOR
void showBitmapExample()
{
display.drawPicture(BitmapWaveshare_black, BitmapWaveshare_red, sizeof(BitmapWaveshare_black), sizeof(BitmapWaveshare_red));
delay(5000);
display.drawExamplePicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
delay(5000);
#if !defined(__AVR)
display.drawExamplePicture(BitmapExample3, BitmapExample4, sizeof(BitmapExample3), sizeof(BitmapExample4));
delay(5000);
#endif
display.drawExampleBitmap(BitmapWaveshare_black, sizeof(BitmapWaveshare_black));
delay(2000);
// example bitmaps for b/w/r are normal on b/w, but inverted on red
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2), GxEPD::bm_invert);
delay(2000);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
}
#endif
#if defined(_GxGDEH0213Z19_H_)
#define HAS_RED_COLOR
void showBitmapExample()
{
display.drawExamplePicture(BitmapExample1_black, BitmapExample1_red, sizeof(BitmapExample1_black), sizeof(BitmapExample1_red));
delay(5000);
#if !defined(__AVR)
display.drawExamplePicture(BitmapExample2_black, BitmapExample2_red, sizeof(BitmapExample2_black), sizeof(BitmapExample2_red));
delay(5000);
#endif
}
#endif
#if defined(_GxGDEH029A1_H_)
void showBitmapExample()
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
delay(5000);
showBoat();
}
#endif
#if defined(_GxGDEW029T5_H_) || defined(_GxGDEW029T5D_H_)
void showBitmapExample()
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
display.drawExampleBitmap(BitmapExample3, sizeof(BitmapExample3));
delay(5000);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
delay(5000);
// showBoat();
}
#endif
#if defined(_GxGDEM029T94_H_) || defined(_GxDEPG0290BS_H_)
void showBitmapExample()
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
delay(5000);
}
#endif
#if defined(_GxGDEW029Z10_H_) || defined(_GxGDEH029Z13_H_)
#define HAS_RED_COLOR
void showBitmapExample()
{
#if defined(__AVR)
display.drawExamplePicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
delay(5000);
#else
display.drawPicture(BitmapWaveshare_black, BitmapWaveshare_red, sizeof(BitmapWaveshare_black), sizeof(BitmapWaveshare_red));
delay(5000);
display.drawExamplePicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
delay(5000);
display.drawExamplePicture(BitmapExample3, BitmapExample4, sizeof(BitmapExample3), sizeof(BitmapExample4));
delay(5000);
display.drawExampleBitmap(BitmapWaveshare_black, sizeof(BitmapWaveshare_black));
delay(2000);
// example bitmaps for b/w/r are normal on b/w, but inverted on red
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2), GxEPD::bm_invert);
delay(2000);
#endif
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
}
#endif
#if defined(_GxGDEW026T0_H_) || defined(_GxDEPG0266BN_H_)
void showBitmapExample()
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
#if !defined(__AVR)
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(2000);
display.drawExampleBitmap(BitmapExample3, sizeof(BitmapExample3));
delay(2000);
#endif
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
}
#endif
#if defined(_GxGDEW027C44_H_)
#define HAS_RED_COLOR
void showBitmapExample()
{
// draw black and red bitmap
display.drawPicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
delay(5000);
return;
display.drawBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.fillScreen(GxEPD_WHITE);
display.drawBitmap(0, 0, BitmapExample1, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
}
#endif
#if defined(_GxGDEW027W3_H_) || defined(_GxGDEY027T91_H_)
void showBitmapExample()
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
#if !defined(__AVR)
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(2000);
display.drawExampleBitmap(BitmapExample3, sizeof(BitmapExample3));
delay(2000);
display.drawExampleBitmap(BitmapExample4, sizeof(BitmapExample4));
delay(2000);
display.drawExampleBitmap(BitmapExample5, sizeof(BitmapExample5));
delay(2000);
#endif
display.drawExampleBitmap(BitmapWaveshare, sizeof(BitmapWaveshare));
delay(5000);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
}
#endif
#if defined(_GxGDEW0371W7_H_)
void showBitmapExample()
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
#if !defined(__AVR)
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(2000);
display.drawExampleBitmap(BitmapExample3, sizeof(BitmapExample3));
delay(2000);
#endif
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
}
#endif
#if defined(_GxGDEW042T2_H_)
void showBitmapExample()
{
#if defined(__AVR)
display.drawBitmap(BitmapExample1, sizeof(BitmapExample1));
#else
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
#endif
}
#endif
#if defined(_GxGDEW042Z15_H_)
#define HAS_RED_COLOR
void showBitmapExample()
{
#if defined(__AVR)
display.drawBitmap(BitmapExample1, sizeof(BitmapExample1));
#else
// draw black and red bitmap
display.drawPicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
delay(5000);
display.drawPicture(BitmapExample3, BitmapExample4, sizeof(BitmapExample3), sizeof(BitmapExample4));
delay(5000);
display.drawPicture(BitmapWaveshare_black, BitmapWaveshare_red, sizeof(BitmapWaveshare_black), sizeof(BitmapWaveshare_red));
delay(5000);
display.drawBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
#endif
}
#endif
#if defined(_GxGDEW0583T7_H_)
void showBitmapExample()
{
#if defined(__AVR)
//display.drawBitmap(BitmapExample1, sizeof(BitmapExample1));
#else
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
#endif
}
#endif
#if defined(_GxGDEW075T8_H_)
void showBitmapExample()
{
#if defined(__AVR)
display.drawBitmap(BitmapExample1, sizeof(BitmapExample1));
#else
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
#endif
}
#endif
#if defined(_GxGDEW075Z09_H_)
#define HAS_RED_COLOR
void showBitmapExample()
{
#if defined(__AVR)
display.drawBitmap(BitmapExample1, sizeof(BitmapExample1));
#elif defined(ARDUINO_GENERIC_STM32F103C)
display.drawBitmap(BitmapExample1, sizeof(BitmapExample1));
#elif defined(ARDUINO_GENERIC_STM32F103V)
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExamplePicture_3C(BitmapPicture_3C, sizeof(BitmapPicture_3C));
#else
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
display.drawExamplePicture_3C(BitmapPicture_3C, sizeof(BitmapPicture_3C));
#endif
}
#endif
#if defined(_GxGDEW075T7_H_)
void showBitmapExample()
{
#if defined(__AVR)
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
#else
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(5000);
display.drawExampleBitmap(BitmapExample3, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample4, sizeof(BitmapExample2));
delay(5000);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
#endif
}
#endif
#if defined(_GxGDEW075Z08_H_)
#define HAS_RED_COLOR
void showBitmapExample()
{
#if defined(__AVR) || defined(MCU_STM32F103C8)
// draw (part of) black bitmap, not enough space for red
display.drawPicture(BitmapExample1, 0, sizeof(BitmapExample1), 0);
#else
// draw black and red bitmap
display.drawExamplePicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
//delay(5000);
//display.drawPicture(BitmapExample1, 0, sizeof(BitmapExample1), 0);
//delay(5000);
//display.drawPicture(0, BitmapExample2, 0, sizeof(BitmapExample2));
//delay(5000);
//display.drawExamplePicture(BitmapExample1, 0, sizeof(BitmapExample1), 0);
//delay(5000);
//display.drawExamplePicture(0, BitmapExample2, 0, sizeof(BitmapExample2));
//delay(5000);
//display.fillScreen(GxEPD_WHITE);
//display.drawBitmap(0, 0, BitmapExample1, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
//display.update();
//delay(5000);
//display.fillScreen(GxEPD_WHITE);
//display.drawBitmap(0, 0, BitmapExample2, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
//display.update();
//display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
//display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, false);
#endif
}
#endif
void showFont(const char name[], const GFXfont* f)
{
display.fillScreen(GxEPD_WHITE);
display.setTextColor(GxEPD_BLACK);
display.setFont(f);
display.setCursor(0, 0);
display.println();
display.println(name);
display.println(" !\"#$%&'()*+,-./");
display.println("0123456789:;<=>?");
display.println("@ABCDEFGHIJKLMNO");
display.println("PQRSTUVWXYZ[\\]^_");
#if defined(HAS_RED_COLOR)
display.setTextColor(GxEPD_RED);
#endif
display.println("`abcdefghijklmno");
display.println("pqrstuvwxyz{|}~ ");
display.update();
delay(5000);
}
void showFontCallback()
{
const char* name = "FreeMonoBold9pt7b";
const GFXfont* f = &FreeMonoBold9pt7b;
display.fillScreen(GxEPD_WHITE);
display.setTextColor(GxEPD_BLACK);
display.setFont(f);
display.setCursor(0, 0);
display.println();
display.println(name);
display.println(" !\"#$%&'()*+,-./");
display.println("0123456789:;<=>?");
display.println("@ABCDEFGHIJKLMNO");
display.println("PQRSTUVWXYZ[\\]^_");
#if defined(HAS_RED_COLOR)
display.setTextColor(GxEPD_RED);
#endif
display.println("`abcdefghijklmno");
display.println("pqrstuvwxyz{|}~ ");
}
void drawCornerTest()
{
display.drawCornerTest();
delay(5000);
uint8_t rotation = display.getRotation();
for (uint16_t r = 0; r < 4; r++)
{
display.setRotation(r);
display.fillScreen(GxEPD_WHITE);
display.fillRect(0, 0, 8, 8, GxEPD_BLACK);
display.fillRect(display.width() - 18, 0, 16, 16, GxEPD_BLACK);
display.fillRect(display.width() - 25, display.height() - 25, 24, 24, GxEPD_BLACK);
display.fillRect(0, display.height() - 33, 32, 32, GxEPD_BLACK);
display.update();
delay(5000);
}
display.setRotation(rotation); // restore
}
#if defined(_GxGDEP015OC1_H_) || defined(_GxGDEH0154D67_H_) || defined(_GxGDE0213B1_H_) || defined(_GxGDEH0213B72_H_) || defined(_GxGDEH0213B73_H_) || defined(_GxGDEM0213B74_H_) \
|| defined(_GxGDEH029A1_H_) || defined(_GxDEPG0150BN_H_) || defined(_GxDEPG0213BN_H_) || defined(_GxGDEW0154M09_H_)
#include "IMG_0001.h"
void showBoat()
{
// thanks to bytecrusher: http://forum.arduino.cc/index.php?topic=487007.msg3367378#msg3367378
uint16_t x = (display.width() - 64) / 2;
uint16_t y = 5;
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(gImage_IMG_0001, x, y, 64, 180, GxEPD_BLACK);
display.update();
delay(500);
uint16_t forward = GxEPD::bm_invert | GxEPD::bm_flip_x;
uint16_t reverse = GxEPD::bm_invert | GxEPD::bm_flip_x | GxEPD::bm_flip_y;
for (; y + 180 + 5 <= display.height(); y += 5)
{
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(gImage_IMG_0001, x, y, 64, 180, GxEPD_BLACK, forward);
display.updateWindow(0, 0, display.width(), display.height());
delay(500);
}
delay(1000);
for (; y >= 5; y -= 5)
{
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(gImage_IMG_0001, x, y, 64, 180, GxEPD_BLACK, reverse);
display.updateWindow(0, 0, display.width(), display.height());
delay(1000);
}
display.update();
delay(1000);
}
#endif

View File

@@ -0,0 +1,104 @@
#ifndef _GxBootExample_H_
#define _GxBootExample_H_
#if defined(ESP8266) || defined(ESP32)
#include <pgmspace.h>
#else
#include <avr/pgmspace.h>
#endif
// 180 x 64 (Boot)
const unsigned char gImage_IMG_0001[1440] PROGMEM = { /* 0X01,0X01,0XB4,0X00,0X40,0X00, */
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XC0,0X1F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X07,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0X00,0X01,0XFF,0XFF,0XFF,0XFF,0XFF,0XFC,0X01,0X80,0X3F,0XFF,0XFF,
0XFF,0XFF,0XFC,0X01,0XE0,0X1F,0XFF,0XFF,0XFF,0XFF,0XF8,0X10,0XF8,0X0F,0XFF,0XFF,
0XFF,0XFF,0XF8,0X70,0XF8,0X0F,0XFF,0XFF,0XFF,0XFF,0XF0,0X70,0XF8,0X0F,0XFF,0XFF,
0XFF,0XFF,0XF0,0XF0,0XF8,0X07,0XFF,0XFF,0XFF,0XFF,0XE1,0XF0,0XFC,0X07,0XFF,0XFF,
0XFF,0XFF,0XE1,0XF0,0XFC,0X03,0XFF,0XFF,0XFF,0XFF,0XE3,0XF0,0XFC,0X01,0XFF,0XFF,
0XFF,0XFF,0XE3,0XF0,0XFC,0X21,0XFF,0XFF,0XFF,0XFF,0XC3,0XF8,0XFE,0X21,0XFF,0XFF,
0XFF,0XFF,0XC3,0XF8,0XFE,0X10,0XFF,0XFF,0XFF,0XFF,0XC7,0XF8,0XFE,0X10,0XFF,0XFF,
0XFF,0XFF,0XC7,0XF8,0XFE,0X10,0XFF,0XFF,0XFF,0XFF,0XC7,0XF8,0XFF,0X18,0XFF,0XFF,
0XFF,0XFF,0XC7,0XF8,0XFF,0X08,0XFF,0XFF,0XFF,0XFF,0XC7,0XF0,0XFF,0X00,0XFF,0XFF,
0XFF,0XFF,0XC7,0XF0,0XFF,0X80,0XFF,0XFF,0XFF,0XFF,0XC7,0XF0,0XFF,0X80,0X7F,0XFF,
0XFF,0XFF,0XC7,0XF0,0XFF,0XC0,0X3F,0XFF,0XFF,0XFF,0X87,0XF1,0XFF,0XC0,0X3F,0XFF,
0XFF,0XFF,0X07,0XF1,0XFF,0XE0,0X1F,0XFF,0XFF,0XFF,0X03,0XE1,0XFF,0XE0,0X1F,0XFF,
0XFF,0XFE,0X01,0XE1,0XFF,0XF1,0X1F,0XFF,0XFF,0XFC,0X01,0XE1,0XFF,0XF1,0X1F,0XFF,
0XFF,0XF8,0X21,0XE1,0XFF,0XF1,0X1F,0XFF,0XFF,0XE0,0X31,0XE1,0XFF,0XF1,0X1F,0XFF,
0XFF,0XE0,0XF1,0XF1,0XFF,0XF1,0X1F,0XFF,0XFF,0XC1,0XF1,0XF0,0XFF,0XF1,0X0F,0XFF,
0XFF,0X83,0XF1,0XF0,0XFF,0XF1,0X0F,0XFF,0XFF,0X87,0XF1,0XF0,0XFF,0XF1,0X0F,0XFF,
0XFF,0X07,0XF1,0XF0,0XFF,0XF0,0X8F,0XFF,0XFF,0X0F,0XF1,0XF0,0XFF,0XF0,0X8F,0XFF,
0XFE,0X0F,0XF1,0XF0,0XFF,0XF8,0X8F,0XFF,0XFE,0X1F,0XF1,0XF0,0XFF,0XF8,0X07,0XFF,
0XFC,0X1F,0XE1,0XF0,0XFF,0XF8,0X07,0XFF,0XFC,0X1F,0XE1,0XF8,0XFF,0XFC,0X03,0XFF,
0XFC,0X1F,0XE1,0XF8,0XFF,0XFC,0X03,0XFF,0XFC,0X07,0XE3,0XF8,0XFF,0XFC,0X23,0XFF,
0XF8,0X01,0XE3,0XF8,0XFF,0XFE,0X21,0XFF,0XF8,0X00,0XE3,0XF8,0XFF,0XFE,0X21,0XFF,
0XF8,0X43,0X23,0XF8,0XFF,0XFE,0X31,0XFF,0XF8,0X40,0X03,0XF8,0XFF,0XFE,0X31,0XFF,
0XF0,0X60,0X03,0XF8,0XFF,0XFE,0X31,0XFF,0XF0,0XE0,0X03,0XF8,0XFF,0XFE,0X31,0XFF,
0XE0,0XFC,0X03,0XF8,0X7F,0XFE,0X30,0XFF,0XE1,0XFF,0X83,0XF8,0X7F,0XFE,0X30,0XFF,
0XE1,0XFF,0XC3,0XFC,0X7F,0XFE,0X30,0XFF,0XE1,0XFF,0XC3,0XFC,0X7F,0XFE,0X38,0XFF,
0XE1,0XFF,0XE3,0XFC,0X3F,0XFE,0X38,0X7F,0XE1,0XFF,0XE3,0XFC,0X3F,0XFE,0X18,0X7F,
0XE1,0XFF,0XE3,0XFC,0X3F,0XFE,0X18,0X3F,0XE1,0XFF,0XE3,0XFC,0X3F,0XFE,0X1C,0X3F,
0XF1,0XFF,0XE3,0XFE,0X3F,0XFF,0X0C,0X3F,0XF1,0XFF,0XE3,0XFE,0X3F,0XFF,0X0E,0X3F,
0XE1,0XFF,0XE3,0XFE,0X1F,0XFF,0X86,0X3F,0XE1,0XFF,0XE3,0XFE,0X1F,0XFF,0X86,0X3F,
0XE1,0XFF,0XE3,0XFE,0X1F,0XFF,0X86,0X3F,0XE3,0XFF,0XE3,0XFE,0X1F,0XFF,0X86,0X3F,
0XE3,0XFF,0XE3,0XFF,0X1F,0XFF,0X86,0X3F,0XC3,0XFF,0XE3,0XFF,0X1F,0XFF,0X8E,0X3F,
0XC3,0XFF,0XE3,0XFF,0X1F,0XFF,0X8E,0X3F,0XC7,0XFF,0XC3,0XFF,0X1F,0XFF,0X8E,0X3F,
0XC7,0XFF,0XC3,0XFF,0X0F,0XFF,0X8E,0X3F,0XC3,0XFF,0XC3,0XFF,0X0F,0XFF,0X8E,0X3F,
0XC0,0X7F,0XC7,0XFF,0X0F,0XFF,0X8E,0X1F,0XC0,0X3F,0XC7,0XFF,0X0F,0XFF,0X8E,0X0F,
0XE0,0X0F,0XC7,0XFF,0X0F,0XFF,0X86,0X0F,0XE2,0X07,0XC7,0XFF,0X0F,0XFF,0X87,0X0F,
0XE3,0X07,0XC7,0XFF,0X8F,0XFF,0XC7,0X8F,0XE3,0X83,0X87,0XFF,0X8F,0XFF,0XC7,0X8F,
0XE3,0XC0,0X87,0XFF,0X8F,0XFF,0XC7,0X0F,0XE3,0XE0,0X0F,0XFF,0X8F,0XFF,0XC7,0X0F,
0XE3,0XF0,0X07,0XFF,0X87,0XFF,0XC7,0X1F,0XE3,0XF8,0X07,0XFF,0X87,0XFF,0XC7,0X1F,
0XC3,0XFC,0X07,0XFF,0X87,0XFF,0XC7,0X1F,0XC3,0XFE,0X07,0XFF,0X87,0XFF,0XC3,0X0F,
0XC3,0XFE,0X07,0XFF,0X87,0XFF,0XC3,0X0F,0XC7,0XFF,0X07,0XFF,0X87,0XFF,0XC3,0X8F,
0XC1,0XFF,0XC7,0XFF,0X87,0XFF,0XE3,0X87,0XC0,0X3F,0X87,0XFF,0X87,0XFF,0XE3,0X83,
0XC0,0X1F,0X87,0XFF,0X87,0XFF,0XE3,0X83,0XC0,0X1F,0X87,0XFF,0X87,0XFF,0XE3,0XC3,
0XE2,0X07,0X87,0XFF,0X83,0XFF,0XE3,0XC3,0XE1,0X07,0X87,0XFF,0X83,0XFF,0XE3,0XC3,
0XE1,0X81,0X87,0XFF,0X83,0XFF,0XE3,0XC3,0XE1,0XC0,0X87,0XFF,0XC3,0XFF,0XE3,0XC7,
0XE1,0XE0,0X0F,0XFF,0XC3,0XFF,0XE3,0XC7,0XE1,0XF0,0X07,0XFF,0XC3,0XFF,0XE3,0XC7,
0XE1,0XF8,0X0F,0XFF,0XC3,0XFF,0XE3,0XC7,0XE1,0XFE,0X0F,0XFF,0XC3,0XFF,0XE3,0XC7,
0XF1,0XFF,0X0F,0XFF,0XC3,0XFF,0XE3,0XC3,0XF1,0XFF,0X0F,0XFF,0XE3,0XFF,0XE3,0XC3,
0XF0,0XFF,0X0F,0XFF,0XE1,0XFF,0XE3,0XE3,0XF0,0XFF,0X8F,0XFF,0XE1,0XFF,0XE3,0XE3,
0XF8,0X7F,0X8F,0XFF,0XE1,0XFF,0XE3,0XE3,0XF8,0X3F,0X8F,0XFF,0XE1,0XFF,0XE3,0XE3,
0XFC,0X1F,0X87,0XFF,0XE1,0XFF,0XE3,0XE3,0XFE,0X0F,0X87,0XFF,0XE1,0XFF,0XE1,0XE3,
0XFF,0X0F,0X87,0XFF,0XE1,0XFF,0XE1,0XE3,0XFF,0X87,0X87,0XFF,0XE1,0XFF,0XE1,0XE3,
0XFF,0X83,0X87,0XFF,0XE1,0XFF,0XF1,0XC3,0XFF,0X81,0X87,0XFF,0XE1,0XFF,0XF1,0XC3,
0XFF,0XC0,0X87,0XFF,0XE1,0XFF,0XF1,0X83,0XFF,0XE0,0X0F,0XFF,0XF1,0XFF,0XF1,0X87,
0XFF,0XF0,0X0F,0XFF,0XF1,0XFF,0XF1,0X87,0XFF,0XFC,0X0F,0XFF,0XE0,0XFF,0XF1,0X8F,
0XFF,0XFE,0X0F,0XFF,0XE0,0XFF,0XF1,0X8F,0XFF,0XFE,0X0F,0XFF,0XE0,0XFF,0XE1,0X8F,
0XFF,0XFF,0X0F,0XFF,0XE0,0XFF,0XE1,0X8F,0XFF,0XFF,0X07,0XFF,0XF0,0XFF,0XE3,0X8F,
0XFF,0XFF,0X87,0XFF,0XF0,0XFF,0XE3,0X8F,0XFF,0XFF,0X87,0XFF,0XF0,0XFF,0XE3,0X8F,
0XFF,0XFF,0XC3,0XFF,0XF0,0XFF,0XE3,0X8F,0XFF,0XFF,0XC3,0XFF,0XF0,0XFF,0XE3,0X8F,
0XFF,0XFF,0XC3,0XFF,0XF0,0XFF,0XE3,0X8F,0XFF,0XFF,0XE3,0XFF,0XF0,0XFF,0XE3,0X8F,
0XFF,0XFF,0XE3,0XFF,0XF0,0XFF,0XE3,0X8F,0XFF,0XFF,0XE1,0XFF,0XF0,0XFF,0XE3,0X0F,
0XFF,0XFF,0XE1,0XFF,0XF0,0XFF,0XE3,0X0F,0XFF,0XFF,0XE1,0XFF,0XF0,0XFF,0XE3,0X1F,
0XFF,0XFF,0XF1,0XFF,0XF0,0XFF,0XE3,0X1F,0XFF,0XFF,0XF0,0XFF,0XF8,0XFF,0XE3,0X1F,
0XFF,0XFF,0XF0,0XFF,0XF8,0X7F,0XE3,0X1F,0XFF,0XFF,0XF0,0XFF,0XF8,0X7F,0XC2,0X1F,
0XFF,0XFF,0XF8,0X7F,0XF8,0X7F,0XC0,0X1F,0XFF,0XFF,0XF8,0X7F,0XF8,0X7F,0XC4,0X1F,
0XFF,0XFF,0XF8,0X7F,0XF8,0X7F,0XC4,0X3F,0XFF,0XFF,0XFC,0X7F,0XF8,0X7F,0XC0,0X7F,
0XFF,0XFF,0XFC,0X7F,0XF8,0X7F,0XC0,0X7F,0XFF,0XFF,0XFC,0X7F,0XF8,0X7F,0XC0,0XFF,
0XFF,0XFF,0XFC,0X7F,0XF8,0X7F,0XE0,0XFF,0XFF,0XFF,0XFC,0X7F,0XF8,0X7F,0XE0,0XFF,
0XFF,0XFF,0XFC,0X3F,0XF8,0X7F,0XE1,0XFF,0XFF,0XFF,0XFC,0X3F,0XF8,0X7F,0XE1,0XFF,
0XFF,0XFF,0XFC,0X3F,0XF8,0X7F,0XC3,0XFF,0XFF,0XFF,0XFE,0X1F,0XF8,0X7F,0XC3,0XFF,
0XFF,0XFF,0XFE,0X1F,0XF0,0X7F,0X83,0XFF,0XFF,0XFF,0XFE,0X0F,0XF0,0X7F,0X87,0XFF,
0XFF,0XFF,0XFF,0X0F,0XF0,0X7F,0X8F,0XFF,0XFF,0XFF,0XFF,0X87,0XF0,0X7F,0X0F,0XFF,
0XFF,0XFF,0XFF,0X87,0XF0,0X7E,0X0F,0XFF,0XFF,0XFF,0XFF,0XC3,0XF0,0X7E,0X0F,0XFF,
0XFF,0XFF,0XFF,0XC1,0XF0,0X7E,0X1F,0XFF,0XFF,0XFF,0XFF,0XE1,0XF0,0X7C,0X3F,0XFF,
0XFF,0XFF,0XFF,0XE0,0XF0,0X7C,0X3F,0XFF,0XFF,0XFF,0XFF,0XF0,0XF0,0X78,0X3F,0XFF,
0XFF,0XFF,0XFF,0XF8,0X70,0X70,0X7F,0XFF,0XFF,0XFF,0XFF,0XF8,0X38,0X60,0X7F,0XFF,
0XFF,0XFF,0XFF,0XFC,0X3C,0X20,0XFF,0XFF,0XFF,0XFF,0XFF,0XFC,0X1C,0X01,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFE,0X18,0X03,0XFF,0XFF,0XFF,0XFF,0XFF,0XFE,0X18,0X03,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0X18,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X08,0X07,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0X08,0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X00,0X1F,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0X80,0X3F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X7F,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XF8,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
};
#endif

View File

@@ -0,0 +1,250 @@
// GxEPD_Hello World Example by Jean-Marc Zingg
//
// Created by Jean-Marc Zingg based on demo code from Good Display,
// available on http://www.e-paper-display.com/download_list/downloadcategoryid=34&isMode=false.html
//
// The e-paper displays are available from:
//
// https://www.aliexpress.com/store/product/Wholesale-1-54inch-E-Ink-display-module-with-embedded-controller-200x200-Communicate-via-SPI-interface-Supports/216233_32824535312.html
//
// http://www.buy-lcd.com/index.php?route=product/product&path=2897_8363&product_id=35120
// or https://www.aliexpress.com/store/product/E001-1-54-inch-partial-refresh-Small-size-dot-matrix-e-paper-display/600281_32815089163.html
//
// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
// Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0
// mapping suggestion from Waveshare SPI e-Paper to Wemos D1 mini
// BUSY -> D2, RST -> D4, DC -> D3, CS -> D8, CLK -> D5, DIN -> D7, GND -> GND, 3.3V -> 3.3V
// mapping suggestion from Waveshare SPI e-Paper to generic ESP8266
// BUSY -> GPIO4, RST -> GPIO2, DC -> GPIO0, CS -> GPIO15, CLK -> GPIO14, DIN -> GPIO13, GND -> GND, 3.3V -> 3.3V
// mapping suggestion for ESP32, e.g. LOLIN32, see .../variants/.../pins_arduino.h for your board
// NOTE: there are variants with different pins for SPI ! CHECK SPI PINS OF YOUR BOARD
// BUSY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V
// new mapping suggestion for STM32F1, e.g. STM32F103C8T6 "BluePill"
// BUSY -> A1, RST -> A2, DC -> A3, CS-> A4, CLK -> A5, DIN -> A7
// mapping suggestion for AVR, UNO, NANO etc.
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 10, CLK -> 13, DIN -> 11
// mapping suggestion for Arduino MEGA
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 53, CLK -> 52, DIN -> 51
// mapping suggestion for Arduino DUE
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 77, CLK -> 76, DIN -> 75
// SPI pins are also on 6 pin 2x3 SPI header
// include library, include base class, make path known
#include <GxEPD.h>
// select the display class to use, only one
//#include <GxDEPG0150BN/GxDEPG0150BN.h> // 1.50" b/w
//#include <GxGDEP015OC1/GxGDEP015OC1.h> // 1.54" b/w
//#include <GxGDEH0154D67/GxGDEH0154D67.h> // 1.54" b/w 200x200, SSD1681
//#include <GxGDEW0154T8/GxGDEW0154T8.h> // 1.54" b/w 152x152 UC8151 (IL0373)
//#include <GxGDEW0154M09/GxGDEW0154M09.h> // 1.54" b/w 200x200 JD79653A
//#include <GxGDEW0154M10/GxGDEW0154M10.h> // 1.54" b/w 152x152 UC8151D
//#include <GxGDEW0154Z04/GxGDEW0154Z04.h> // 1.54" b/w/r 200x200
//#include <GxGDEW0154Z17/GxGDEW0154Z17.h> // 1.54" b/w/r 152x152
//#include <GxGDEH0154Z90/GxGDEH0154Z90.h> // 1.54" b/w/r 200x200 SSD1681
//#include <GxGDEW0213I5F/GxGDEW0213I5F.h> // 2.13" b/w 104x212 flexible
//#include <GxGDE0213B1/GxGDE0213B1.h> // 2.13" b/w
//#include <GxGDEH0213B72/GxGDEH0213B72.h> // 2.13" b/w new panel
//#include <GxGDEH0213B73/GxGDEH0213B73.h> // 2.13" b/w newer panel
//#include <GxGDEM0213B74/GxGDEM0213B74.h> // 2.13" b/w 128x250 SSD1680
//#include <GxGDEW0213Z16/GxGDEW0213Z16.h> // 2.13" b/w/r
//#include <GxGDEH0213Z19/GxGDEH0213Z19.h> // 2.13" b/w/r UC8151D
//#include <GxGDEW0213T5D/GxGDEW0213T5D.h> // 2.13" b/w 104x212 UC8151D
//#include <GxDEPG0213BN/GxDEPG0213BN.h> // 2.13" b/w 128x250, SSD1680, TTGO T5 V2.4.1, V2.3.1
//#include <GxGDEH029A1/GxGDEH029A1.h> // 2.9" b/w
//#include <GxGDEW029T5/GxGDEW029T5.h> // 2.9" b/w UC8151 (IL0373)
//#include <GxGDEW029T5D/GxGDEW029T5D.h> // 2.9" b/w UC8151D
//#include <GxGDEM029T94/GxGDEM029T94.h> // 2.9" b/w
//#include <GxDEPG0290BS/GxDEPG0290BS.h> // 2.9" b/w Waveshare variant, TTGO T5 V2.4.1 2.9"
//#include <GxGDEW029Z10/GxGDEW029Z10.h> // 2.9" b/w/r
//#include <GxGDEH029Z13/GxGDEH029Z13.h> // 2.9" b/w/r UC8151D
//#include <GxGDEW026T0/GxGDEW026T0.h> // 2.6" b/w
//#include <GxDEPG0266BN/GxDEPG0266BN.h> // 2.66" b/w 152x296, SSD1680, TTGO T5 V2.66, TTGO T5 V2.4.1
//#include <GxGDEW027C44/GxGDEW027C44.h> // 2.7" b/w/r
//#include <GxGDEW027W3/GxGDEW027W3.h> // 2.7" b/w
//#include <GxGDEY027T91/GxGDEY027T91.h> // 2.7" b/w
//#include <GxGDEW0371W7/GxGDEW0371W7.h> // 3.7" b/w
//#include <GxGDEW042T2/GxGDEW042T2.h> // 4.2" b/w
//#include <GxGDEW042Z15/GxGDEW042Z15.h> // 4.2" b/w/r
//#include <GxGDEW0583T7/GxGDEW0583T7.h> // 5.83" b/w
//#include <GxGDEW075T8/GxGDEW075T8.h> // 7.5" b/w
//#include <GxGDEW075T7/GxGDEW075T7.h> // 7.5" b/w 800x480
//#include <GxGDEW075Z09/GxGDEW075Z09.h> // 7.5" b/w/r
//#include <GxGDEW075Z08/GxGDEW075Z08.h> // 7.5" b/w/r 800x480
#include GxEPD_BitmapExamples
// FreeFonts from Adafruit_GFX
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>
#include <Fonts/FreeMonoBold24pt7b.h>
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
#if defined(ESP8266)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.2\variants\generic\common.h
GxIO_Class io(SPI, /*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2); // arbitrary selection of D3(=0), D4(=2), selected for default of GxEPD_Class
GxEPD_Class display(io, /*RST=D4*/ 2, /*BUSY=D2*/ 4); // default selection of D4(=2), D2(=4)
// Heltec E-Paper 1.54" b/w without RST, BUSY
//GxEPD_Class display(io, /*RST=D4*/ -1, /*BUSY=D2*/ -1); // no RST, no BUSY
// Waveshare e-Paper ESP8266 Driver Board
//GxIO_Class io(SPI, 15, 4, 5);
//GxEPD_Class display(io, 5, 16);
#elif defined(ESP32)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\espressif\esp32\variants\lolin32\pins_arduino.h
GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16); // arbitrary selection of 17, 16
GxEPD_Class display(io, /*RST=*/ 16, /*BUSY=*/ 4); // arbitrary selection of (16), 4
// for LILYGO® TTGO T5 2.66 board uncomment next two lines instead of previous two lines
//GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 19, /*RST=*/ 4); // LILYGO® TTGO T5 2.66
//GxEPD_Class display(io, /*RST=*/ 4, /*BUSY=*/ 34); // LILYGO® TTGO T5 2.66
#elif defined(ARDUINO_ARCH_SAMD)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.19\variants\mkr1000\variant.h
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.19\variants\mkrzero\variant.h
GxIO_Class io(SPI, /*CS=*/ 4, /*DC=*/ 7, /*RST=*/ 6);
GxEPD_Class display(io, /*RST=*/ 6, /*BUSY=*/ 5);
#elif defined(ARDUINO_GENERIC_STM32F103C) && defined(MCU_STM32F103C8)
// STM32 Boards(STM32duino.com) Generic STM32F103C series STM32F103C8
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\variant.h
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\board\board.h
// new mapping suggestion for STM32F1, e.g. STM32F103C8T6 "BluePill"
// BUSY -> A1, RST -> A2, DC -> A3, CS-> A4, CLK -> A5, DIN -> A7
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 3, /*RST=*/ 2);
GxEPD_Class display(io, /*RST=*/ 2, /*BUSY=*/ 1);
#elif defined(ARDUINO_GENERIC_STM32F103V) && defined(MCU_STM32F103VB)
// STM32 Boards(STM32duino.com) Generic STM32F103V series STM32F103VB
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103vb\variant.h
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103vb\board\board.h
// Good Display DESPI-M01
// note: needs jumper wires from SS=PA4->CS, SCK=PA5->SCK, MOSI=PA7->SDI
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ PE15, /*RST=*/ PE14); // DC, RST as wired by DESPI-M01
GxEPD_Class display(io, /*RST=*/ PE14, /*BUSY=*/ PE13); // RST, BUSY as wired by DESPI-M01
#elif defined(ARDUINO_AVR_MEGA2560)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\mega\pins_arduino.h
// select one, depending on your CS connection
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
//GxIO_Class io(SPI, /*CS=*/ 10, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9, CS on 10 (for CS same as on UNO, for SPI on ICSP use)
GxEPD_Class display(io, /*RST=*/ 9, /*BUSY=*/ 7); // default selection of (9), 7
#else
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\standard\pins_arduino.h
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
GxEPD_Class display(io, /*RST=*/ 9, /*BUSY=*/ 7); // default selection of (9), 7
#endif
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println("setup");
display.init(115200); // enable diagnostic output on Serial
#if defined(__AVR) || false
display.drawPaged(drawHelloWorld);
#elif (defined(_GxGDEW075Z09_H_) || defined(_GxGDEW075Z08_H_)) && (defined(ESP8266) || defined(ARDUINO_ARCH_STM32F1))
display.drawPaged(drawHelloWorld);
#elif defined(_GxGDEW075Z09_H_)
display.drawPaged(drawHelloWorld);
#else
drawHelloWorld();
display.update();
#endif
display.powerDown();
Serial.println("setup done");
}
void loop() {};
const char HelloWorld[] = "Hello World!";
void drawHelloWorld()
{
//Serial.println("drawHelloWorld");
display.setRotation(1);
display.setFont(&FreeMonoBold9pt7b);
display.setTextColor(GxEPD_BLACK);
int16_t tbx, tby; uint16_t tbw, tbh;
display.getTextBounds(HelloWorld, 0, 0, &tbx, &tby, &tbw, &tbh);
// center bounding box by transposition of origin:
uint16_t x = ((display.width() - tbw) / 2) - tbx;
uint16_t y = ((display.height() - tbh) / 2) - tby;
display.fillScreen(GxEPD_WHITE);
display.setCursor(x, y);
display.print(HelloWorld);
//Serial.println("drawHelloWorld done");
}
void drawHelloWorldForDummies()
{
// This example function/method can be used with full buffered graphics AND/OR paged drawing graphics
// for paged drawing it is to be used as callback function
// it will be executed once or multiple times, as many as needed,
// in case of full buffer it can be called directly, or as callback
// IMPORTANT: each iteration needs to draw the same, to avoid strange effects
// use a copy of values that might change, don't read e.g. from analog or pins in the loop!
//Serial.println("drawHelloWorldForDummies");
const char text[] = "Hello World!";
// most e-papers have width < height (portrait) as native orientation, especially the small ones
// in GxEPD rotation 0 is used for native orientation (most TFT libraries use 0 fix for portrait orientation)
// set rotation to 1 (rotate right 90 degrees) to have enough space on small displays (landscape)
display.setRotation(1);
// select a suitable font in Adafruit_GFX
display.setFont(&FreeMonoBold9pt7b);
// on e-papers black on white is more pleasant to read
display.setTextColor(GxEPD_BLACK);
// Adafruit_GFX has a handy method getTextBounds() to determine the boundary box for a text for the actual font
int16_t tbx, tby; uint16_t tbw, tbh; // boundary box window
display.getTextBounds(text, 0, 0, &tbx, &tby, &tbw, &tbh); // it works for origin 0, 0, fortunately (negative tby!)
// center bounding box by transposition of origin:
uint16_t x = ((display.width() - tbw) / 2) - tbx;
uint16_t y = ((display.height() - tbh) / 2) - tby;
display.fillScreen(GxEPD_WHITE); // set the background to white (fill the buffer with value for white)
display.setCursor(x, y); // set the postition to start printing text
display.print(text); // print some text
//Serial.println("drawHelloWorldForDummies done");
}

View File

@@ -0,0 +1,29 @@
// GxEPD_MinimumExample by Jean-Marc Zingg
#include <GxEPD.h>
// select the display class to use, only one, copy from GxEPD_Example
#include <GxGDEH0154D67/GxGDEH0154D67.h> // 1.54" b/w
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
// constructor for AVR Arduino, copy from GxEPD_Example else
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
GxEPD_Class display(io, /*RST=*/ 9, /*BUSY=*/ 7); // default selection of (9), 7
void setup()
{
display.init();
display.eraseDisplay();
// comment out next line to have no or minimal Adafruit_GFX code
display.drawPaged(drawHelloWorld); // version for AVR using paged drawing, works also on other processors
}
void drawHelloWorld()
{
display.setTextColor(GxEPD_BLACK);
display.print("Hello World!");
}
void loop() {};

View File

@@ -0,0 +1,413 @@
// GxEPD_MultiDisplayExample : test example for e-Paper displays from Waveshare and from Dalian Good Display Inc.
//
// Created by Jean-Marc Zingg based on demo code from Good Display,
// available on http://www.good-display.com/download_list/downloadcategoryid=34&isMode=false.html
//
// The e-paper displays are available from:
//
// https://www.aliexpress.com/store/product/Wholesale-1-54inch-E-Ink-display-module-with-embedded-controller-200x200-Communicate-via-SPI-interface-Supports/216233_32824535312.html
//
// http://www.buy-lcd.com/index.php?route=product/product&path=2897_8363&product_id=35120
// or https://www.aliexpress.com/store/product/E001-1-54-inch-partial-refresh-Small-size-dot-matrix-e-paper-display/600281_32815089163.html
//
// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
// Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0
// mapping suggestion from Waveshare 2.9inch e-Paper to Wemos D1 mini
// BUSY -> D2, RST -> D4, DC -> D3, CS -> D8, CLK -> D5, DIN -> D7, GND -> GND, 3.3V -> 3.3V
// mapping suggestion for ESP32, e.g. LOLIN32, see .../variants/.../pins_arduino.h for your board
// NOTE: there are variants with different pins for SPI ! CHECK SPI PINS OF YOUR BOARD
// BUSY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V
// mapping suggestion for AVR, UNO, NANO etc.
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 10, CLK -> 13, DIN -> 11
// include library, include base class, make path known
#include <GxEPD.h>
// select the display classes to use
#include <GxDEPG0150BN/GxDEPG0150BN.h> // 1.50" b/w
#include <GxGDEP015OC1/GxGDEP015OC1.h> // 1.54" b/w
#include <GxGDEH0154D67/GxGDEH0154D67.h> // 1.54" b/w 200x200, SSD1681
#include <GxGDEW0154T8/GxGDEW0154T8.h> // 1.54" b/w 152x152 UC8151 (IL0373)
#include <GxGDEW0154M09/GxGDEW0154M09.h> // 1.54" b/w 200x200 JD79653A
#include <GxGDEW0154M10/GxGDEW0154M10.h> // 1.54" b/w 152x152 UC8151D
#include <GxGDEW0154Z04/GxGDEW0154Z04.h> // 1.54" b/w/r 200x200
#include <GxGDEW0154Z17/GxGDEW0154Z17.h> // 1.54" b/w/r 152x152
#include <GxGDEH0154Z90/GxGDEH0154Z90.h> // 1.54" b/w/r 200x200 SSD1681
#include <GxGDEW0213I5F/GxGDEW0213I5F.h> // 2.13" b/w 104x212 flexible
#include <GxGDE0213B1/GxGDE0213B1.h> // 2.13" b/w
#include <GxGDEH0213B72/GxGDEH0213B72.h> // 2.13" b/w new panel
#include <GxGDEH0213B73/GxGDEH0213B73.h> // 2.13" b/w newer panel
#include <GxGDEM0213B74/GxGDEM0213B74.h> // 2.13" b/w 128x250 SSD1680
#include <GxGDEW0213Z16/GxGDEW0213Z16.h> // 2.13" b/w/r
#include <GxGDEH0213Z19/GxGDEH0213Z19.h> // 2.13" b/w/r UC8151D
#include <GxGDEW0213T5D/GxGDEW0213T5D.h> // 2.13" b/w 104x212 UC8151D
#include <GxDEPG0213BN/GxDEPG0213BN.h> // 2.13" b/w 128x250, SSD1680, TTGO T5 V2.4.1, V2.3.1
#include <GxGDEH029A1/GxGDEH029A1.h> // 2.9" b/w
#include <GxGDEW029T5/GxGDEW029T5.h> // 2.9" b/w UC8151 (IL0373)
#include <GxGDEW029T5D/GxGDEW029T5D.h> // 2.9" b/w UC8151D
#include <GxGDEM029T94/GxGDEM029T94.h> // 2.9" b/w
#include <GxDEPG0290BS/GxDEPG0290BS.h> // 2.9" b/w Waveshare variant, TTGO T5 V2.4.1 2.9"
#include <GxGDEW029Z10/GxGDEW029Z10.h> // 2.9" b/w/r
#include <GxGDEH029Z13/GxGDEH029Z13.h> // 2.9" b/w/r UC8151D
#include <GxGDEW026T0/GxGDEW026T0.h> // 2.6" b/w
#include <GxDEPG0266BN/GxDEPG0266BN.h> // 2.66" b/w 152x296, SSD1680, TTGO T5 V2.66, TTGO T5 V2.4.1
#include <GxGDEW027C44/GxGDEW027C44.h> // 2.7" b/w/r
#include <GxGDEW027W3/GxGDEW027W3.h> // 2.7" b/w
#include <GxGDEY027T91/GxGDEY027T91.h> // 2.7" b/w
#include <GxGDEW0371W7/GxGDEW0371W7.h> // 3.7" b/w
#include <GxGDEW042T2/GxGDEW042T2.h> // 4.2" b/w
#include <GxGDEW042Z15/GxGDEW042Z15.h> // 4.2" b/w/r
#include <GxGDEW0583T7/GxGDEW0583T7.h> // 5.83" b/w
#include <GxGDEW075T8/GxGDEW075T8.h> // 7.5" b/w
#include <GxGDEW075T7/GxGDEW075T7.h> // 7.5" b/w 800x480
#include <GxGDEW075Z09/GxGDEW075Z09.h> // 7.5" b/w/r
#include <GxGDEW075Z08/GxGDEW075Z08.h> // 7.5" b/w/r 800x480
// FreeFonts from Adafruit_GFX
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>
#include <Fonts/FreeMonoBold24pt7b.h>
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
#if defined(ESP8266)
// create GxIO_SPI instances for each display, each instance with different CS line;
// disable reset line to disable cross resets by multiple instances
// GxIO_SPI(SPIClass& spi, int8_t cs, int8_t dc, int8_t rst = -1, int8_t bl = -1);
GxIO_SPI io1(SPI, 15, 2, -1); // CS = D8(15), DC = D4(2), RST disabled
GxIO_SPI io2(SPI, 16, 2, -1); // CS = D0(16), DC = D4(2), RST disabled
GxIO_SPI io3(SPI, 5, 2, -1); // CS = D1(5), DC = D4(2), RST disabled
// create display class instances for each display, each instance with different BUSY line, or BUSY lines or-ed to one pin
// GxGDEP015OC1(GxIO& io, int8_t rst = 2, int8_t busy = 4);
//GxGDEP015OC1 display1(io1, -1, 4); // RST disabled, BUSY = D2(4)
//GxGDEH029A1 display2(io2, -1, 12); // RST disabled, BUSY = D6(12)
// BUSY lines can be or-ed with diodes and pulldown register for displays with BUSY active HIGH
GxGDEP015OC1 display1(io1, -1, 4); // RST disabled, BUSY = D2(4)
GxGDEH029A1 display2(io2, -1, 4); // RST disabled, BUSY = D2(4)
GxGDE0213B1 display3(io3, -1, 4); // RST disabled, BUSY = D2(4)
#define RST_PIN 0 // D3(0)
#elif defined(ESP32)
// create GxIO_SPI instances for each display, each instance with different CS line;
// disable reset line to disable cross resets by multiple instances
// GxIO_SPI(SPIClass& spi, int8_t cs, int8_t dc, int8_t rst = -1, int8_t bl = -1);
GxIO_Class io1(SPI, 5, 17, -1); // CS = 5(SS), DC = 17, RST disabled
GxIO_Class io2(SPI, 0, 17, -1); // CS = 0, DC = 17, RST disabled
GxIO_Class io3(SPI, 2, 17, -1); // CS = 2, DC = 17, RST disabled
GxIO_Class io4(SPI, 13, 17, -1); // CS = 13, DC = 17, RST disabled
// create display class instances for each display, each instance with different BUSY line, or BUSY lines or-ed to one pin
// GxGDEP015OC1(GxIO& io, int8_t rst = D4, int8_t busy = D2);
// BUSY lines can be or-ed with diodes and pulldown resistor for displays with BUSY active HIGH
GxGDEP015OC1 display1(io1, -1, 4); // BUSY = 4, or-ed
GxGDEH029A1 display2(io2, -1, 4); // BUSY = 4, or-ed
GxGDE0213B1 display3(io3, -1, 4); // BUSY = 4, or-ed
// BUSY lines can be or-ed with diodes and pulldown resistor for displays with BUSY active LOW
//GxGDEW027C44 display4(io4, -1, 15); // BUSY = 15, active LOW
//GxGDEW029Z10 display4(io4, -1, 15); // BUSY = 15, or-ed
GxGDEW042T2 display4(io4, -1, 15); // BUSY = 15, or-ed
//GxGDEW075T8 display4(io4, -1, 15); // BUSY = 15, or-ed
//GxGDEW0154Z04 display4(io4, -1, 15); // BUSY = 15, or-ed
//GxGDEW0213Z16 display4(io4, -1, 15); // BUSY = 15, or-ed
#define RST_PIN 16
#endif
#if defined(_GxGDEP015OC1_H_)
namespace BMxGDEP015OC1
{
#include "GxGDEP015OC1/BitmapExamples.h"
void showBitmapExample(GxEPD& display)
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(2000);
display.setRotation(0);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxGDEP015OC1_WIDTH, GxGDEP015OC1_HEIGHT, GxEPD_BLACK);
display.update();
delay(2000);
}
// fix this later
#undef BitmapExample1
#undef BitmapExample2
#undef _GxBitmapExamples_H_
}
#endif
#if defined(_GxGDEW0154Z04_H_)
namespace BMxGDEW0154Z04
{
#include "GxGDEW0154Z04/BitmapExamples.h"
void showBitmapExample(GxEPD& display)
{
display.drawPicture(BitmapWaveshare_black, BitmapWaveshare_red, sizeof(BitmapWaveshare_black), sizeof(BitmapWaveshare_red), GxEPD::bm_normal);
delay(2000);
display.drawExamplePicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
delay(2000);
}
// fix this later
#undef BitmapExample1
#undef BitmapExample2
#undef _BitmapWaveshare_H_
#undef _GxBitmapExamples_H_
}
#endif
#if defined(_GxGDE0213B1_H_)
namespace BMxGDE0213B1
{
#include "GxGDE0213B1/BitmapExamples.h"
void showBitmapExample(GxEPD& display)
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(2000);
display.setRotation(0);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxGDE0213B1_WIDTH, GxGDE0213B1_HEIGHT, GxEPD_BLACK);
display.update();
delay(2000);
}
#undef _GxBitmapExamples_H_
}
#endif
#if defined(_GxGDEW0213Z16_H_)
namespace BMxGDEW0213Z16
{
#include "GxGDEW0213Z16/BitmapExamples.h"
void showBitmapExample(GxEPD& display)
{
display.drawPicture(BitmapWaveshare_black, BitmapWaveshare_red, sizeof(BitmapWaveshare_black), sizeof(BitmapWaveshare_red));
delay(2000);
display.drawExamplePicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
delay(2000);
display.drawExamplePicture(BitmapExample3, BitmapExample4, sizeof(BitmapExample3), sizeof(BitmapExample4));
delay(2000);
display.drawExampleBitmap(BitmapWaveshare_black, sizeof(BitmapWaveshare_black));
delay(2000);
// example bitmaps for b/w/r are normal on b/w, but inverted on red
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2), GxEPD::bm_invert);
delay(2000);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxGDEW0213Z16_WIDTH, GxGDEW0213Z16_HEIGHT, GxEPD_BLACK);
display.update();
delay(2000);
}
#undef _BitmapWaveshare_H_
#undef _GxBitmapExamples_H_
}
#endif
#if defined(_GxGDEH029A1_H_)
namespace BMxGDEH029A1
{
#include "GxGDEH029A1/BitmapExamples.h"
void showBitmapExample(GxEPD& display)
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(2000);
display.setRotation(0);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxGDEH029A1_WIDTH, GxGDEH029A1_HEIGHT, GxEPD_BLACK);
display.update();
delay(2000);
}
#undef _BitmapWaveshare_H_
#undef _GxBitmapExamples_H_
}
#endif
#if defined(_GxGDEW029Z10_H_)
namespace BMxGDEW029Z10
{
#include "GxGDEW029Z10/BitmapExamples.h"
void showBitmapExample(GxEPD& display)
{
display.drawPicture(BitmapWaveshare_black, BitmapWaveshare_red, sizeof(BitmapWaveshare_black), sizeof(BitmapWaveshare_red));
delay(2000);
display.drawExamplePicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
delay(2000);
display.drawExamplePicture(BitmapExample3, BitmapExample4, sizeof(BitmapExample3), sizeof(BitmapExample4));
delay(2000);
display.drawExampleBitmap(BitmapWaveshare_black, sizeof(BitmapWaveshare_black));
delay(2000);
// example bitmaps for b/w/r are normal on b/w, but inverted on red
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2), GxEPD::bm_invert);
delay(2000);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxGDEW029Z10_WIDTH, GxGDEW029Z10_HEIGHT, GxEPD_BLACK);
display.update();
delay(2000);
}
#undef _BitmapWaveshare_H_
#undef _GxBitmapExamples_H_
}
#endif
#if defined(_GxGDEW027C44_H_)
namespace BMxGDEW027C44
{
#include "GxGDEW027C44/BitmapExamples.h"
void showBitmapExample(GxEPD& display)
{
// draw black and red bitmap
display.drawExamplePicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
delay(2000);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxGDEW027C44_WIDTH, GxGDEW027C44_HEIGHT, GxEPD_BLACK);
display.update();
delay(2000);
}
#undef _GxBitmapExamples_H_
}
#endif
#if defined(_GxGDEW042T2_H_)
namespace BMxGDEW042T2
{
#include "GxGDEW042T2/BitmapExamples.h"
void showBitmapExample(GxEPD& display)
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(2000);
display.setRotation(0);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxGDEW042T2_WIDTH, GxGDEW042T2_HEIGHT, GxEPD_BLACK);
display.update();
delay(2000);
}
#undef _GxBitmapExamples_H_
}
#endif
#if defined(_GxGDEW042T2_FPU_H_)
namespace BMxGDEW042T2_FPU
{
#include "GxGDEW042T2_FPU/BitmapExamples.h"
void showBitmapExample(GxEPD& display)
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(2000);
display.setRotation(0);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxGDEW042T2_FPU_WIDTH, GxGDEW042T2_FPU_HEIGHT, GxEPD_BLACK);
display.update();
delay(2000);
}
#undef _GxBitmapExamples_H_
}
#endif
#if defined(_GxGDEW075T8_H_)
namespace BMxGDEW075T8
{
#include "GxGDEW075T8/BitmapExamples.h"
void showBitmapExample(GxEPD& display)
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
display.drawExampleBitmap(BitmapExample2, sizeof(BitmapExample2));
delay(2000);
display.setRotation(0);
display.fillScreen(GxEPD_WHITE);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxGDEW075T8_WIDTH, GxGDEW075T8_HEIGHT, GxEPD_BLACK);
display.update();
delay(2000);
}
#undef _GxBitmapExamples_H_
}
#endif
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println("setup");
// one common reset for all displays
pinMode(RST_PIN, OUTPUT);
digitalWrite(RST_PIN, LOW);
delay(20);
digitalWrite(RST_PIN, HIGH);
delay(20);
display1.init(115200); // enable diagnostic output on Serial
display2.init(115200); // enable diagnostic output on Serial
display3.init(115200); // enable diagnostic output on Serial
#if defined(ESP32)
display4.init(115200); // enable diagnostic output on Serial
#endif
Serial.println("setup done");
}
void loop()
{
Serial.println("BMxGDEP015OC1::showBitmapExample(display1)");
BMxGDEP015OC1::showBitmapExample(display1);
Serial.println("BMxGDEH029A1::showBitmapExample(display2)");
BMxGDEH029A1::showBitmapExample(display2);
Serial.println("BMxGDE0213B1::showBitmapExample(display3)");
BMxGDE0213B1::showBitmapExample(display3);
Serial.println("showFont(display1, \"FreeMonoBold9pt7b\", &FreeMonoBold9pt7b)");
showFont(display1, "FreeMonoBold9pt7b", &FreeMonoBold9pt7b);
Serial.println("showFont(display2, \"FreeMonoBold9pt7b\", &FreeMonoBold9pt7b)");
showFont(display2, "FreeMonoBold9pt7b", &FreeMonoBold9pt7b);
Serial.println("showFont(display3, \"FreeMonoBold9pt7b\", &FreeMonoBold9pt7b)");
showFont(display3, "FreeMonoBold9pt7b", &FreeMonoBold9pt7b);
#if defined(ESP32)
//Serial.println("BMxGDEW027C44::showBitmapExample(display4)");
//BMxGDEW027C44::showBitmapExample(display4);
Serial.println("BMxGDEW042T2::showBitmapExample(display4)");
BMxGDEW042T2::showBitmapExample(display4);
Serial.println("showFont(display4, \"FreeMonoBold9pt7b\", &FreeMonoBold9pt7b)");
showFont(display4, "FreeMonoBold9pt7b", &FreeMonoBold9pt7b);
#endif
delay(10000);
}
void showFont(GxEPD& display, const char name[], const GFXfont* f)
{
display.fillScreen(GxEPD_WHITE);
display.setTextColor(GxEPD_BLACK);
display.setFont(f);
display.setCursor(0, 0);
display.println();
display.println(name);
display.println(" !\"#$%&'()*+,-./");
display.println("0123456789:;<=>?");
display.println("@ABCDEFGHIJKLMNO");
display.println("PQRSTUVWXYZ[\\]^_");
#if defined(_GxGDEW0154Z04_H_) || defined(_GxGDEW0213Z16_H_) || defined(_GxGDEW029Z10_H_) || defined(_GxGDEW027C44_H_)
display.setTextColor(GxEPD_RED);
#endif
display.println("`abcdefghijklmno");
display.println("pqrstuvwxyz{|}~ ");
display.update();
delay(5000);
}

View File

@@ -0,0 +1,520 @@
// GxEPD_SD_Example : test example for e-Paper displays from Waveshare and from Dalian Good Display Inc.
//
// Created by Jean-Marc Zingg based on demo code from Good Display,
// available on http://www.good-display.com/download_list/downloadcategoryid=34&isMode=false.html
//
// The e-paper displays are available from:
//
// https://www.aliexpress.com/store/product/Wholesale-1-54inch-E-Ink-display-module-with-embedded-controller-200x200-Communicate-via-SPI-interface-Supports/216233_32824535312.html
//
// http://www.buy-lcd.com/index.php?route=product/product&path=2897_8363&product_id=35120
// or https://www.aliexpress.com/store/product/E001-1-54-inch-partial-refresh-Small-size-dot-matrix-e-paper-display/600281_32815089163.html
//
// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
// Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0
// mapping suggestion from Waveshare SPI e-Paper to Wemos D1 mini
// BUSY -> D2, RST -> D4, DC -> D3, CS -> D8, CLK -> D5, DIN -> D7, GND -> GND, 3.3V -> 3.3V
// mapping suggestion from Waveshare SPI e-Paper to generic ESP8266
// BUSY -> GPIO4, RST -> GPIO2, DC -> GPIO0, CS -> GPIO15, CLK -> GPIO14, DIN -> GPIO13, GND -> GND, 3.3V -> 3.3V
// mapping suggestion for ESP32, e.g. LOLIN32, see .../variants/.../pins_arduino.h for your board
// NOTE: there are variants with different pins for SPI ! CHECK SPI PINS OF YOUR BOARD
// BUSY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V
// new mapping suggestion for STM32F1, e.g. STM32F103C8T6 "BluePill"
// BUSY -> A1, RST -> A2, DC -> A3, CS-> A4, CLK -> A5, DIN -> A7
// mapping suggestion for AVR, UNO, NANO etc.
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 10, CLK -> 13, DIN -> 11
//
// **** NOTE that the mapping suggestion may need modification depending on SD board used! ****
// ********************************************************************************************
//
// **** NOTE: does not compile for small RAM AVR, not enough RAM. Not tested on MEGA.
#include <SPI.h>
#if defined(ESP32)
#define SD_CS 2
#define EPD_CS SS
// has support for FAT32 support with long filenames
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#define SdFile File
#define seekSet seek
#elif defined(ESP8266)
#define SD_CS SS // e.g. for RobotDyn Wemos D1 mini SD board
#define EPD_CS D1 // alternative I use with RobotDyn Wemos D1 mini SD board
// include SdFat for FAT32 support with long filenames; available through Library Manager
#include <SdFat.h>
SdFat SD;
#else
#define SD_CS 6
#define EPD_CS SS
// include SdFat for FAT32 support with long filenames; available through Library Manager
#include <SdFat.h>
SdFat SD;
#endif
// include library, include base class, make path known
#include <GxEPD.h>
// select the display class to use, only one
//#include <GxDEPG0150BN/GxDEPG0150BN.h> // 1.50" b/w
//#include <GxGDEP015OC1/GxGDEP015OC1.h> // 1.54" b/w
//#include <GxGDEH0154D67/GxGDEH0154D67.h> // 1.54" b/w 200x200, SSD1681
//#include <GxGDEW0154T8/GxGDEW0154T8.h> // 1.54" b/w 152x152 UC8151 (IL0373)
//#include <GxGDEW0154M09/GxGDEW0154M09.h> // 1.54" b/w 200x200 JD79653A
//#include <GxGDEW0154M10/GxGDEW0154M10.h> // 1.54" b/w 152x152 UC8151D
//#include <GxGDEW0154Z04/GxGDEW0154Z04.h> // 1.54" b/w/r 200x200
//#include <GxGDEW0154Z17/GxGDEW0154Z17.h> // 1.54" b/w/r 152x152
//#include <GxGDEH0154Z90/GxGDEH0154Z90.h> // 1.54" b/w/r 200x200 SSD1681
//#include <GxGDEW0213I5F/GxGDEW0213I5F.h> // 2.13" b/w 104x212 flexible
//#include <GxGDE0213B1/GxGDE0213B1.h> // 2.13" b/w
//#include <GxGDEH0213B72/GxGDEH0213B72.h> // 2.13" b/w new panel
//#include <GxGDEH0213B73/GxGDEH0213B73.h> // 2.13" b/w newer panel
//#include <GxGDEM0213B74/GxGDEM0213B74.h> // 2.13" b/w 128x250 SSD1680
//#include <GxGDEW0213Z16/GxGDEW0213Z16.h> // 2.13" b/w/r
//#include <GxGDEH0213Z19/GxGDEH0213Z19.h> // 2.13" b/w/r UC8151D
//#include <GxGDEW0213T5D/GxGDEW0213T5D.h> // 2.13" b/w 104x212 UC8151D
//#include <GxDEPG0213BN/GxDEPG0213BN.h> // 2.13" b/w 128x250, SSD1680, TTGO T5 V2.4.1, V2.3.1
//#include <GxGDEH029A1/GxGDEH029A1.h> // 2.9" b/w
//#include <GxGDEW029T5/GxGDEW029T5.h> // 2.9" b/w UC8151 (IL0373)
//#include <GxGDEW029T5D/GxGDEW029T5D.h> // 2.9" b/w UC8151D
//#include <GxGDEM029T94/GxGDEM029T94.h> // 2.9" b/w
//#include <GxDEPG0290BS/GxDEPG0290BS.h> // 2.9" b/w Waveshare variant, TTGO T5 V2.4.1 2.9"
//#include <GxGDEW029Z10/GxGDEW029Z10.h> // 2.9" b/w/r
//#include <GxGDEH029Z13/GxGDEH029Z13.h> // 2.9" b/w/r UC8151D
//#include <GxGDEW026T0/GxGDEW026T0.h> // 2.6" b/w
//#include <GxDEPG0266BN/GxDEPG0266BN.h> // 2.66" b/w 152x296, SSD1680, TTGO T5 V2.66, TTGO T5 V2.4.1
//#include <GxGDEW027C44/GxGDEW027C44.h> // 2.7" b/w/r
//#include <GxGDEW027W3/GxGDEW027W3.h> // 2.7" b/w
//#include <GxGDEY027T91/GxGDEY027T91.h> // 2.7" b/w
//#include <GxGDEW0371W7/GxGDEW0371W7.h> // 3.7" b/w
//#include <GxGDEW042T2/GxGDEW042T2.h> // 4.2" b/w
//#include <GxGDEW042Z15/GxGDEW042Z15.h> // 4.2" b/w/r
//#include <GxGDEW0583T7/GxGDEW0583T7.h> // 5.83" b/w
//#include <GxGDEW075T8/GxGDEW075T8.h> // 7.5" b/w
//#include <GxGDEW075T7/GxGDEW075T7.h> // 7.5" b/w 800x480
//#include <GxGDEW075Z09/GxGDEW075Z09.h> // 7.5" b/w/r
//#include <GxGDEW075Z08/GxGDEW075Z08.h> // 7.5" b/w/r 800x480
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
#if defined(ESP8266)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.2\variants\generic\common.h
GxIO_Class io(SPI, /*CS=D8*/ EPD_CS, /*DC=D3*/ 0, /*RST=D4*/ 2); // arbitrary selection of D3(=0), D4(=2), selected for default of GxEPD_Class
GxEPD_Class display(io /*RST=D4*/ /*BUSY=D2*/); // default selection of D4(=2), D2(=4)
// Heltec E-Paper 1.54" b/w without RST, BUSY
//GxEPD_Class display(io, /*RST=D4*/ -1, /*BUSY=D2*/ -1); // no RST, no BUSY
#elif defined(ESP32)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\espressif\esp32\variants\lolin32\pins_arduino.h
// for LILYGO® TTGO T5 2.66 board uncomment next two lines instead of previous two lines
//GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 19, /*RST=*/ 4); // LILYGO® TTGO T5 2.66
//GxEPD_Class display(io, /*RST=*/ 4, /*BUSY=*/ 34); // LILYGO® TTGO T5 2.66
GxIO_Class io(SPI, /*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16); // arbitrary selection of 17, 16
GxEPD_Class display(io, /*RST=*/ 16, /*BUSY=*/ 4); // arbitrary selection of (16), 4
#elif defined(ARDUINO_ARCH_SAMD)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.19\variants\mkr1000\variant.h
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.19\variants\mkrzero\variant.h
GxIO_Class io(SPI, /*CS=*/ EPD_CS, /*DC=*/ 7, /*RST=*/ 6);
GxEPD_Class display(io, /*RST=*/ 6, /*BUSY=*/ 5);
#elif defined(ARDUINO_GENERIC_STM32F103C) && defined(MCU_STM32F103C8)
// STM32 Boards(STM32duino.com) Generic STM32F103C series STM32F103C8
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\variant.h
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\board\board.h
// new mapping suggestion for STM32F1, e.g. STM32F103C8T6 "BluePill"
// BUSY -> A1, RST -> A2, DC -> A3, CS-> A4, CLK -> A5, DIN -> A7
GxIO_Class io(SPI, /*CS=*/ EPD_CS, /*DC=*/ 3, /*RST=*/ 2);
GxEPD_Class display(io, /*RST=*/ 2, /*BUSY=*/ 1);
#elif defined(ARDUINO_GENERIC_STM32F103V) && defined(MCU_STM32F103VB)
// STM32 Boards(STM32duino.com) Generic STM32F103V series STM32F103VB
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103vb\variant.h
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103vb\board\board.h
// Good Display DESPI-M01
// note: needs jumper wires from SS=PA4->CS, SCK=PA5->SCK, MOSI=PA7->SDI
GxIO_Class io(SPI, /*CS=*/ EPD_CS, /*DC=*/ PE15, /*RST=*/ PE14); // DC, RST as wired by DESPI-M01
GxEPD_Class display(io, /*RST=*/ PE14, /*BUSY=*/ PE13); // RST, BUSY as wired by DESPI-M01
#else
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\standard\pins_arduino.h
GxIO_Class io(SPI, /*CS=*/ EPD_CS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
GxEPD_Class display(io /*RST=9*/ /*BUSY=7*/); // default selection of (9), 7
#endif
// function declaration with default parameter
void drawBitmapFromSD(const char *filename, int16_t x, int16_t y, bool with_color = true);
void setup(void)
{
Serial.begin(115200);
Serial.println();
Serial.println("GxEPD_SD_Example");
display.init(115200); // enable diagnostic output on Serial
Serial.print("Initializing SD card...");
if (!SD.begin(SD_CS))
{
Serial.println("SD failed!");
return;
}
Serial.println("SD OK!");
drawBitmaps_200x200();
drawBitmaps_other();
//drawBitmaps_test();
Serial.println("GxEPD_SD_Example done");
}
void loop()
{
}
void drawBitmaps_200x200()
{
int16_t x = (display.width() - 200) / 2;
int16_t y = (display.height() - 200) / 2;
drawBitmapFromSD("logo200x200.bmp", x, y);
delay(2000);
drawBitmapFromSD("first200x200.bmp", x, y);
delay(2000);
drawBitmapFromSD("second200x200.bmp", x, y);
delay(2000);
drawBitmapFromSD("third200x200.bmp", x, y);
delay(2000);
drawBitmapFromSD("fourth200x200.bmp", x, y);
delay(2000);
drawBitmapFromSD("fifth200x200.bmp", x, y);
delay(2000);
drawBitmapFromSD("sixth200x200.bmp", x, y);
delay(2000);
drawBitmapFromSD("seventh200x200.bmp", x, y);
delay(2000);
drawBitmapFromSD("eighth200x200.bmp", x, y);
delay(2000);
}
void drawBitmaps_other()
{
int16_t w2 = display.width() / 2;
int16_t h2 = display.height() / 2;
drawBitmapFromSD("parrot.bmp", w2 - 64, h2 - 80);
delay(2000);
drawBitmapFromSD("betty_1.bmp", w2 - 100, h2 - 160);
delay(2000);
drawBitmapFromSD("betty_4.bmp", w2 - 102, h2 - 126);
delay(2000);
drawBitmapFromSD("marilyn_240x240x8.bmp", w2 - 120, h2 - 120);
delay(2000);
drawBitmapFromSD("miniwoof.bmp", w2 - 60, h2 - 80);
delay(2000);
drawBitmapFromSD("t200x200.bmp", w2 - 100, h2 - 100);
delay(2000);
drawBitmapFromSD("test.bmp", w2 - 120, h2 - 160);
delay(2000);
drawBitmapFromSD("tiger.bmp", w2 - 160, h2 - 120);
delay(2000);
drawBitmapFromSD("tiger_178x160x4.bmp", w2 - 89, h2 - 80);
delay(2000);
drawBitmapFromSD("tiger_240x317x4.bmp", w2 - 120, h2 - 160);
delay(2000);
drawBitmapFromSD("tiger_320x200x24.bmp", w2 - 160, h2 - 100);
delay(2000);
drawBitmapFromSD("tiger16T.bmp", w2 - 160, h2 - 120);
delay(2000);
drawBitmapFromSD("woof.bmp", w2 - 120, h2 - 160);
delay(2000);
drawBitmapFromSD("bitmap640x384_1.bmp", 0, 0);
delay(2000);
}
void drawBitmaps_test()
{
int16_t w2 = display.width() / 2;
int16_t h2 = display.height() / 2;
drawBitmapFromSD("betty_4.bmp", w2 - 102, h2 - 126);
delay(2000);
drawBitmapFromSD("bb4.bmp", 0, 0);
delay(2000);
}
static const uint16_t input_buffer_pixels = 20; // may affect performance
static const uint16_t max_palette_pixels = 256; // for depth <= 8
uint8_t input_buffer[3 * input_buffer_pixels]; // up to depth 24
uint8_t mono_palette_buffer[max_palette_pixels / 8]; // palette buffer for depth <= 8 b/w
uint8_t color_palette_buffer[max_palette_pixels / 8]; // palette buffer for depth <= 8 c/w
void drawBitmapFrom_SD_ToBuffer(const char *filename, int16_t x, int16_t y, bool with_color)
{
SdFile file;
bool valid = false; // valid format to be handled
bool flip = true; // bitmap is stored bottom-to-top
uint32_t startTime = millis();
if ((x >= display.width()) || (y >= display.height())) return;
Serial.println();
Serial.print("Loading image '");
Serial.print(filename);
Serial.println('\'');
#if defined(ESP32)
file = SD.open(String("/") + filename, FILE_READ);
if (!file)
{
Serial.print("File not found");
return;
}
#else
if (!file.open(filename, FILE_READ))
{
Serial.print("File not found");
return;
}
#endif
// Parse BMP header
if (read16(file) == 0x4D42) // BMP signature
{
int32_t fileSize = read32(file);
int32_t creatorBytes = read32(file);
int32_t imageOffset = read32(file); // Start of image data
int32_t headerSize = read32(file);
int32_t width = read32(file);
int32_t height = read32(file);
uint16_t planes = read16(file);
uint16_t depth = read16(file); // bits per pixel
int32_t format = read32(file);
(void) creatorBytes;
if ((planes == 1) && ((format == 0) || (format == 3))) // uncompressed is handled, 565 also
{
Serial.print("File size: "); Serial.println(fileSize);
Serial.print("Image Offset: "); Serial.println(imageOffset);
Serial.print("Header size: "); Serial.println(headerSize);
Serial.print("Bit Depth: "); Serial.println(depth);
Serial.print("Image size: ");
Serial.print(width);
Serial.print('x');
Serial.println(height);
// BMP rows are padded (if needed) to 4-byte boundary
int32_t rowSize = (width * depth / 8 + 3) & ~3;
if (depth < 8) rowSize = ((width * depth + 8 - depth) / 8 + 3) & ~3;
if (height < 0)
{
height = -height;
flip = false;
}
uint16_t w = width;
uint16_t h = height;
if ((x + w - 1) >= display.width()) w = display.width() - x;
if ((y + h - 1) >= display.height()) h = display.height() - y;
valid = true;
uint8_t bitmask = 0xFF;
uint8_t bitshift = 8 - depth;
uint16_t red, green, blue;
bool whitish = false;
bool colored = false;
if (depth == 1) with_color = false;
if (depth <= 8)
{
if (depth < 8) bitmask >>= depth;
//file.seekSet(54); //palette is always @ 54
file.seekSet(imageOffset - (4 << depth)); // 54 for regular, diff for colorsimportant
for (uint16_t pn = 0; pn < (1 << depth); pn++)
{
blue = file.read();
green = file.read();
red = file.read();
file.read();
whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
if (0 == pn % 8) mono_palette_buffer[pn / 8] = 0;
mono_palette_buffer[pn / 8] |= whitish << pn % 8;
if (0 == pn % 8) color_palette_buffer[pn / 8] = 0;
color_palette_buffer[pn / 8] |= colored << pn % 8;
}
}
display.fillScreen(GxEPD_WHITE);
int32_t rowPosition = flip ? imageOffset + (height - h) * rowSize : imageOffset;
for (uint16_t row = 0; row < h; row++, rowPosition += rowSize) // for each line
{
uint32_t in_remain = rowSize;
uint32_t in_idx = 0;
uint32_t in_bytes = 0;
uint8_t in_byte = 0; // for depth <= 8
uint8_t in_bits = 0; // for depth <= 8
uint16_t color = GxEPD_WHITE;
file.seekSet(rowPosition);
for (uint16_t col = 0; col < w; col++) // for each pixel
{
// Time to read more pixel data?
if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
{
in_bytes = file.read(input_buffer, in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain);
in_remain -= in_bytes;
in_idx = 0;
}
switch (depth)
{
case 24:
blue = input_buffer[in_idx++];
green = input_buffer[in_idx++];
red = input_buffer[in_idx++];
whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
break;
case 16:
{
uint8_t lsb = input_buffer[in_idx++];
uint8_t msb = input_buffer[in_idx++];
if (format == 0) // 555
{
blue = (lsb & 0x1F) << 3;
green = ((msb & 0x03) << 6) | ((lsb & 0xE0) >> 2);
red = (msb & 0x7C) << 1;
}
else // 565
{
blue = (lsb & 0x1F) << 3;
green = ((msb & 0x07) << 5) | ((lsb & 0xE0) >> 3);
red = (msb & 0xF8);
}
whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
}
break;
case 1:
case 4:
case 8:
{
if (0 == in_bits)
{
in_byte = input_buffer[in_idx++];
in_bits = 8;
}
uint16_t pn = (in_byte >> bitshift) & bitmask;
whitish = mono_palette_buffer[pn / 8] & (0x1 << pn % 8);
colored = color_palette_buffer[pn / 8] & (0x1 << pn % 8);
in_byte <<= depth;
in_bits -= depth;
}
break;
}
if (whitish)
{
color = GxEPD_WHITE;
}
else if (colored && with_color)
{
color = GxEPD_RED;
}
else
{
color = GxEPD_BLACK;
}
uint16_t yrow = y + (flip ? h - row - 1 : row);
display.drawPixel(x + col, yrow, color);
} // end pixel
} // end line
Serial.print("loaded in "); Serial.print(millis() - startTime); Serial.println(" ms");
}
}
file.close();
if (!valid)
{
Serial.println("bitmap format not handled.");
}
}
#if defined(__AVR) //|| true
struct Parameters
{
const char* filename;
int16_t x;
int16_t y;
bool with_color;
};
void drawBitmapFrom_SD_ToBuffer_Callback(const void* params)
{
const Parameters* p = reinterpret_cast<const Parameters*>(params);
drawBitmapFrom_SD_ToBuffer(p->filename, p->x, p->y, p->with_color);
}
void drawBitmapFromSD(const char *filename, int16_t x, int16_t y, bool with_color)
{
Parameters parameters{filename, x, y, with_color};
display.drawPaged(drawBitmapFrom_SD_ToBuffer_Callback, &parameters);
}
#else
void drawBitmapFromSD(const char *filename, int16_t x, int16_t y, bool with_color)
{
drawBitmapFrom_SD_ToBuffer(filename, x, y, with_color);
display.update();
}
#endif
uint16_t read16(SdFile& f)
{
// BMP data is stored little-endian, same as Arduino.
uint16_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read(); // MSB
return result;
}
int32_t read32(SdFile& f)
{
// BMP data is stored little-endian, same as Arduino.
int32_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read();
((uint8_t *)&result)[2] = f.read();
((uint8_t *)&result)[3] = f.read(); // MSB
return result;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@@ -0,0 +1,865 @@
// GxEPD_WiFi_Example : Display Library example for SPI e-paper panels from Dalian Good Display and boards from Waveshare.
// Requires HW SPI and Adafruit_GFX. Caution: these e-papers 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
//
// BMP handling code extracts taken from: https://github.com/prenticedavid/MCUFRIEND_kbv/tree/master/examples/showBMP_kbv_Uno
//
// Author: Jean-Marc Zingg
//
// Version: see library.properties
//
// Library: https://github.com/ZinggJM/GxEPD
// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
// Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0
// mapping suggestion from Waveshare SPI e-Paper to Wemos D1 mini
// BUSY -> D2, RST -> D4, DC -> D3, CS -> D8, CLK -> D5, DIN -> D7, GND -> GND, 3.3V -> 3.3V
// mapping suggestion from Waveshare SPI e-Paper to generic ESP8266
// BUSY -> GPIO4, RST -> GPIO2, DC -> GPIO0, CS -> GPIO15, CLK -> GPIO14, DIN -> GPIO13, GND -> GND, 3.3V -> 3.3V
// mapping of Waveshare e-Paper ESP8266 Driver Board
// BUSY -> GPIO16, RST -> GPIO5, DC -> GPIO4, CS -> GPIO15, CLK -> GPIO14, DIN -> GPIO13, GND -> GND, 3.3V -> 3.3V
// mapping suggestion for ESP32, e.g. LOLIN32, see .../variants/.../pins_arduino.h for your board
// NOTE: there are variants with different pins for SPI ! CHECK SPI PINS OF YOUR BOARD
// BUSY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V
// new mapping suggestion for STM32F1, e.g. STM32F103C8T6 "BluePill"
// BUSY -> A1, RST -> A2, DC -> A3, CS-> A4, CLK -> A5, DIN -> A7
// mapping suggestion for AVR, UNO, NANO etc.
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 10, CLK -> 13, DIN -> 11
//
// mapping suggestion for Arduino MEGA
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 53, CLK -> 52, DIN -> 51
// mapping suggestion for Arduino DUE
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 77, CLK -> 76, DIN -> 75
// SPI pins are also on 6 pin 2x3 SPI header
// include library, include base class, make path known
#include <GxEPD.h>
// select the display class to use, only one
//#include <GxDEPG0150BN/GxDEPG0150BN.h> // 1.50" b/w
//#include <GxGDEP015OC1/GxGDEP015OC1.h> // 1.54" b/w
//#include <GxGDEH0154D67/GxGDEH0154D67.h> // 1.54" b/w 200x200, SSD1681
//#include <GxGDEW0154T8/GxGDEW0154T8.h> // 1.54" b/w 152x152 UC8151 (IL0373)
//#include <GxGDEW0154M09/GxGDEW0154M09.h> // 1.54" b/w 200x200 JD79653A
//#include <GxGDEW0154M10/GxGDEW0154M10.h> // 1.54" b/w 152x152 UC8151D
//#include <GxGDEW0154Z04/GxGDEW0154Z04.h> // 1.54" b/w/r 200x200
//#include <GxGDEW0154Z17/GxGDEW0154Z17.h> // 1.54" b/w/r 152x152
//#include <GxGDEH0154Z90/GxGDEH0154Z90.h> // 1.54" b/w/r 200x200 SSD1681
//#include <GxGDEW0213I5F/GxGDEW0213I5F.h> // 2.13" b/w 104x212 flexible
//#include <GxGDE0213B1/GxGDE0213B1.h> // 2.13" b/w
//#include <GxGDEH0213B72/GxGDEH0213B72.h> // 2.13" b/w new panel
//#include <GxGDEH0213B73/GxGDEH0213B73.h> // 2.13" b/w newer panel
//#include <GxGDEM0213B74/GxGDEM0213B74.h> // 2.13" b/w 128x250 SSD1680
//#include <GxGDEW0213Z16/GxGDEW0213Z16.h> // 2.13" b/w/r
//#include <GxGDEH0213Z19/GxGDEH0213Z19.h> // 2.13" b/w/r UC8151D
//#include <GxGDEW0213T5D/GxGDEW0213T5D.h> // 2.13" b/w 104x212 UC8151D
//#include <GxDEPG0213BN/GxDEPG0213BN.h> // 2.13" b/w 128x250, SSD1680, TTGO T5 V2.4.1, V2.3.1
//#include <GxGDEH029A1/GxGDEH029A1.h> // 2.9" b/w
//#include <GxGDEW029T5/GxGDEW029T5.h> // 2.9" b/w UC8151 (IL0373)
//#include <GxGDEW029T5D/GxGDEW029T5D.h> // 2.9" b/w UC8151D
//#include <GxGDEM029T94/GxGDEM029T94.h> // 2.9" b/w
//#include <GxDEPG0290BS/GxDEPG0290BS.h> // 2.9" b/w Waveshare variant, TTGO T5 V2.4.1 2.9"
//#include <GxGDEW029Z10/GxGDEW029Z10.h> // 2.9" b/w/r
//#include <GxGDEH029Z13/GxGDEH029Z13.h> // 2.9" b/w/r UC8151D
//#include <GxGDEW026T0/GxGDEW026T0.h> // 2.6" b/w
//#include <GxDEPG0266BN/GxDEPG0266BN.h> // 2.66" b/w 152x296, SSD1680, TTGO T5 V2.66, TTGO T5 V2.4.1
//#include <GxGDEW027C44/GxGDEW027C44.h> // 2.7" b/w/r
//#include <GxGDEW027W3/GxGDEW027W3.h> // 2.7" b/w
//#include <GxGDEY027T91/GxGDEY027T91.h> // 2.7" b/w
//#include <GxGDEW0371W7/GxGDEW0371W7.h> // 3.7" b/w
//#include <GxGDEW042T2/GxGDEW042T2.h> // 4.2" b/w
//#include <GxGDEW042Z15/GxGDEW042Z15.h> // 4.2" b/w/r
//#include <GxGDEW0583T7/GxGDEW0583T7.h> // 5.83" b/w
//#include <GxGDEW075T8/GxGDEW075T8.h> // 7.5" b/w
//#include <GxGDEW075T7/GxGDEW075T7.h> // 7.5" b/w 800x480
//#include <GxGDEW075Z09/GxGDEW075Z09.h> // 7.5" b/w/r
//#include <GxGDEW075Z08/GxGDEW075Z08.h> // 7.5" b/w/r 800x480
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
#if defined(ESP8266)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.2\variants\generic\common.h
GxIO_Class io(SPI, /*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2); // arbitrary selection of D3(=0), D4(=2), selected for default of GxEPD_Class
GxEPD_Class display(io /*RST=D4*/ /*BUSY=D2*/); // default selection of D4(=2), D2(=4)
// Heltec E-Paper 1.54" b/w without RST, BUSY
//GxEPD_Class display(io, /*RST=D4*/ -1, /*BUSY=D2*/ -1); // no RST, no BUSY
#elif defined(ESP32)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\espressif\esp32\variants\lolin32\pins_arduino.h
GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16); // arbitrary selection of 17, 16
GxEPD_Class display(io, /*RST=*/ 16, /*BUSY=*/ 4); // arbitrary selection of (16), 4
// for LILYGO® TTGO T5 2.66 board uncomment next two lines instead of previous two lines
//GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 19, /*RST=*/ 4); // LILYGO® TTGO T5 2.66
//GxEPD_Class display(io, /*RST=*/ 4, /*BUSY=*/ 34); // LILYGO® TTGO T5 2.66
#endif
#if defined (ESP8266)
#include <ESP8266WiFi.h>
#define USE_BearSSL true
#endif
#include <WiFiClient.h>
#include <WiFiClientSecure.h>
const char* ssid = "........";
const char* password = "........";
const int httpPort = 80;
const int httpsPort = 443;
const char* fp_api_github_com = "df b2 29 c6 a6 38 1a 59 9d c9 ad 92 2d 26 f5 3c 83 8f a5 87"; // as of 25.11.2020
const char* fp_github_com = "5f 3f 7a c2 56 9f 50 a4 66 76 47 c6 a1 8c a0 07 aa ed bb 8e"; // as of 25.11.2020
//const char* fp_rawcontent = "70 94 de dd e6 c4 69 48 3a 92 70 a1 48 56 78 2d 18 64 e0 b7"; // as of 25.11.2020
const char* fp_rawcontent = "8F 0E 79 24 71 C5 A7 D2 A7 46 76 30 C1 3C B7 2A 13 B0 01 B2"; // as of 29.7.2022
// how to find the certificate was not easy. finally I found it using Mozilla Firefox.
// opened one of the bitmaps, e.g. https://raw.githubusercontent.com/ZinggJM/GxEPD2/master/extras/bitmaps/logo200x200.bmp
// clicked the lock symbol, Connection secure clicked >, show connection details, clicked More Information, clicked View Certificate, clicked Download PEM (chain),
// selected Open with Notepad. Copied the middle certificate and editted to the following format:
// the number of characters per line is of no importance, but the 3 \n are needed
// Validity
// Not Before Fri, 18 Mar 2022 00:00:00 GMT
// Not After Tue, 21 Mar 2023 23:59:59 GMT
const char* certificate_rawcontent =
"-----BEGIN CERTIFICATE-----\n"
"MIIEvjCCA6agAwIBAgIQBtjZBNVYQ0b2ii+nVCJ+xDANBgkqhkiG9w0BAQsFADBh"
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3"
"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD"
"QTAeFw0yMTA0MTQwMDAwMDBaFw0zMTA0MTMyMzU5NTlaME8xCzAJBgNVBAYTAlVT"
"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxKTAnBgNVBAMTIERpZ2lDZXJ0IFRMUyBS"
"U0EgU0hBMjU2IDIwMjAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC"
"AQEAwUuzZUdwvN1PWNvsnO3DZuUfMRNUrUpmRh8sCuxkB+Uu3Ny5CiDt3+PE0J6a"
"qXodgojlEVbbHp9YwlHnLDQNLtKS4VbL8Xlfs7uHyiUDe5pSQWYQYE9XE0nw6Ddn"
"g9/n00tnTCJRpt8OmRDtV1F0JuJ9x8piLhMbfyOIJVNvwTRYAIuE//i+p1hJInuW"
"raKImxW8oHzf6VGo1bDtN+I2tIJLYrVJmuzHZ9bjPvXj1hJeRPG/cUJ9WIQDgLGB"
"Afr5yjK7tI4nhyfFK3TUqNaX3sNk+crOU6JWvHgXjkkDKa77SU+kFbnO8lwZV21r"
"eacroicgE7XQPUDTITAHk+qZ9QIDAQABo4IBgjCCAX4wEgYDVR0TAQH/BAgwBgEB"
"/wIBADAdBgNVHQ4EFgQUt2ui6qiqhIx56rTaD5iyxZV2ufQwHwYDVR0jBBgwFoAU"
"A95QNVbRTLtm8KPiGxvDl7I90VUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQG"
"CCsGAQUFBwMBBggrBgEFBQcDAjB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGG"
"GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBABggrBgEFBQcwAoY0aHR0cDovL2Nh"
"Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNydDBCBgNV"
"HR8EOzA5MDegNaAzhjFodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRH"
"bG9iYWxSb290Q0EuY3JsMD0GA1UdIAQ2MDQwCwYJYIZIAYb9bAIBMAcGBWeBDAEB"
"MAgGBmeBDAECATAIBgZngQwBAgIwCAYGZ4EMAQIDMA0GCSqGSIb3DQEBCwUAA4IB"
"AQCAMs5eC91uWg0Kr+HWhMvAjvqFcO3aXbMM9yt1QP6FCvrzMXi3cEsaiVi6gL3z"
"ax3pfs8LulicWdSQ0/1s/dCYbbdxglvPbQtaCdB73sRD2Cqk3p5BJl+7j5nL3a7h"
"qG+fh/50tx8bIKuxT8b1Z11dmzzp/2n3YWzW2fP9NsarA4h20ksudYbj/NhVfSbC"
"EXffPgK2fPOre3qGNm+499iTcc+G33Mw+nur7SpZyEKEOxEXGlLzyQ4UfaJbcme6"
"ce1XR2bFuAJKZTRei9AqPCCcUZlM51Ke92sRKw2Sfh3oius2FkOH6ipjv3U/697E"
"A7sKPPcw7+uvTPyLNhBzPvOk\n"
"-----END CERTIFICATE-----\n";
const char* host_rawcontent = "raw.githubusercontent.com";
const char* path_rawcontent = "/ZinggJM/GxEPD2/master/extras/bitmaps/";
const char* path_prenticedavid = "/prenticedavid/MCUFRIEND_kbv/master/extras/bitmaps/";
const char* path_waveshare_c = "/waveshare/e-Paper/master/RaspberryPi_JetsonNano/c/pic/";
const char* path_waveshare_py = "/waveshare/e-Paper/master/RaspberryPi_JetsonNano/python/pic/";
void showBitmapFrom_HTTP(const char* host, const char* path, const char* filename, int16_t x, int16_t y, bool with_color = true);
void showBitmapFrom_HTTPS(const char* host, const char* path, const char* filename, const char* fingerprint, int16_t x, int16_t y, bool with_color = true,
const char* certificate = certificate_rawcontent);
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println("GxEPD_WiFi_Example");
display.init(115200);
#ifdef RE_INIT_NEEDED
WiFi.persistent(true);
WiFi.mode(WIFI_STA); // switch off AP
WiFi.setAutoConnect(true);
WiFi.setAutoReconnect(true);
WiFi.disconnect();
#endif
if (!WiFi.getAutoConnect() || ( WiFi.getMode() != WIFI_STA) || ((WiFi.SSID() != ssid) && String(ssid) != "........"))
{
Serial.println();
Serial.print("WiFi.getAutoConnect()=");
Serial.println(WiFi.getAutoConnect());
Serial.print("WiFi.SSID()=");
Serial.println(WiFi.SSID());
WiFi.mode(WIFI_STA); // switch off AP
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
}
int ConnectTimeout = 30; // 15 seconds
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
Serial.print(WiFi.status());
if (--ConnectTimeout <= 0)
{
Serial.println();
Serial.println("WiFi connect timeout");
return;
}
}
Serial.println();
Serial.println("WiFi connected");
// Print the IP address
Serial.println(WiFi.localIP());
drawBitmaps_200x200();
drawBitmaps_other();
//drawBitmaps_test();
//drawBitmapsBuffered_test();
Serial.println("GxEPD_WiFi_Example done");
}
void loop(void)
{
}
void drawBitmaps_200x200()
{
int16_t x = (display.width() - 200) / 2;
int16_t y = (display.height() - 200) / 2;
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "logo200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "first200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "second200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "third200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "fourth200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "fifth200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "sixth200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "seventh200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "eighth200x200.bmp", fp_rawcontent, x, y);
delay(2000);
}
void drawBitmaps_other()
{
int16_t w2 = display.width() / 2;
int16_t h2 = display.height() / 2;
showBitmapFrom_HTTP("www.squix.org", "/blog/wunderground/", "chanceflurries.bmp", w2 - 50, h2 - 50, false);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "betty_1.bmp", fp_rawcontent, w2 - 100, h2 - 160);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "betty_4.bmp", fp_rawcontent, w2 - 102, h2 - 126);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "marilyn_240x240x8.bmp", fp_rawcontent, w2 - 120, h2 - 120);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "miniwoof.bmp", fp_rawcontent, w2 - 60, h2 - 80);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "test.bmp", fp_rawcontent, w2 - 100, h2 - 100);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "tiger.bmp", fp_rawcontent, w2 - 160, h2 - 120);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "tiger_178x160x4.bmp", fp_rawcontent, w2 - 89, h2 - 80);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "tiger_240x317x4.bmp", fp_rawcontent, w2 - 120, h2 - 160);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "tiger_320x200x24.bmp", fp_rawcontent, w2 - 160, h2 - 100);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "tiger16T.bmp", fp_rawcontent, w2 - 160, h2 - 100);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "woof.bmp", fp_rawcontent, w2 - 100, h2 - 100);
delay(2000);
}
void drawBitmaps_test()
{
int16_t w2 = display.width() / 2;
int16_t h2 = display.height() / 2;
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "betty_4.bmp", fp_rawcontent, w2 - 102, h2 - 126);
delay(2000);
}
static const uint16_t input_buffer_pixels = 800; // may affect performance
static const uint16_t max_row_width = 1448; // for up to 6" display 1448x1072
static const uint16_t max_palette_pixels = 256; // for depth <= 8
uint8_t input_buffer[3 * input_buffer_pixels]; // up to depth 24
uint8_t output_row_mono_buffer[max_row_width / 8]; // buffer for at least one row of b/w bits
uint8_t output_row_color_buffer[max_row_width / 8]; // buffer for at least one row of color bits
uint8_t mono_palette_buffer[max_palette_pixels / 8]; // palette buffer for depth <= 8 b/w
uint8_t color_palette_buffer[max_palette_pixels / 8]; // palette buffer for depth <= 8 c/w
void drawBitmapFrom_HTTP_ToBuffer(const char* host, const char* path, const char* filename, int16_t x, int16_t y, bool with_color)
{
WiFiClient client;
bool connection_ok = false;
bool valid = false; // valid format to be handled
bool flip = true; // bitmap is stored bottom-to-top
uint32_t startTime = millis();
if ((x >= display.width()) || (y >= display.height())) return;
display.fillScreen(GxEPD_WHITE);
Serial.print("connecting to "); Serial.println(host);
if (!client.connect(host, httpPort))
{
Serial.println("connection failed");
return;
}
Serial.print("requesting URL: ");
Serial.println(String("http://") + host + path + filename);
client.print(String("GET ") + path + filename + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"User-Agent: GxEPD_WiFi_Example\r\n" +
"Connection: close\r\n\r\n");
Serial.println("request sent");
while (client.connected())
{
String line = client.readStringUntil('\n');
if (!connection_ok)
{
connection_ok = line.startsWith("HTTP/1.1 200 OK");
if (connection_ok) Serial.println(line);
//if (!connection_ok) Serial.println(line);
}
if (!connection_ok) Serial.println(line);
//Serial.println(line);
if (line == "\r")
{
Serial.println("headers received");
break;
}
}
if (!connection_ok) return;
// Parse BMP header
if (read16(client) == 0x4D42) // BMP signature
{
int32_t fileSize = read32(client);
int32_t creatorBytes = read32(client);
int32_t imageOffset = read32(client); // Start of image data
int32_t headerSize = read32(client);
int32_t width = read32(client);
int32_t height = read32(client);
uint16_t planes = read16(client);
uint16_t depth = read16(client); // bits per pixel
int32_t format = read32(client);
int32_t bytes_read = 7 * 4 + 3 * 2; // read so far
(void) creatorBytes;
if ((planes == 1) && ((format == 0) || (format == 3))) // uncompressed is handled, 565 also
{
Serial.print("File size: "); Serial.println(fileSize);
Serial.print("Image Offset: "); Serial.println(imageOffset);
Serial.print("Header size: "); Serial.println(headerSize);
Serial.print("Bit Depth: "); Serial.println(depth);
Serial.print("Image size: ");
Serial.print(width);
Serial.print('x');
Serial.println(height);
// BMP rows are padded (if needed) to 4-byte boundary
uint32_t rowSize = (width * depth / 8 + 3) & ~3;
if (depth < 8) rowSize = ((width * depth + 8 - depth) / 8 + 3) & ~3;
if (height < 0)
{
height = -height;
flip = false;
}
uint16_t w = width;
uint16_t h = height;
if ((x + w - 1) >= display.width()) w = display.width() - x;
if ((y + h - 1) >= display.height()) h = display.height() - y;
valid = true;
uint8_t bitmask = 0xFF;
uint8_t bitshift = 8 - depth;
uint16_t red, green, blue;
bool whitish = false;
bool colored = false;
if (depth == 1) with_color = false;
if (depth <= 8)
{
if (depth < 8) bitmask >>= depth;
//bytes_read += skip(client, 54 - bytes_read); //palette is always @ 54
bytes_read += skip(client, imageOffset - (4 << depth) - bytes_read); // 54 for regular, diff for colorsimportant
for (uint16_t pn = 0; pn < (1 << depth); pn++)
{
blue = client.read();
green = client.read();
red = client.read();
client.read();
bytes_read += 4;
whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
if (0 == pn % 8) mono_palette_buffer[pn / 8] = 0;
mono_palette_buffer[pn / 8] |= whitish << pn % 8;
if (0 == pn % 8) color_palette_buffer[pn / 8] = 0;
color_palette_buffer[pn / 8] |= colored << pn % 8;
//Serial.print("0x00"); Serial.print(red, HEX); Serial.print(green, HEX); Serial.print(blue, HEX);
//Serial.print(" : "); Serial.print(whitish); Serial.print(", "); Serial.println(colored);
}
}
display.fillScreen(GxEPD_WHITE);
uint32_t rowPosition = flip ? imageOffset + (height - h) * rowSize : imageOffset;
//Serial.print("skip "); Serial.println(rowPosition - bytes_read);
bytes_read += skip(client, rowPosition - bytes_read);
for (uint16_t row = 0; row < h; row++, rowPosition += rowSize) // for each line
{
if (!connection_ok || !(client.connected() || client.available())) break;
delay(1); // yield() to avoid WDT
uint32_t in_remain = rowSize;
uint32_t in_idx = 0;
uint32_t in_bytes = 0;
uint8_t in_byte = 0; // for depth <= 8
uint8_t in_bits = 0; // for depth <= 8
uint16_t color = GxEPD_WHITE;
for (uint16_t col = 0; col < w; col++) // for each pixel
{
yield();
if (!connection_ok || !(client.connected() || client.available())) break;
// Time to read more pixel data?
if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
{
uint32_t get = in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain;
uint32_t got = read8n(client, input_buffer, get);
while ((got < get) && connection_ok)
{
//Serial.print("got "); Serial.print(got); Serial.print(" < "); Serial.print(get); Serial.print(" @ "); Serial.println(bytes_read);
uint32_t gotmore = read8n(client, input_buffer + got, get - got);
got += gotmore;
connection_ok = gotmore > 0;
}
in_bytes = got;
in_remain -= got;
bytes_read += got;
}
if (!connection_ok)
{
Serial.print("Error: got no more after "); Serial.print(bytes_read); Serial.println(" bytes read!");
break;
}
switch (depth)
{
case 24:
blue = input_buffer[in_idx++];
green = input_buffer[in_idx++];
red = input_buffer[in_idx++];
whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
break;
case 16:
{
uint8_t lsb = input_buffer[in_idx++];
uint8_t msb = input_buffer[in_idx++];
if (format == 0) // 555
{
blue = (lsb & 0x1F) << 3;
green = ((msb & 0x03) << 6) | ((lsb & 0xE0) >> 2);
red = (msb & 0x7C) << 1;
}
else // 565
{
blue = (lsb & 0x1F) << 3;
green = ((msb & 0x07) << 5) | ((lsb & 0xE0) >> 3);
red = (msb & 0xF8);
}
whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
}
break;
case 1:
case 4:
case 8:
{
if (0 == in_bits)
{
in_byte = input_buffer[in_idx++];
in_bits = 8;
}
uint16_t pn = (in_byte >> bitshift) & bitmask;
whitish = mono_palette_buffer[pn / 8] & (0x1 << pn % 8);
colored = color_palette_buffer[pn / 8] & (0x1 << pn % 8);
in_byte <<= depth;
in_bits -= depth;
}
break;
}
if (whitish)
{
color = GxEPD_WHITE;
}
else if (colored && with_color)
{
color = GxEPD_RED;
}
else
{
color = GxEPD_BLACK;
}
uint16_t yrow = y + (flip ? h - row - 1 : row);
display.drawPixel(x + col, yrow, color);
} // end pixel
} // end line
}
Serial.print("bytes read "); Serial.println(bytes_read);
}
Serial.print("loaded in "); Serial.print(millis() - startTime); Serial.println(" ms");
if (!valid)
{
Serial.println("bitmap format not handled.");
}
}
void showBitmapFrom_HTTP(const char* host, const char* path, const char* filename, int16_t x, int16_t y, bool with_color)
{
Serial.println(); Serial.print("downloading file \""); Serial.print(filename); Serial.println("\"");
drawBitmapFrom_HTTP_ToBuffer(host, path, filename, x, y, with_color);
display.update();
}
void drawBitmapFrom_HTTPS_ToBuffer(const char* host, const char* path, const char* filename, const char* fingerprint, int16_t x, int16_t y, bool with_color, const char* certificate)
{
// Use WiFiClientSecure class to create TLS connection
#if USE_BearSSL
BearSSL::WiFiClientSecure client;
#else
WiFiClientSecure client;
#endif
bool connection_ok = false;
bool valid = false; // valid format to be handled
bool flip = true; // bitmap is stored bottom-to-top
uint32_t startTime = millis();
if ((x >= display.width()) || (y >= display.height())) return;
display.fillScreen(GxEPD_WHITE);
Serial.print("connecting to "); Serial.println(host);
#if defined (ESP8266)
client.setBufferSizes(4096, 4096); // doesn't help
if (fingerprint) client.setFingerprint(fingerprint);
#elif defined (ESP32)
if (certificate) client.setCACert(certificate);
#endif
if (!client.connect(host, httpsPort))
{
Serial.println("connection failed");
return;
}
Serial.print("requesting URL: ");
Serial.println(String("https://") + host + path + filename);
client.print(String("GET ") + path + filename + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"User-Agent: GxEPD_WiFi_Example\r\n" +
"Connection: close\r\n\r\n");
Serial.println("request sent");
while (client.connected())
{
String line = client.readStringUntil('\n');
if (!connection_ok)
{
connection_ok = line.startsWith("HTTP/1.1 200 OK");
if (connection_ok) Serial.println(line);
//if (!connection_ok) Serial.println(line);
}
if (!connection_ok) Serial.println(line);
//Serial.println(line);
if (line == "\r")
{
Serial.println("headers received");
break;
}
}
if (!connection_ok) return;
// Parse BMP header
if (read16(client) == 0x4D42) // BMP signature
{
int32_t fileSize = read32(client);
int32_t creatorBytes = read32(client);
int32_t imageOffset = read32(client); // Start of image data
int32_t headerSize = read32(client);
int32_t width = read32(client);
int32_t height = read32(client);
uint16_t planes = read16(client);
uint16_t depth = read16(client); // bits per pixel
int32_t format = read32(client);
int32_t bytes_read = 7 * 4 + 3 * 2; // read so far
(void) creatorBytes;
if ((planes == 1) && ((format == 0) || (format == 3))) // uncompressed is handled, 565 also
{
Serial.print("File size: "); Serial.println(fileSize);
Serial.print("Image Offset: "); Serial.println(imageOffset);
Serial.print("Header size: "); Serial.println(headerSize);
Serial.print("Bit Depth: "); Serial.println(depth);
Serial.print("Image size: ");
Serial.print(width);
Serial.print('x');
Serial.println(height);
// BMP rows are padded (if needed) to 4-byte boundary
uint32_t rowSize = (width * depth / 8 + 3) & ~3;
if (depth < 8) rowSize = ((width * depth + 8 - depth) / 8 + 3) & ~3;
if (height < 0)
{
height = -height;
flip = false;
}
uint16_t w = width;
uint16_t h = height;
if ((x + w - 1) >= display.width()) w = display.width() - x;
if ((y + h - 1) >= display.height()) h = display.height() - y;
valid = true;
uint8_t bitmask = 0xFF;
uint8_t bitshift = 8 - depth;
uint16_t red, green, blue;
bool whitish = false;
bool colored = false;
if (depth == 1) with_color = false;
if (depth <= 8)
{
if (depth < 8) bitmask >>= depth;
//bytes_read += skip(client, 54 - bytes_read); //palette is always @ 54
bytes_read += skip(client, imageOffset - (4 << depth) - bytes_read); // 54 for regular, diff for colorsimportant
for (uint16_t pn = 0; pn < (1 << depth); pn++)
{
blue = client.read();
green = client.read();
red = client.read();
client.read();
bytes_read += 4;
whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
if (0 == pn % 8) mono_palette_buffer[pn / 8] = 0;
mono_palette_buffer[pn / 8] |= whitish << pn % 8;
if (0 == pn % 8) color_palette_buffer[pn / 8] = 0;
color_palette_buffer[pn / 8] |= colored << pn % 8;
//Serial.print("0x00"); Serial.print(red, HEX); Serial.print(green, HEX); Serial.print(blue, HEX);
//Serial.print(" : "); Serial.print(whitish); Serial.print(", "); Serial.println(colored);
}
}
display.fillScreen(GxEPD_WHITE);
uint32_t rowPosition = flip ? imageOffset + (height - h) * rowSize : imageOffset;
//Serial.print("skip "); Serial.println(rowPosition - bytes_read);
bytes_read += skip(client, rowPosition - bytes_read);
for (uint16_t row = 0; row < h; row++, rowPosition += rowSize) // for each line
{
if (!connection_ok || !(client.connected() || client.available())) break;
delay(1); // yield() to avoid WDT
uint32_t in_remain = rowSize;
uint32_t in_idx = 0;
uint32_t in_bytes = 0;
uint8_t in_byte = 0; // for depth <= 8
uint8_t in_bits = 0; // for depth <= 8
uint16_t color = GxEPD_WHITE;
for (uint16_t col = 0; col < w; col++) // for each pixel
{
yield();
if (!connection_ok || !(client.connected() || client.available())) break;
// Time to read more pixel data?
if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
{
uint32_t get = in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain;
uint32_t got = read8n(client, input_buffer, get);
while ((got < get) && connection_ok)
{
//Serial.print("got "); Serial.print(got); Serial.print(" < "); Serial.print(get); Serial.print(" @ "); Serial.println(bytes_read);
uint32_t gotmore = read8n(client, input_buffer + got, get - got);
got += gotmore;
connection_ok = gotmore > 0;
}
in_bytes = got;
in_remain -= got;
bytes_read += got;
}
if (!connection_ok)
{
Serial.print("Error: got no more after "); Serial.print(bytes_read); Serial.println(" bytes read!");
break;
}
switch (depth)
{
case 24:
blue = input_buffer[in_idx++];
green = input_buffer[in_idx++];
red = input_buffer[in_idx++];
whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
break;
case 16:
{
uint8_t lsb = input_buffer[in_idx++];
uint8_t msb = input_buffer[in_idx++];
if (format == 0) // 555
{
blue = (lsb & 0x1F) << 3;
green = ((msb & 0x03) << 6) | ((lsb & 0xE0) >> 2);
red = (msb & 0x7C) << 1;
}
else // 565
{
blue = (lsb & 0x1F) << 3;
green = ((msb & 0x07) << 5) | ((lsb & 0xE0) >> 3);
red = (msb & 0xF8);
}
whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
}
break;
case 1:
case 4:
case 8:
{
if (0 == in_bits)
{
in_byte = input_buffer[in_idx++];
in_bits = 8;
}
uint16_t pn = (in_byte >> bitshift) & bitmask;
whitish = mono_palette_buffer[pn / 8] & (0x1 << pn % 8);
colored = color_palette_buffer[pn / 8] & (0x1 << pn % 8);
in_byte <<= depth;
in_bits -= depth;
}
break;
}
if (whitish)
{
color = GxEPD_WHITE;
}
else if (colored && with_color)
{
color = GxEPD_RED;
}
else
{
color = GxEPD_BLACK;
}
uint16_t yrow = y + (flip ? h - row - 1 : row);
display.drawPixel(x + col, yrow, color);
} // end pixel
} // end line
}
Serial.print("bytes read "); Serial.println(bytes_read);
}
Serial.print("loaded in "); Serial.print(millis() - startTime); Serial.println(" ms");
if (!valid)
{
Serial.println("bitmap format not handled.");
}
client.stop();
}
void showBitmapFrom_HTTPS(const char* host, const char* path, const char* filename, const char* fingerprint, int16_t x, int16_t y, bool with_color, const char* certificate)
{
Serial.println(); Serial.print("downloading file \""); Serial.print(filename); Serial.println("\"");
drawBitmapFrom_HTTPS_ToBuffer(host, path, filename, fingerprint, x, y, with_color, certificate);
display.update();
}
uint16_t read16(WiFiClient& client)
{
// BMP data is stored little-endian, same as Arduino.
uint16_t result;
((uint8_t *)&result)[0] = client.read(); // LSB
((uint8_t *)&result)[1] = client.read(); // MSB
return result;
}
int32_t read32(WiFiClient& client)
{
// BMP data is stored little-endian, same as Arduino.
int32_t result;
((uint8_t *)&result)[0] = client.read(); // LSB
((uint8_t *)&result)[1] = client.read();
((uint8_t *)&result)[2] = client.read();
((uint8_t *)&result)[3] = client.read(); // MSB
return result;
}
#if USE_BearSSL
uint32_t skip(BearSSL::WiFiClientSecure& client, int32_t bytes)
{
int32_t remain = bytes;
uint32_t start = millis();
while (client.connected() && (remain > 0))
{
if (client.available())
{
int16_t v = client.read();
remain--;
}
else delay(1);
if (millis() - start > 2000) break; // don't hang forever
}
return bytes - remain;
}
uint32_t read(BearSSL::WiFiClientSecure& client, uint8_t* buffer, int32_t bytes)
{
int32_t remain = bytes;
uint32_t start = millis();
while (client.connected() && (remain > 0))
{
if (client.available())
{
int16_t v = client.read();
*buffer++ = uint8_t(v);
remain--;
}
else delay(1);
if (millis() - start > 2000) break; // don't hang forever
}
return bytes - remain;
}
#endif
uint32_t skip(WiFiClient& client, int32_t bytes)
{
int32_t remain = bytes;
uint32_t start = millis();
while ((client.connected() || client.available()) && (remain > 0))
{
if (client.available())
{
int16_t v = client.read();
(void) v;
remain--;
}
else delay(1);
if (millis() - start > 2000) break; // don't hang forever
}
return bytes - remain;
}
uint32_t read8n(WiFiClient& client, uint8_t* buffer, int32_t bytes)
{
int32_t remain = bytes;
uint32_t start = millis();
while ((client.connected() || client.available()) && (remain > 0))
{
if (client.available())
{
int16_t v = client.read();
*buffer++ = uint8_t(v);
remain--;
}
else delay(1);
if (millis() - start > 2000) break; // don't hang forever
}
return bytes - remain;
}

View File

@@ -0,0 +1,354 @@
// GxFont_GFX_Example : example to show the use of additional fonts rendering these fonts
//
// Author : J-M Zingg
//
// Version : see library.properties
//
// License: GNU GENERAL PUBLIC LICENSE V3, see LICENSE
//
// Library: https://github.com/ZinggJM/GxEPD
//
// NOTE: you need to SAVE the modified example to a saveable location for UTF-8 characters to work
// e.g. for Umlauts
// for use of additional fonts you need to enable these in file GxFont_GFX.h
// and install the library
//
// selection of the additional fonts is done by the following methods:
//
// void setFont(const uint8_t *font); // selects rendering and fonts from library U8G2_FOR_ADAFRUIT_GFX
//
// void setFreeFont(const GFXfont *f = NULL); // selects rendering and fonts from library GxFont_GFX_TFT_eSPI
// void void setTextFont(uint8_t font); // selects rendering and fonts from library GxFont_GFX_TFT_eSPI
//
// void setFont(uint8_t f); // selects rendering and fonts from library Adafruit_tfGFX
// (no additional fonts, as all are now part of Adafruit_GFX, but fonts above 7bit character set)
//
// void setFont(const GFXfont *f = NULL); // reverts back to Adafruit_GFX FreeFonts
// use setFont((void*)NULL); // to select Adafruit_GFX classic font
//
// these additions may not work with AVR Arduinos
//
// these additions are only partially tested; more tests and additions may follow
// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
// Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0
// mapping suggestion from Waveshare SPI e-Paper to Wemos D1 mini
// BUSY -> D2, RST -> D4, DC -> D3, CS -> D8, CLK -> D5, DIN -> D7, GND -> GND, 3.3V -> 3.3V
// mapping suggestion from Waveshare SPI e-Paper to generic ESP8266
// BUSY -> GPIO4, RST -> GPIO2, DC -> GPIO0, CS -> GPIO15, CLK -> GPIO14, DIN -> GPIO13, GND -> GND, 3.3V -> 3.3V
// mapping suggestion for ESP32, e.g. LOLIN32, see .../variants/.../pins_arduino.h for your board
// NOTE: there are variants with different pins for SPI ! CHECK SPI PINS OF YOUR BOARD
// BUSY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V
// new mapping suggestion for STM32F1, e.g. STM32F103C8T6 "BluePill"
// BUSY -> A1, RST -> A2, DC -> A3, CS-> A4, CLK -> A5, DIN -> A7
// mapping suggestion for AVR, UNO, NANO etc.
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 10, CLK -> 13, DIN -> 11
// mapping suggestion for Arduino MEGA
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 53, CLK -> 52, DIN -> 51
// mapping suggestion for Arduino DUE
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 77, CLK -> 76, DIN -> 75
// SPI pins are also on 6 pin 2x3 SPI header
// include library, include base class, make path known
#include <GxEPD.h>
//
// NOTE: you need to SAVE the modified example to a saveable location for UTF-8 characters to work
// e.g. for Umlauts
// select the display class to use, only one
//#include <GxDEPG0150BN/GxDEPG0150BN.h> // 1.50" b/w
//#include <GxGDEP015OC1/GxGDEP015OC1.h> // 1.54" b/w
//#include <GxGDEH0154D67/GxGDEH0154D67.h> // 1.54" b/w 200x200, SSD1681
//#include <GxGDEW0154T8/GxGDEW0154T8.h> // 1.54" b/w 152x152 UC8151 (IL0373)
//#include <GxGDEW0154M09/GxGDEW0154M09.h> // 1.54" b/w 200x200 JD79653A
//#include <GxGDEW0154M10/GxGDEW0154M10.h> // 1.54" b/w 152x152 UC8151D
//#include <GxGDEW0154Z04/GxGDEW0154Z04.h> // 1.54" b/w/r 200x200
//#include <GxGDEW0154Z17/GxGDEW0154Z17.h> // 1.54" b/w/r 152x152
//#include <GxGDEH0154Z90/GxGDEH0154Z90.h> // 1.54" b/w/r 200x200 SSD1681
//#include <GxGDEW0213I5F/GxGDEW0213I5F.h> // 2.13" b/w 104x212 flexible
//#include <GxGDE0213B1/GxGDE0213B1.h> // 2.13" b/w
//#include <GxGDEH0213B72/GxGDEH0213B72.h> // 2.13" b/w new panel
//#include <GxGDEH0213B73/GxGDEH0213B73.h> // 2.13" b/w newer panel
//#include <GxGDEM0213B74/GxGDEM0213B74.h> // 2.13" b/w 128x250 SSD1680
//#include <GxGDEW0213Z16/GxGDEW0213Z16.h> // 2.13" b/w/r
//#include <GxGDEH0213Z19/GxGDEH0213Z19.h> // 2.13" b/w/r UC8151D
//#include <GxGDEW0213T5D/GxGDEW0213T5D.h> // 2.13" b/w 104x212 UC8151D
//#include <GxDEPG0213BN/GxDEPG0213BN.h> // 2.13" b/w 128x250, SSD1680, TTGO T5 V2.4.1, V2.3.1
//#include <GxGDEH029A1/GxGDEH029A1.h> // 2.9" b/w
//#include <GxGDEW029T5/GxGDEW029T5.h> // 2.9" b/w UC8151 (IL0373)
//#include <GxGDEW029T5D/GxGDEW029T5D.h> // 2.9" b/w UC8151D
//#include <GxGDEM029T94/GxGDEM029T94.h> // 2.9" b/w
//#include <GxDEPG0290BS/GxDEPG0290BS.h> // 2.9" b/w Waveshare variant, TTGO T5 V2.4.1 2.9"
//#include <GxGDEW029Z10/GxGDEW029Z10.h> // 2.9" b/w/r
//#include <GxGDEH029Z13/GxGDEH029Z13.h> // 2.9" b/w/r UC8151D
//#include <GxGDEW026T0/GxGDEW026T0.h> // 2.6" b/w
//#include <GxDEPG0266BN/GxDEPG0266BN.h> // 2.66" b/w 152x296, SSD1680, TTGO T5 V2.66, TTGO T5 V2.4.1
//#include <GxGDEW027C44/GxGDEW027C44.h> // 2.7" b/w/r
//#include <GxGDEW027W3/GxGDEW027W3.h> // 2.7" b/w
//#include <GxGDEY027T91/GxGDEY027T91.h> // 2.7" b/w
//#include <GxGDEW0371W7/GxGDEW0371W7.h> // 3.7" b/w
//#include <GxGDEW042T2/GxGDEW042T2.h> // 4.2" b/w
//#include <GxGDEW042Z15/GxGDEW042Z15.h> // 4.2" b/w/r
//#include <GxGDEW0583T7/GxGDEW0583T7.h> // 5.83" b/w
//#include <GxGDEW075T8/GxGDEW075T8.h> // 7.5" b/w
//#include <GxGDEW075T7/GxGDEW075T7.h> // 7.5" b/w 800x480
//#include <GxGDEW075Z09/GxGDEW075Z09.h> // 7.5" b/w/r
//#include <GxGDEW075Z08/GxGDEW075Z08.h> // 7.5" b/w/r 800x480
#if !defined(_GxFont_GFX_TFT_eSPI_H_)
// FreeFonts from Adafruit_GFX
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
//#include <Fonts/FreeMonoBold18pt7b.h>
//#include <Fonts/FreeMonoBold24pt7b.h>
#endif
#if defined(_ADAFRUIT_TF_GFX_H_)
#include <Fonts/Open_Sans_Bold_12pt.h>
#endif
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
#if defined(ESP8266)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.2\variants\generic\common.h
GxIO_Class io(SPI, /*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2); // arbitrary selection of D3(=0), D4(=2), selected for default of GxEPD_Class
GxEPD_Class display(io /*RST=D4*/ /*BUSY=D2*/); // default selection of D4(=2), D2(=4)
#elif defined(ESP32)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\espressif\esp32\variants\lolin32\pins_arduino.h
GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16); // arbitrary selection of 17, 16
GxEPD_Class display(io, /*RST=*/ 16, /*BUSY=*/ 4); // arbitrary selection of (16), 4
// for LILYGO® TTGO T5 2.66 board uncomment next two lines instead of previous two lines
//GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 19, /*RST=*/ 4); // LILYGO® TTGO T5 2.66
//GxEPD_Class display(io, /*RST=*/ 4, /*BUSY=*/ 34); // LILYGO® TTGO T5 2.66
#elif defined(ARDUINO_ARCH_SAMD)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.19\variants\mkr1000\variant.h
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.19\variants\mkrzero\variant.h
GxIO_Class io(SPI, /*CS=*/ 4, /*DC=*/ 7, /*RST=*/ 6);
GxEPD_Class display(io, /*RST=*/ 6, /*BUSY=*/ 5);
#elif defined(ARDUINO_GENERIC_STM32F103C) && defined(MCU_STM32F103C8)
// STM32 Boards(STM32duino.com) Generic STM32F103C series STM32F103C8
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\variant.h
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\board\board.h
// new mapping suggestion for STM32F1, e.g. STM32F103C8T6 "BluePill"
// BUSY -> A1, RST -> A2, DC -> A3, CS-> A4, CLK -> A5, DIN -> A7
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 3, /*RST=*/ 2);
GxEPD_Class display(io, /*RST=*/ 2, /*BUSY=*/ 1);
#elif defined(ARDUINO_GENERIC_STM32F103V) && defined(MCU_STM32F103VB)
// STM32 Boards(STM32duino.com) Generic STM32F103V series STM32F103VB
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103vb\variant.h
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103vb\board\board.h
// Good Display DESPI-M01
// note: needs jumper wires from SS=PA4->CS, SCK=PA5->SCK, MOSI=PA7->SDI
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ PE15, /*RST=*/ PE14); // DC, RST as wired by DESPI-M01
GxEPD_Class display(io, /*RST=*/ PE14, /*BUSY=*/ PE13); // RST, BUSY as wired by DESPI-M01
#else
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\standard\pins_arduino.h
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
GxEPD_Class display(io /*RST=9*/ /*BUSY=7*/); // default selection of (9), 7
#endif
#if defined(_GxGDEW0154Z04_H_) || defined(_GxGDEW0213Z16_H_) || defined(_GxGDEW029Z10_H_) || defined(_GxGDEW027C44_H_) || defined(_GxGDEW042Z15_H_) || defined(_GxGDEW075Z09_H_)
#define HAS_RED_COLOR
#endif
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println("setup");
display.init(115200); // enable diagnostic output on Serial
Serial.println("setup done");
}
void loop()
{
#if !defined(_ADAFRUIT_TF_GFX_H_) && !defined(_GxFont_GFX_TFT_eSPI_H_) && !defined(U8g2_for_Adafruit_GFX_h)
showFont("FreeMonoBold12pt7b", &FreeMonoBold12pt7b);
#endif
#if defined(U8g2_for_Adafruit_GFX_h)
showFont("u8g2_font_helvR14_tf", u8g2_font_helvR14_tf); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
delay(2000);
showFont("u8g2_font_profont22_mr", u8g2_font_profont22_mr); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
delay(2000);
#endif
#if defined(_GxFont_GFX_TFT_eSPI_H_)
showFreeFont("FreeMonoBold12pt7b", &FreeMonoBold12pt7b);
delay(2000);
//showFreeFont("NULL", NULL);
showTextFont("Font 1", 1, 1);
delay(2000);
showTextFont("Font 1", 1, 2);
delay(2000);
showTextFont("Font 1", 1, 3);
delay(2000);
showTextFont("Font 2", 2, 1);
delay(2000);
showTextFont("Font 2", 2, 2);
delay(2000);
showTextFont("Font 2", 2, 3);
delay(2000);
showTextFont("Font 4", 4, 1);
delay(2000);
showTextFont("Font 4", 4, 2);
delay(2000);
showTextFont("Font 4", 4, 3);
#endif
#if defined(_ADAFRUIT_TF_GFX_H_)
showFont("Open_Sans_Bold_12pt", OPENSANSBOLD_12);
#endif
delay(10000);
}
void showFont(const char name[], const GFXfont* f)
{
display.fillScreen(GxEPD_WHITE);
display.setTextColor(GxEPD_BLACK);
display.setFont(f);
display.setCursor(0, 0);
display.println();
display.println(name);
display.println(" !\"#$%&'()*+,-./");
display.println("0123456789:;<=>?");
display.println("@ABCDEFGHIJKLMNO");
display.println("PQRSTUVWXYZ[\\]^_");
#if defined(HAS_RED_COLOR)
display.setTextColor(GxEPD_RED);
#endif
display.println("`abcdefghijklmno");
display.println("pqrstuvwxyz{|}~ ");
display.update();
delay(5000);
}
#if defined(U8g2_for_Adafruit_GFX_h)
void showFont(const char name[], const uint8_t *f)
{
display.setRotation(0);
display.fillScreen(GxEPD_WHITE);
display.setFontMode(1); // use u8g2 transparent mode (this is default)
display.setFontDirection(0); // left to right (this is default)
display.setForegroundColor(GxEPD_BLACK); // apply Adafruit GFX color
display.setBackgroundColor(GxEPD_WHITE); // apply Adafruit GFX color
display.setFont(f); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
display.setCursor(0, 0);
display.println();
display.println(name);
display.println(" !\"#$%&'()*+,-./");
display.println("0123456789:;<=>?");
display.println("@ABCDEFGHIJKLMNO");
display.println("PQRSTUVWXYZ[\\]^_");
#if defined(HAS_RED_COLOR)
display.setForegroundColor(GxEPD_RED);
#endif
display.println("`abcdefghijklmno");
display.println("pqrstuvwxyz{|}~ ");
display.println("Umlaut ÄÖÜäéöü");
display.update();
}
#endif
#if defined(_ADAFRUIT_TF_GFX_H_)
void showFont(const char name[], uint8_t f)
{
display.setRotation(0);
display.fillScreen(GxEPD_WHITE);
display.setTextColor(GxEPD_BLACK);
display.setFont(f);
display.setCursor(0, 0);
display.println();
display.println(name);
display.println(" !\"#$%&'()*+,-./");
display.println("0123456789:;<=>?");
display.println("@ABCDEFGHIJKLMNO");
display.println("PQRSTUVWXYZ[\\]^_");
#if defined(HAS_RED_COLOR)
display.setTextColor(GxEPD_RED);
#endif
display.println("`abcdefghijklmno");
display.println("pqrstuvwxyz{|}~ ");
display.update();
}
#endif
#if defined(_GxFont_GFX_TFT_eSPI_H_)
void showFreeFont(const char name[], const GFXfont* f)
{
display.setRotation(0);
display.fillScreen(GxEPD_WHITE);
display.setTextColor(GxEPD_BLACK);
display.setFreeFont(f);
display.setCursor(0, 0);
display.println();
display.println(name);
display.println(" !\"#$%&'()*+,-./");
display.println("0123456789:;<=>?");
display.println("@ABCDEFGHIJKLMNO");
display.println("PQRSTUVWXYZ[\\]^_");
#if defined(HAS_RED_COLOR)
display.setTextColor(GxEPD_RED);
#endif
display.println("`abcdefghijklmno");
display.println("pqrstuvwxyz{|}~ ");
display.update();
}
void showTextFont(const char name[], uint8_t f, uint8_t size)
{
display.setRotation(0);
display.fillScreen(GxEPD_WHITE);
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
display.setTextFont(f);
display.setTextSize(size);
display.setCursor(0, 0);
display.println();
display.println(name);
display.println(" !\"#$%&'()*+,-./");
display.println("0123456789:;<=>?");
display.println("@ABCDEFGHIJKLMNO");
display.println("PQRSTUVWXYZ[\\]^_");
#if defined(HAS_RED_COLOR)
display.setTextColor(GxEPD_RED);
#endif
display.println("`abcdefghijklmno");
display.println("pqrstuvwxyz{|}~ ");
display.update();
}
#endif

View File

@@ -0,0 +1,344 @@
// IoT_SHT31LP_Example_1.54inchEPD : GxEPD demo example for Waveshare 1.54 e-Paper display or Good Display GDEP015OC1
//
// https://www.aliexpress.com/item/200x200-1-54inch-E-Ink-display-module-Without-PCB-Communicate-via-SPI-interface-Supports-various-controller/32811540997.html
// "200x200, 1.54inch E-Ink display module with embedded controller Communicate via SPI interface Supports various controller boards"
//
// https://www.aliexpress.com/store/product/E-paper-display-GDEW0154T8-with-demo-Board-DESTM32-S2/600281_32813958757.html
// https://www.aliexpress.com/store/product/E001-1-54-inch-partial-refresh-Small-size-dot-matrix-e-paper-display/600281_32815089163.html
//
// Created for my IoT sensor network by Jean-Marc Zingg, adapted for demo example use
//
// for low power deep sleep mode connect D0 pin to reset pin of ESP8266, e.g. through 0.1k
//
// for supply voltage measurement connect 5V pin through 300k to A0
// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
// Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0
// SPECIAL mapping for IoT from Waveshare 1.54inch e-Paper to Wemos D1 mini
// BUSY -> D6, RST -> D4, DC -> D3, CS -> D8, CLK -> D5, DIN -> D7, GND -> GND, 3.3V -> 3.3V
// mapping example for AVR, UNO, NANO etc.
// BUSY -> 7, RST -> 9, DC -> 8, C S-> 10, CLK -> 13, DIN -> 11
#define SENSOR A0
#define PERIOD_MINUTES 3
#define USE_GxGDEP015OC1
//#define USE_MicroOLED
//#define USE_NETWORK
//#define RE_INIT_NEEDED
// SDA is on D2 GPIO04
// SCL is on D1 GPIO05
#include <Wire.h>
#include "Adafruit_SHT31.h"
#ifdef USE_GxGDEP015OC1
// include library, include base class, make path known
#include <GxEPD.h>
// select the display class to use
#include <GxGDEP015OC1/GxGDEP015OC1.h>
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
GxIO_Class io(SPI, SS, D3, D4);
// D2 reserved for SDA, use D6 (MISO) instead
GxEPD_Class display(io, D4, D6);
// FreeFonts from Adafruit_GFX
#include <Fonts/FreeSansBold18pt7b.h>
#include <Fonts/FreeSansBold24pt7b.h>
#endif
Adafruit_SHT31 myHumidity;
#include <ESP8266WiFi.h>
#ifdef ESP8266
extern "C"
{
#include "user_interface.h"
}
#endif
struct parameter_type
{
float delta_t;
float delta_h;
float sv_factor;
};
parameter_type parameter[] =
{
{ -0.5, +0.0, 0.00575 }, // 0 : ESP_1191B4
{ -0.5, +0.0, 0.00575 }, // 1 : ESP_118E0F
{ -0.5, +0.0, 0.00558 }, // 2 : ESP_246056 SHT21 D6RGP
{ -0.5, +3.0, 0.00558 }, // 3 : ESP_0BE239 HTU21 D5247 (+3% on 23° 63%)
{ -0.5, +0.0, 0.00558 }, // 4 : ESP_CC9456 HTU21 ok
{ -0.5, +0.0, 0.00665 }, // 5 : ESP_CAE971 SHT21 D6RGP
{ -0.0, +5.0, 0.00667 }, // 6 : ESP_D092C6 SHT21 D5M5E (rot) 300k
{ -0.5, +0.0, 0.00667 }, // 7 : ESP_D09477 SHT21 D6RGP 300k
{ -0.5, +0.0, 0.00575 }, // 8 : ESP_CC9268 SHT21 D6RGP
{ -0.0, +0.0, 0.00558 }, // 9 : ESP_CC844F HTU21 test
{ -0.0, +0.0, 0.00575 }, // 10 : ESP_CC9268 SHT31
{ -0.0, +0.0, 0.00667 }, // 11 : ESP_192589 SHT31 300k
{ -0.0, +0.0, 0.00558 }
};
int pidx = 11;
const char* ssid = "4D2DE33";
const char* password = "F4DFD1D1";
const int port = 80;
IPAddress IoTMasterIP = {192, 168, 4, 1};
// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(port);
WiFiClient client;
#ifdef USE_MicroOLED
// include this after ESP8266WiFi.h to avoid conflicting swap
#include <SFE_MicroOLED.h> // Include the SFE_MicroOLED library
// MicroOLED Definition
#define PIN_RESET 255 //
#define DC_JUMPER 0 // I2C Addres: 0 - 0x3C, 1 - 0x3D
// MicroOLED Object Declaration
MicroOLED oled(PIN_RESET, DC_JUMPER); // I2C declaration
#endif
byte ReadDHT(byte dht_dat[]);
void sendUpdateDHT22();
float SupplyVoltage = 5.0;
//#define Serial if(0) Serial
void setup()
{
Serial.begin(115200);
delay(10);
Serial.println();
Serial.println("setup");
SupplyVoltage = system_adc_read() * parameter[pidx].sv_factor;
Serial.print("SupplyVoltage=");
Serial.println(SupplyVoltage);
if (SupplyVoltage < 3.4) // Li 18650
{
Serial.println("SupplyVoltage low - going to sleep deep for 10 min");
system_deep_sleep(600000000);
return;
}
myHumidity.begin(SHT31_DEFAULT_ADDR); // 0x44
#ifdef USE_NETWORK
RandomInfo();
#ifdef RE_INIT_NEEDED
WiFi.persistent(true);
WiFi.mode(WIFI_STA); // switch off AP
WiFi.setAutoConnect(true);
WiFi.setAutoReconnect(true);
WiFi.disconnect();
#endif
if (!WiFi.getAutoConnect() || ( WiFi.getMode() != WIFI_STA) || (WiFi.SSID() != ssid))
{
Serial.println();
Serial.print("wifi_station_dhcpc_status()=");
Serial.println(wifi_station_dhcpc_status());
Serial.print("WiFi.getAutoConnect()=");
Serial.println(WiFi.getAutoConnect());
Serial.print("WiFi.SSID()=");
Serial.println(WiFi.SSID());
WiFi.mode(WIFI_STA); // switch off AP
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
}
int ConnectTimeout = 20; // 5 seconds
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
Serial.print(WiFi.status());
if (--ConnectTimeout <= 0)
{
Serial.println("WiFi connect timeout - going to sleep deep for 10 min");
system_deep_sleep(600000000);
return;
}
}
Serial.println("");
Serial.println("WiFi connected");
// Start the server
server.begin();
Serial.println("Server started");
// Print the IP address
Serial.println(WiFi.localIP());
WiFi.setOutputPower(20.5);
#endif // USE_NETWORK
#ifdef USE_MicroOLED
oled.begin(); // Initialize the OLED
oled.clear(ALL); // Clear the display's internal memory
oled.clear(PAGE); // Clear the buffer.
#endif
#ifdef USE_GxGDEP015OC1
display.init();
#endif
}
void loop()
{
sendUpdateDHT22();
Serial.println("system_deep_sleep");
system_deep_sleep(60000000 * PERIOD_MINUTES);
delay(120000);
}
double SaturationVaporPressure(double Temperature)
{
return 6.1078 * pow(10.0, ((7.5 * Temperature) / (237.3 + Temperature)));
}
double VaporPressure(double Humidity, double Temperature)
{
return Humidity / 100 * SaturationVaporPressure(Temperature);
}
double Humidity(double Temperature, double DewpointTemperature)
{
return 100 * SaturationVaporPressure(DewpointTemperature) / SaturationVaporPressure(Temperature);
}
double DewpointTemperature(double Humidity, double Temperature)
{
double v = log10(VaporPressure(Humidity, Temperature) / 6.1078);
return 237.3 * v / (7.5 - v);
}
double AbsoluteHumidity(double Humidity, double Temperature)
{
return 10e4 * 18.016 / 8314.3 * VaporPressure(Humidity, Temperature) / (Temperature + 273.15);
}
double AbsoluteHumidityFromDewpoint(double DewpointTemperature, double Temperature)
{
return 10e4 * 18.016 / 8314.3 * SaturationVaporPressure(DewpointTemperature) / (Temperature + 273.15);
}
void sendUpdateDHT22()
{
float humidity = myHumidity.readHumidity() + parameter[pidx].delta_h;
float temperature = myHumidity.readTemperature() + parameter[pidx].delta_t;
float dewpoint = DewpointTemperature(humidity, temperature);
//float water = AbsoluteHumidity(humidity, temperature);
float waterFDP = AbsoluteHumidityFromDewpoint(dewpoint, temperature);
char dC[3] = {'°', 'C', 0};
Serial.print("Current humdity = ");
Serial.print(humidity);
Serial.print("% ");
Serial.print("temperature = ");
Serial.print(temperature);
Serial.print(dC);
// Serial.print(" water=");
// Serial.print(water);
// Serial.print("g/m3");
Serial.print(" water=");
Serial.print(waterFDP);
Serial.print("g/m3");
Serial.print(" dewpoint = ");
Serial.print(dewpoint);
Serial.println(dC);
#ifdef USE_MicroOLED
int middleY = oled.getLCDHeight() / 2;
oled.clear(PAGE);
oled.setCursor(0, 0);
oled.setFontType(2);
oled.print(temperature, 1);
oled.setFontType(0); // no '°' in font 1 !
// oled.setCursor(oled.getLCDWidth()-oled.getFontWidth(), 0);
oled.print(" ");
oled.write(247); // '°' in font 0
oled.setCursor(0, middleY);
oled.setFontType(2);
oled.print(humidity, 1);
oled.setFontType(0);
// oled.setCursor(oled.getLCDWidth()-oled.getFontWidth(), middleY);
oled.print(" %");
oled.display();
#endif
#ifdef USE_GxGDEP015OC1
uint16_t middleY = display.height() / 2;
display.setRotation(3);
display.fillScreen(GxEPD_WHITE);
display.setTextColor(GxEPD_BLACK);
display.setFont(&FreeSansBold24pt7b);
display.setTextSize(2);
display.setCursor(8, 72);
display.print(temperature, 1);
display.setFont(&FreeSansBold18pt7b);
display.setTextSize(2);
display.setCursor(16, 146);
display.print(humidity, 1);
display.setTextSize(1);
display.print("%");
display.setCursor(16, 198);
display.print(dewpoint, 1);
display.print(" ");
display.print(SupplyVoltage, 1);
display.print("V");
display.update();
#endif
#ifdef USE_NETWORK
if (client.connect(IoTMasterIP, port))
{
Serial.println("IoTMaster connected successfully");
String postDHT22 = "POST /update/DHT22/?device=" +
String(wifi_station_get_hostname()) +
"&temperature=" + String(temperature, 1) +
"&humidity=" + String(humidity, 1) +
"&water=" + String(waterFDP, 1) +
"&dewpoint=" + String(dewpoint, 1) +
"&supply=" + String(SupplyVoltage, 1) +
" HTTP/1.1\n Host: " + String(WiFi.localIP()) + "Connection: close\n";
client.print(postDHT22);
}
else
{
Serial.println("IoTMaster connection failed - going to sleep deep for 10 min");
system_deep_sleep(600000000);
}
#endif
}
void RandomInfo()
{
long r1 = os_random();
long r2 = os_random();
Serial.print("random1 : ");
Serial.println(r1, HEX);
Serial.print("random2 : ");
Serial.println(r2, HEX);
}

View File

@@ -0,0 +1,209 @@
// PagedDisplayForSmallRam : test example for e-Paper displays from Waveshare and from Dalian Good Display Inc.
// shows how the full display screen can be used with Adafruit_GFX on small RAM Arduinos
// runs also on Arduinos with more RAM, e.g. ESP8266, for test
//
// Created by Jean-Marc Zingg based on demo code from Good Display for GDEP015OC1.
//
// The e-paper displays are available from:
//
// https://www.aliexpress.com/store/product/Wholesale-1-54inch-E-Ink-display-module-with-embedded-controller-200x200-Communicate-via-SPI-interface-Supports/216233_32824535312.html
//
// http://www.buy-lcd.com/index.php?route=product/product&path=2897_8363&product_id=35120
// or https://www.aliexpress.com/store/product/E001-1-54-inch-partial-refresh-Small-size-dot-matrix-e-paper-display/600281_32815089163.html
//
// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
// Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0
// mapping suggestion from Waveshare 2.9inch e-Paper to Wemos D1 mini
// BUSY -> D2, RST -> D4, DC -> D3, CS -> D8, CLK -> D5, DIN -> D7, GND -> GND, 3.3V -> 3.3V
// mapping suggestion from Waveshare 2.9inch e-Paper to generic ESP8266
// BUSY -> GPIO4, RST -> GPIO2, DC -> GPIO0, CS -> GPIO15, CLK -> GPIO14, DIN -> GPIO13, GND -> GND, 3.3V -> 3.3V
// mapping suggestion for ESP32, e.g. LOLIN32, see .../variants/.../pins_arduino.h for your board
// NOTE: there are variants with different pins for SPI ! CHECK SPI PINS OF YOUR BOARD
// BUSY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V
// mapping suggestion for AVR, UNO, NANO etc.
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 10, CLK -> 13, DIN -> 11
// mapping suggestion for Arduino MEGA
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 53, CLK -> 52, DIN -> 51
// include library, include base class, make path known
#include <GxEPD.h>
// select the display class to use, only one
//#include <GxDEPG0150BN/GxDEPG0150BN.h> // 1.54" b/w
//#include <GxGDEP015OC1/GxGDEP015OC1.h> // 1.54" b/w
//#include <GxGDEH0154D67/GxGDEH0154D67.h> // 1.54" b/w 200x200, SSD1681
//#include <GxGDEW0154T8/GxGDEW0154T8.h> // 1.54" b/w 152x152 UC8151 (IL0373)
//#include <GxGDEW0154M09/GxGDEW0154M09.h> // 1.54" b/w 200x200, JD79653A
//#include <GxGDEW0154M10/GxGDEW0154M10.h> // 1.54" b/w 152x152 UC8151D
//#include <GxGDEW0154Z04/GxGDEW0154Z04.h> // 1.54" b/w/r 200x200
//#include <GxGDEW0154Z17/GxGDEW0154Z17.h> // 1.54" b/w/r 152x152
//#include <GxGDEH0154Z90/GxGDEH0154Z90.h> // 1.54" b/w/r 200x200 SSD1681
//#include <GxGDEW0213I5F/GxGDEW0213I5F.h> // 2.13" b/w 104x212 flexible
//#include <GxGDE0213B1/GxGDE0213B1.h> // 2.13" b/w
//#include <GxGDEH0213B72/GxGDEH0213B72.h> // 2.13" b/w new panel
//#include <GxGDEH0213B73/GxGDEH0213B73.h> // 2.13" b/w newer panel
//#include <GxGDEM0213B74/GxGDEM0213B74.h> // 2.13" b/w 128x250, SSD1680
//#include <GxGDEW0213Z16/GxGDEW0213Z16.h> // 2.13" b/w/r
//#include <GxGDEH0213Z19/GxGDEH0213Z19.h> // 2.13" b/w/r UC8151D
//#include <GxGDEW0213T5D/GxGDEW0213T5D.h> // 2.13" b/w 104x212 UC8151D
//#include <GxDEPG0213BN/GxDEPG0213BN.h> // 2.13" b/w 128x250, SSD1680, TTGO T5 V2.4.1, V2.3.1
//#include <GxGDEH029A1/GxGDEH029A1.h> // 2.9" b/w
//#include <GxGDEW029T5/GxGDEW029T5.h> // 2.9" b/w IL0373
//#include <GxGDEW029T5D/GxGDEW029T5D.h> // 2.9" b/w UC8151D
//#include <GxGDEM029T94/GxGDEM029T94.h> // 2.9" b/w
//#include <GxDEPG0290BS/GxDEPG0290BS.h> // 2.9" b/w Waveshare variant, TTGO T5 V2.4.1 2.9"
//#include <GxGDEW029Z10/GxGDEW029Z10.h> // 2.9" b/w/r
//#include <GxGDEH029Z13/GxGDEH029Z13.h> // 2.9" b/w/r UC8151D
//#include <GxGDEW026T0/GxGDEW026T0.h> // 2.6" b/w // NOTE: does not compile for UNO: segmentation fault, reason unknown
//#include <GxDEPG0266BN/GxDEPG0266BN.h> // 2.66" b/w 152x296, SSD1680, TTGO T5 V2.66, TTGO T5 V2.4.1
//#include <GxGDEW027C44/GxGDEW027C44.h> // 2.7" b/w/r
//#include <GxGDEW027W3/GxGDEW027W3.h> // 2.7" b/w
//#include <GxGDEY027T91/GxGDEY027T91.h> // 2.7" b/w
//#include <GxGDEW0371W7/GxGDEW0371W7.h> // 3.7" b/w
//#include <GxGDEW042T2/GxGDEW042T2.h> // 4.2" b/w
//#include <GxGDEW042Z15/GxGDEW042Z15.h> // 4.2" b/w/r
//#include <GxGDEW0583T7/GxGDEW0583T7.h> // 5.83" b/w
//#include <GxGDEW075T8/GxGDEW075T8.h> // 7.5" b/w
//#include <GxGDEW075Z09/GxGDEW075Z09.h> // 7.5" b/w/r
//#include <GxGDEW075Z08/GxGDEW075Z08.h> // 7.5" b/w/r 800x480
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
// FreeFonts from Adafruit_GFX
#include <Fonts/FreeMonoBold9pt7b.h>
#include GxEPD_BitmapExamples
#if defined(ESP8266)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.2\variants\generic\common.h
GxIO_Class io(SPI, /*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2); // arbitrary selection of D3(=0), D4(=2), selected for default of GxEPD_Class
GxEPD_Class display(io, /*RST=D4*/ 2, /*BUSY=D2*/ 4); // default selection of D4(=2), D2(=4)
#elif defined(ESP32)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\espressif\esp32\variants\lolin32\pins_arduino.h
GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16); // arbitrary selection of 17, 16
GxEPD_Class display(io, /*RST=*/ 16, /*BUSY=*/ 4); // arbitrary selection of (16), 4
// for LILYGO® TTGO T5 2.66 board uncomment next two lines instead of previous two lines
//GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 19, /*RST=*/ 4); // LILYGO® TTGO T5 2.66
//GxEPD_Class display(io, /*RST=*/ 4, /*BUSY=*/ 34); // LILYGO® TTGO T5 2.66
#elif defined(ARDUINO_ARCH_SAMD)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.19\variants\mkr1000\variant.h
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.19\variants\mkrzero\variant.h
GxIO_Class io(SPI, /*CS=*/ 4, /*DC=*/ 7, /*RST=*/ 6);
GxEPD_Class display(io, /*RST=*/ 6, /*BUSY=*/ 5);
#elif defined(ARDUINO_GENERIC_STM32F103C) && defined(MCU_STM32F103C8)
// STM32 Boards(STM32duino.com) Generic STM32F103C series STM32F103C8
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\variant.h
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\board\board.h
// new mapping suggestion for STM32F1, e.g. STM32F103C8T6 "BluePill"
// BUSY -> A1, RST -> A2, DC -> A3, CS-> A4, CLK -> A5, DIN -> A7
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 3, /*RST=*/ 2);
GxEPD_Class display(io, /*RST=*/ 2, /*BUSY=*/ 1);
#elif defined(ARDUINO_GENERIC_STM32F103V) && defined(MCU_STM32F103VB)
// STM32 Boards(STM32duino.com) Generic STM32F103V series STM32F103VB
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103vb\variant.h
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103vb\board\board.h
// Good Display DESPI-M01
// note: needs jumper wires from SS=PA4->CS, SCK=PA5->SCK, MOSI=PA7->SDI
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ PE15, /*RST=*/ PE14); // DC, RST as wired by DESPI-M01
GxEPD_Class display(io, /*RST=*/ PE14, /*BUSY=*/ PE13); // RST, BUSY as wired by DESPI-M01
#elif defined(ARDUINO_AVR_MEGA2560)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\mega\pins_arduino.h
// select one, depending on your CS connection
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
//GxIO_Class io(SPI, /*CS=*/ 10, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9, CS on 10 (for CS same as on UNO, for SPI on ICSP use)
GxEPD_Class display(io, /*RST=*/ 9, /*BUSY=*/ 7); // default selection of (9), 7
#else
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\standard\pins_arduino.h
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
GxEPD_Class display(io, /*RST=*/ 9, /*BUSY=*/ 7); // default selection of (9), 7
#endif
//#define DEMO_DELAY 3*60 // seconds
//#define DEMO_DELAY 1*60 // seconds
#define DEMO_DELAY 10
void setup(void)
{
Serial.begin(115200);
Serial.println();
Serial.println("setup");
display.init(115200); // enable diagnostic output on Serial
Serial.println("setup done");
}
void loop()
{
#if defined(_GxGDEW0154Z04_H_) || defined(_GxGDEH0154Z90_H_) || defined(_GxGDEW0213Z16_H_) || defined(_GxGDEW029Z10_H_) || defined(_GxGDEW027C44_H_)
display.drawExamplePicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
#elif !defined(__AVR) && defined(_GxGDEW042Z15_H_)
display.drawExamplePicture(BitmapExample1, BitmapExample2, sizeof(BitmapExample1), sizeof(BitmapExample2));
#else
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
#endif
delay(DEMO_DELAY * 1000);
display.drawPaged(showFontCallback);
display.powerDown();
delay(DEMO_DELAY * 1000);
}
void showFontCallback()
{
const char* name = "FreeMonoBold9pt7b";
const GFXfont* f = &FreeMonoBold9pt7b;
display.fillScreen(GxEPD_WHITE);
display.setTextColor(GxEPD_BLACK);
display.setFont(f);
display.setCursor(0, 0);
display.println();
display.println(name);
display.println(" !\"#$%&'()*+,-./");
display.println("0123456789:;<=>?");
display.println("@ABCDEFGHIJKLMNO");
display.println("PQRSTUVWXYZ[\\]^_");
#if defined(_GxGDEW0154Z04_H_) || defined(_GxGDEH0154Z90_H_) || defined(_GxGDEW0213Z16_H_) || defined(_GxGDEW029Z10_H_) \
|| defined(_GxGDEW027C44_H_) || defined(_GxGDEW042Z15_H_) || defined(_GxGDEW075Z09_H_) || defined(_GxGDEW075Z08_H_)
display.setTextColor(GxEPD_RED);
#endif
display.println("`abcdefghijklmno");
display.println("pqrstuvwxyz{|}~ ");
}

View File

@@ -0,0 +1,454 @@
// PartialUpdateExample : example for Waveshare 1.54", 2.31" and 2.9" e-Paper and the same e-papers from Dalian Good Display Inc.
//
// Created by Jean-Marc Zingg based on demo code from Good Display for GDEP015OC1.
//
// The e-paper displays are available from:
//
// https://www.aliexpress.com/store/product/Wholesale-1-54inch-E-Ink-display-module-with-embedded-controller-200x200-Communicate-via-SPI-interface-Supports/216233_32824535312.html
//
// http://www.buy-lcd.com/index.php?route=product/product&path=2897_8363&product_id=35120
// or https://www.aliexpress.com/store/product/E001-1-54-inch-partial-refresh-Small-size-dot-matrix-e-paper-display/600281_32815089163.html
//
// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
// Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0
// mapping suggestion from Waveshare 2.9inch e-Paper to Wemos D1 mini
// BUSY -> D2, RST -> D4, DC -> D3, CS -> D8, CLK -> D5, DIN -> D7, GND -> GND, 3.3V -> 3.3V
// mapping suggestion from Waveshare 2.9inch e-Paper to generic ESP8266
// BUSY -> GPIO4, RST -> GPIO2, DC -> GPIO0, CS -> GPIO15, CLK -> GPIO14, DIN -> GPIO13, GND -> GND, 3.3V -> 3.3V
// mapping suggestion for ESP32, e.g. LOLIN32, see .../variants/.../pins_arduino.h for your board
// NOTE: there are variants with different pins for SPI ! CHECK SPI PINS OF YOUR BOARD
// BUSY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V
// mapping suggestion for AVR, UNO, NANO etc.
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 10, CLK -> 13, DIN -> 11
// mapping suggestion for Arduino MEGA
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 53, CLK -> 52, DIN -> 51
// mapping suggestion for Arduino DUE
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 77, CLK -> 76, DIN -> 75
// SPI pins are also on 6 pin 2x3 SPI header
// include library, include base class, make path known
#include <GxEPD.h>
// select the display class to use, only one
//#include <GxDEPG0150BN/GxDEPG0150BN.h> // 1.50" b/w
//#include <GxGDEP015OC1/GxGDEP015OC1.h> // 1.54" b/w
//#include <GxGDEH0154D67/GxGDEH0154D67.h> // 1.54" b/w 200x200, SSD1681
//#include <GxGDEW0154T8/GxGDEW0154T8.h> // 1.54" b/w 152x152 UC8151 (IL0373)
//#include <GxGDEW0154M09/GxGDEW0154M09.h> // 1.54" b/w 200x200, JD79653A
//#include <GxGDEW0154M10/GxGDEW0154M10.h> // 1.54" b/w 152x152 UC8151D
//#include <GxGDEH0154Z90/GxGDEH0154Z90.h> // 1.54" b/w/r 200x200 SSD1681
//#include <GxGDEW0213I5F/GxGDEW0213I5F.h> // 2.13" b/w 104x212 flexible
//#include <GxGDE0213B1/GxGDE0213B1.h> // 2.13" b/w
//#include <GxGDEH0213B72/GxGDEH0213B72.h> // 2.13" b/w new panel
//#include <GxGDEH0213B73/GxGDEH0213B73.h> // 2.13" b/w newer panel
//#include <GxGDEM0213B74/GxGDEM0213B74.h> // 2.13" b/w 128x250, SSD1680
//#include <GxGDEW0213T5D/GxGDEW0213T5D.h> // 2.13" b/w 104x212 UC8151D
//#include <GxDEPG0213BN/GxDEPG0213BN.h> // 2.13" b/w 128x250, SSD1680, TTGO T5 V2.4.1, V2.3.1
//#include <GxGDEH029A1/GxGDEH029A1.h> // 2.9" b/w
//#include <GxGDEW029T5/GxGDEW029T5.h> // 2.9" b/w UC8151 (IL0373)
//#include <GxGDEW029T5D/GxGDEW029T5D.h> // 2.9" b/w UC8151D
//#include <GxGDEM029T94/GxGDEM029T94.h> // 2.9" b/w
//#include <GxDEPG0290BS/GxDEPG0290BS.h> // 2.9" b/w Waveshare variant, TTGO T5 V2.4.1 2.9"
//#include <GxGDEW026T0/GxGDEW026T0.h> // 2.6" b/w
//#include <GxDEPG0266BN/GxDEPG0266BN.h> // 2.66" b/w 152x296, SSD1680, TTGO T5 V2.66, TTGO T5 V2.4.1
//#include <GxGDEW027W3/GxGDEW027W3.h> // 2.7" b/w
//#include <GxGDEY027T91/GxGDEY027T91.h> // 2.7" b/w
//#include <GxGDEW0371W7/GxGDEW0371W7.h> // 3.7" b/w
//#include <GxGDEW042T2/GxGDEW042T2.h> // 4.2" b/w
//#include <GxGDEW075T7/GxGDEW075T7.h> // 7.5" b/w 800x480
// these displays do not fully support partial update
//#include <GxGDEW0154Z17/GxGDEW0154Z17.h> // 1.54" b/w/r 152x152
//#include <GxGDEH0154Z90/GxGDEH0154Z90.h> // 1.54" b/w/r 200x200 SSD1681
//#include <GxGDEW0213Z16/GxGDEW0213Z16.h> // 2.13" b/w/r
//#include <GxGDEH0213Z19/GxGDEH0213Z19.h> // 2.13" b/w/r UC8151D
//#include <GxGDEW029Z10/GxGDEW029Z10.h> // 2.9" b/w/r
//#include <GxGDEH029Z13/GxGDEH029Z13.h> // 2.9" b/w/r UC8151D
//#include <GxGDEW027C44/GxGDEW027C44.h> // 2.7" b/w/r
//#include <GxGDEW042Z15/GxGDEW042Z15.h> // 4.2" b/w/r
//#include <GxGDEW0583T7/GxGDEW0583T7.h> // 5.83" b/w
//#include <GxGDEW075T8/GxGDEW075T8.h> // 7.5" b/w
//#include <GxGDEW075Z09/GxGDEW075Z09.h> // 7.5" b/w/r
//#include <GxGDEW075Z08/GxGDEW075Z08.h> // 7.5" b/w/r 800x480
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
// FreeFonts from Adafruit_GFX
#include <Fonts/FreeMonoBold9pt7b.h>
#include GxEPD_BitmapExamples
#if defined(ESP8266)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.2\variants\generic\common.h
GxIO_Class io(SPI, /*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2); // arbitrary selection of D3(=0), D4(=2), selected for default of GxEPD_Class
GxEPD_Class display(io, /*RST=D4*/ 2, /*BUSY=D2*/ 4); // default selection of D4(=2), D2(=4)
#elif defined(ESP32)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\espressif\esp32\variants\lolin32\pins_arduino.h
GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16); // arbitrary selection of 17, 16
GxEPD_Class display(io, /*RST=*/ 16, /*BUSY=*/ 4); // arbitrary selection of (16), 4
// for LILYGO® TTGO T5 2.66 board uncomment next two lines instead of previous two lines
//GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 19, /*RST=*/ 4); // LILYGO® TTGO T5 2.66
//GxEPD_Class display(io, /*RST=*/ 4, /*BUSY=*/ 34); // LILYGO® TTGO T5 2.66
#elif defined(ARDUINO_ARCH_SAMD)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.19\variants\mkr1000\variant.h
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.19\variants\mkrzero\variant.h
GxIO_Class io(SPI, /*CS=*/ 4, /*DC=*/ 7, /*RST=*/ 6);
GxEPD_Class display(io, /*RST=*/ 6, /*BUSY=*/ 5);
#elif defined(ARDUINO_GENERIC_STM32F103C) && defined(MCU_STM32F103C8)
// STM32 Boards(STM32duino.com) Generic STM32F103C series STM32F103C8
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\variant.h
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\board\board.h
// new mapping suggestion for STM32F1, e.g. STM32F103C8T6 "BluePill"
// BUSY -> A1, RST -> A2, DC -> A3, CS-> A4, CLK -> A5, DIN -> A7
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 3, /*RST=*/ 2);
GxEPD_Class display(io, /*RST=*/ 2, /*BUSY=*/ 1);
#elif defined(ARDUINO_GENERIC_STM32F103V) && defined(MCU_STM32F103VB)
// STM32 Boards(STM32duino.com) Generic STM32F103V series STM32F103VB
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103vb\variant.h
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103vb\board\board.h
// Good Display DESPI-M01
// note: needs jumper wires from SS=PA4->CS, SCK=PA5->SCK, MOSI=PA7->SDI
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ PE15, /*RST=*/ PE14); // DC, RST as wired by DESPI-M01
GxEPD_Class display(io, /*RST=*/ PE14, /*BUSY=*/ PE13); // RST, BUSY as wired by DESPI-M01
#elif defined(ARDUINO_AVR_MEGA2560)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\mega\pins_arduino.h
// select one, depending on your CS connection
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
//GxIO_Class io(SPI, /*CS=*/ 10, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9, CS on 10 (for CS same as on UNO, for SPI on ICSP use)
GxEPD_Class display(io, /*RST=*/ 9, /*BUSY=*/ 7); // default selection of (9), 7
#else
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\standard\pins_arduino.h
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
GxEPD_Class display(io, /*RST=*/ 9, /*BUSY=*/ 7); // default selection of (9), 7
#endif
//#define DEMO_DELAY 3*60 // seconds
//#define DEMO_DELAY 1*60 // seconds
#define DEMO_DELAY 30
void setup(void)
{
Serial.begin(115200);
Serial.println();
Serial.println("setup");
display.init(115200); // enable diagnostic output on Serial
Serial.println("setup done");
}
void loop()
{
#if defined(__AVR) || false
showPartialUpdatePaged();
#elif (defined(_GxGDEW075Z09_H_) || defined(_GxGDEW075Z08_H_)) && (defined(ESP8266) || defined(ARDUINO_ARCH_STM32F1))
showPartialUpdatePaged();
#elif defined(_GxGDEW075Z09_H_)
showPartialUpdate_75Z09();
#else
showPartialUpdate();
#endif
display.powerDown();
delay(DEMO_DELAY * 1000);
}
#if !defined(__AVR)
void showPartialUpdate()
{
// use asymmetric values for test
uint16_t box_x = 10;
uint16_t box_y = 15;
uint16_t box_w = 70;
uint16_t box_h = 20;
uint16_t cursor_y = box_y + box_h - 6;
float value = 13.95;
display.setFont(&FreeMonoBold9pt7b);
display.setTextColor(GxEPD_BLACK);
display.setRotation(0);
// draw background
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
delay(2000);
// partial update to full screen to preset for partial update of box window
// (this avoids strange background effects)
display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, false);
// show where the update box is
for (uint16_t r = 0; r < 4; r++)
{
display.setRotation(r);
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_BLACK);
display.updateWindow(box_x, box_y, box_w, box_h, true);
delay(1000);
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.updateWindow(box_x, box_y, box_w, box_h, true);
}
// show updates in the update box
for (uint16_t r = 0; r < 4; r++)
{
// reset the background
display.setRotation(0);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, false);
display.setRotation(r);
for (uint16_t i = 1; i <= 10; i++)
{
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.setCursor(box_x, cursor_y);
display.print(value * i, 2);
display.updateWindow(box_x, box_y, box_w, box_h, true);
delay(2000);
}
delay(2000);
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.updateWindow(box_x, box_y, box_w, box_h, true);
}
// should have checked this, too
box_x = GxEPD_HEIGHT - box_x - box_w - 1; // not valid for all corners
// should show on right side of long side
// reset the background
display.setRotation(0);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, false);
// show where the update box is
for (uint16_t r = 0; r < 4; r++)
{
display.setRotation(r);
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_BLACK);
display.updateWindow(box_x, box_y, box_w, box_h, true);
delay(1000);
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.updateWindow(box_x, box_y, box_w, box_h, true);
}
// show updates in the update box
for (uint16_t r = 0; r < 4; r++)
{
// reset the background
display.setRotation(0);
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, false);
display.setRotation(r);
if (box_x >= display.width()) continue; // avoid delay
for (uint16_t i = 1; i <= 10; i++)
{
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.setCursor(box_x, cursor_y);
display.print(value * i, 2);
display.updateWindow(box_x, box_y, box_w, box_h, true);
delay(2000);
}
delay(2000);
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.updateWindow(box_x, box_y, box_w, box_h, true);
}
display.setRotation(0);
display.powerDown();
}
#endif
#if defined(_GxGDEW075Z09_H_) && !(defined(ESP8266) || defined(ARDUINO_ARCH_STM32F1))
void showPartialUpdate_75Z09()
{
// use asymmetric values for test
uint16_t box_x = 10;
uint16_t box_y = 15;
uint16_t box_w = 70;
uint16_t box_h = 20;
uint16_t cursor_y = box_y + box_h - 6;
float value = 13.95;
display.setFont(&FreeMonoBold9pt7b);
display.setTextColor(GxEPD_BLACK);
display.setRotation(0);
// draw background, partial update to full screen to preset for partial update of box window
// (updateWindow() would clear display if partial update not set, to avoid strange background effect)
display.drawExamplePicture_3C(BitmapPicture_3C, sizeof(BitmapPicture_3C), GxEPD::bm_partial_update);
// show where the update box is
for (uint16_t r = 0; r < 4; r++)
{
display.setRotation(r);
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_BLACK);
display.updateWindow(box_x, box_y, box_w, box_h, true);
delay(1000);
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.updateWindow(box_x, box_y, box_w, box_h, true);
}
// show updates in the update box
for (uint16_t r = 0; r < 4; r++)
{
// reset the background
display.setRotation(0);
display.drawExamplePicture_3C(BitmapPicture_3C, sizeof(BitmapPicture_3C), GxEPD::bm_partial_update);
display.setRotation(r);
for (uint16_t i = 1; i <= 10; i++)
{
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.setCursor(box_x, cursor_y);
display.print(value * i, 2);
display.updateWindow(box_x, box_y, box_w, box_h, true);
delay(2000);
}
delay(2000);
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.updateWindow(box_x, box_y, box_w, box_h, true);
}
// should have checked this, too
box_x = GxEPD_HEIGHT - box_x - box_w - 1; // not valid for all corners
// should show on right side of long side
// reset the background
display.setRotation(0);
display.drawExamplePicture_3C(BitmapPicture_3C, sizeof(BitmapPicture_3C), GxEPD::bm_partial_update);
// show where the update box is
for (uint16_t r = 0; r < 4; r++)
{
display.setRotation(r);
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_BLACK);
display.updateWindow(box_x, box_y, box_w, box_h, true);
delay(1000);
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.updateWindow(box_x, box_y, box_w, box_h, true);
}
// show updates in the update box
for (uint16_t r = 0; r < 4; r++)
{
// reset the background
display.setRotation(0);
display.drawExamplePicture_3C(BitmapPicture_3C, sizeof(BitmapPicture_3C), GxEPD::bm_partial_update);
display.setRotation(r);
if (box_x >= display.width()) continue; // avoid delay
for (uint16_t i = 1; i <= 10; i++)
{
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.setCursor(box_x, cursor_y);
display.print(value * i, 2);
display.updateWindow(box_x, box_y, box_w, box_h, true);
delay(2000);
}
delay(2000);
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.updateWindow(box_x, box_y, box_w, box_h, true);
}
display.setRotation(0);
display.powerDown();
}
#endif
#if defined(__AVR) || (defined(_GxGDEW075Z09_H_) || defined(_GxGDEW075Z08_H_)) && (defined(ESP8266) || defined(ARDUINO_ARCH_STM32F1)) || false
// modified to avoid float; reduces program size ~2k (for GxGDEW042T2)
void showBlackBoxCallback(uint32_t v)
{
uint16_t box_x = 10;
uint16_t box_y = 15;
uint16_t box_w = 70;
uint16_t box_h = 20;
display.fillRect(box_x, box_y, box_w, box_h, v);
}
void showValueBoxCallback(const uint32_t v)
{
uint16_t box_x = 10;
uint16_t box_y = 15;
uint16_t box_w = 70;
uint16_t box_h = 20;
uint16_t cursor_y = box_y + box_h - 6;
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.setCursor(box_x, cursor_y);
display.print(v / 100);
display.print(v % 100 > 9 ? "." : ".0");
display.print(v % 100);
}
void showPartialUpdatePaged()
{
uint16_t box_x = 10;
uint16_t box_y = 15;
uint16_t box_w = 70;
uint16_t box_h = 20;
uint32_t value = 1395;
display.setFont(&FreeMonoBold9pt7b);
display.setTextColor(GxEPD_BLACK);
display.setRotation(0);
// draw background
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(2000);
// partial update to full screen to preset for partial update of box window
// (this avoids strange background effects)
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1), GxEPD::bm_default | GxEPD::bm_partial_update);
delay(1000);
// show where the update box is
for (uint16_t r = 0; r < 4; r++)
{
display.setRotation(r);
display.drawPagedToWindow(showBlackBoxCallback, box_x, box_y, box_w, box_h, GxEPD_BLACK);
delay(1000);
display.drawPagedToWindow(showBlackBoxCallback, box_x, box_y, box_w, box_h, GxEPD_WHITE);
}
// show updates in the update box
for (uint16_t r = 0; r < 4; r++)
{
// reset the background
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1), GxEPD::bm_default | GxEPD::bm_partial_update);
display.setRotation(r);
for (uint16_t i = 1; i <= 10; i++)
{
uint32_t v = value * i;
display.drawPagedToWindow(showValueBoxCallback, box_x, box_y, box_w, box_h, v);
delay(500);
}
delay(1000);
display.drawPagedToWindow(showBlackBoxCallback, box_x, box_y, box_w, box_h, GxEPD_WHITE);
}
// reset the background
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1), GxEPD::bm_default | GxEPD::bm_partial_update);
display.setRotation(0);
display.powerDown();
}
#endif

View File

@@ -0,0 +1,269 @@
// PartialUpdateTest : example for Waveshare 1.54", 2.31" and 2.9" e-Paper and the same e-papers from Dalian Good Display Inc.
//
// Created by Jean-Marc Zingg based on demo code from Good Display for GDEP015OC1.
//
// The e-paper displays are available from:
//
// https://www.aliexpress.com/store/product/Wholesale-1-54inch-E-Ink-display-module-with-embedded-controller-200x200-Communicate-via-SPI-interface-Supports/216233_32824535312.html
//
// http://www.buy-lcd.com/index.php?route=product/product&path=2897_8363&product_id=35120
// or https://www.aliexpress.com/store/product/E001-1-54-inch-partial-refresh-Small-size-dot-matrix-e-paper-display/600281_32815089163.html
//
// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
// Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0
// mapping from Waveshare 2.9inch e-Paper to Wemos D1 mini
// BUSY -> D2, RST -> D4, DC -> D3, CS -> D8, CLK -> D5, DIN -> D7, GND -> GND, 3.3V -> 3.3V
// mapping example for AVR, UNO, NANO etc.
// BUSY -> 7, RST -> 9, DC -> 8, C S-> 10, CLK -> 13, DIN -> 11
// include library, include base class, make path known
#include <GxEPD.h>
// select the display class to use, only one
//#include <GxDEPG0150BN/GxDEPG0150BN.h> // 1.50" b/w
//#include <GxGDEP015OC1/GxGDEP015OC1.h> // 1.54" b/w
//#include <GxGDEH0154D67/GxGDEH0154D67.h> // 1.54" b/w 200x200, SSD1681
//#include <GxGDEW0154T8/GxGDEW0154T8.h> // 1.54" b/w 152x152 UC8151 (IL0373)
//#include <GxGDEW0154M09/GxGDEW0154M09.h> // 1.54" b/w 200x200 JD79653A
//#include <GxGDEW0154M10/GxGDEW0154M10.h> // 1.54" b/w 152x152 UC8151D
//#include <GxGDEW0154Z04/GxGDEW0154Z04.h> // 1.54" b/w/r 200x200
//#include <GxGDEW0154Z17/GxGDEW0154Z17.h> // 1.54" b/w/r 152x152
//#include <GxGDEH0154Z90/GxGDEH0154Z90.h> // 1.54" b/w/r 200x200 SSD1681
//#include <GxGDEW0213I5F/GxGDEW0213I5F.h> // 2.13" b/w 104x212 flexible
//#include <GxGDE0213B1/GxGDE0213B1.h> // 2.13" b/w
//#include <GxGDEH0213B72/GxGDEH0213B72.h> // 2.13" b/w new panel
//#include <GxGDEH0213B73/GxGDEH0213B73.h> // 2.13" b/w newer panel
//#include <GxGDEM0213B74/GxGDEM0213B74.h> // 2.13" b/w 128x250 SSD1680
//#include <GxGDEW0213Z16/GxGDEW0213Z16.h> // 2.13" b/w/r
//#include <GxGDEH0213Z19/GxGDEH0213Z19.h> // 2.13" b/w/r UC8151D
//#include <GxGDEW0213T5D/GxGDEW0213T5D.h> // 2.13" b/w 104x212 UC8151D
//#include <GxDEPG0213BN/GxDEPG0213BN.h> // 2.13" b/w 128x250, SSD1680, TTGO T5 V2.4.1, V2.3.1
//#include <GxGDEH029A1/GxGDEH029A1.h> // 2.9" b/w
//#include <GxGDEW029T5/GxGDEW029T5.h> // 2.9" b/w UC8151 (IL0373)
//#include <GxGDEW029T5D/GxGDEW029T5D.h> // 2.9" b/w UC8151D
//#include <GxGDEM029T94/GxGDEM029T94.h> // 2.9" b/w
//#include <GxDEPG0290BS/GxDEPG0290BS.h> // 2.9" b/w Waveshare variant, TTGO T5 V2.4.1 2.9"
//#include <GxGDEW029Z10/GxGDEW029Z10.h> // 2.9" b/w/r
//#include <GxGDEH029Z13/GxGDEH029Z13.h> // 2.9" b/w/r UC8151D
//#include <GxGDEW026T0/GxGDEW026T0.h> // 2.6" b/w
//#include <GxDEPG0266BN/GxDEPG0266BN.h> // 2.66" b/w 152x296, SSD1680, TTGO T5 V2.66, TTGO T5 V2.4.1
//#include <GxGDEW027C44/GxGDEW027C44.h> // 2.7" b/w/r
//#include <GxGDEW027W3/GxGDEW027W3.h> // 2.7" b/w
//#include <GxGDEY027T91/GxGDEY027T91.h> // 2.7" b/w
//#include <GxGDEW0371W7/GxGDEW0371W7.h> // 3.7" b/w
//#include <GxGDEW042T2/GxGDEW042T2.h> // 4.2" b/w
//#include <GxGDEW042Z15/GxGDEW042Z15.h> // 4.2" b/w/r
//#include <GxGDEW0583T7/GxGDEW0583T7.h> // 5.83" b/w
//#include <GxGDEW075T8/GxGDEW075T8.h> // 7.5" b/w
//#include <GxGDEW075T7/GxGDEW075T7.h> // 7.5" b/w 800x480
//#include <GxGDEW075Z09/GxGDEW075Z09.h> // 7.5" b/w/r
//#include <GxGDEW075Z08/GxGDEW075Z08.h> // 7.5" b/w/r 800x480
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>
// FreeFonts from Adafruit_GFX
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include GxEPD_BitmapExamples
#if defined(ESP8266)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.2\variants\generic\common.h
GxIO_Class io(SPI, /*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2); // arbitrary selection of D3(=0), D4(=2), selected for default of GxEPD_Class
GxEPD_Class display(io /*RST=D4*/ /*BUSY=D2*/); // default selection of D4(=2), D2(=4)
#elif defined(ESP32)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\espressif\esp32\variants\lolin32\pins_arduino.h
GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16); // arbitrary selection of 17, 16
GxEPD_Class display(io, /*RST=*/ 16, /*BUSY=*/ 4); // arbitrary selection of (16), 4
// for LILYGO® TTGO T5 2.66 board uncomment next two lines instead of previous two lines
//GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 19, /*RST=*/ 4); // LILYGO® TTGO T5 2.66
//GxEPD_Class display(io, /*RST=*/ 4, /*BUSY=*/ 34); // LILYGO® TTGO T5 2.66
#elif defined(ARDUINO_ARCH_SAMD)
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.19\variants\mkr1000\variant.h
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.19\variants\mkrzero\variant.h
GxIO_Class io(SPI, /*CS=*/ 4, /*DC=*/ 7, /*RST=*/ 6);
GxEPD_Class display(io, /*RST=*/ 6, /*BUSY=*/ 5);
#elif defined(_BOARD_GENERIC_STM32F103C_H_)
// STM32 Boards(STM32duino.com) Generic STM32F103C series STM32F103C8
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\variant.h
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\board\board.h
// new mapping suggestion for STM32F1, e.g. STM32F103C8T6 "BluePill"
// BUSY -> A1, RST -> A2, DC -> A3, CS-> A4, CLK -> A5, DIN -> A7
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 3, /*RST=*/ 2);
GxEPD_Class display(io, /*RST=*/ 2, /*BUSY=*/ 1);
#elif defined(ARDUINO_GENERIC_STM32F103V) && defined(MCU_STM32F103VB)
// STM32 Boards(STM32duino.com) Generic STM32F103V series STM32F103VB
// for SPI pin definitions see e.g.:
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103vb\variant.h
// C:\Users\xxx\Documents\Arduino\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103vb\board\board.h
// Good Display DESPI-M01
// note: needs jumper wires from SS=PA4->CS, SCK=PA5->SCK, MOSI=PA7->SDI
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ PE15, /*RST=*/ PE14); // DC, RST as wired by DESPI-M01
GxEPD_Class display(io, /*RST=*/ PE14, /*BUSY=*/ PE13); // RST, BUSY as wired by DESPI-M01
#else
// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\standard\pins_arduino.h
GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
GxEPD_Class display(io /*RST=9*/ /*BUSY=7*/); // default selection of (9), 7
#endif
#if defined(_GxGDEP015OC1_H_) || defined(_GxGDEH0154D67_H_)
const uint32_t partial_update_period_s = 1;
const uint32_t full_update_period_s = 6 * 60 * 60;
#elif defined(_GxGDE0213B1_H_) || defined(_GxGDEH029A1_H_) || defined(_GxGDEM029T94_H_) || defined(_GxGDEW042T2_H_)
const uint32_t partial_update_period_s = 2;
const uint32_t full_update_period_s = 1 * 60 * 60;
#else
const uint32_t partial_update_period_s = 2;
const uint32_t full_update_period_s = 1 * 60 * 60;
#endif
uint32_t start_time;
uint32_t next_time;
uint32_t previous_time;
uint32_t previous_full_update;
uint32_t total_seconds = 0;
uint32_t seconds, minutes, hours, days;
void setup(void)
{
Serial.begin(115200);
Serial.println();
Serial.println("setup");
//display.init(115200); // enable diagnostic output on Serial
display.init(); // disable diagnostic output on Serial
Serial.println("setup done");
display.setTextColor(GxEPD_BLACK);
display.setRotation(0);
// draw background
#if defined(__AVR) && defined(_GxGDEW042T2_H_)
// cope with code size limitation
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
display.setFont(&FreeMonoBold9pt7b);
#else
display.drawExampleBitmap(BitmapExample1, 0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, GxEPD_BLACK);
display.update();
display.setFont(&FreeMonoBold12pt7b);
#endif
// partial update to full screen to preset for partial update of box window
// (this avoids strange background effects)
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1), GxEPD::bm_default | GxEPD::bm_partial_update);
start_time = next_time = previous_time = previous_full_update = millis();
display.setRotation(1);
}
void loop()
{
uint32_t actual = millis();
while (actual < next_time)
{
// the "BlinkWithoutDelay" method works also for overflowed millis
if ((actual - previous_time) > (partial_update_period_s * 1000))
{
//Serial.print(actual - previous_time); Serial.print(" > "); Serial.println(partial_update_period_s * 1000);
break;
}
delay(100);
actual = millis();
}
//Serial.print("actual: "); Serial.print(actual); Serial.print(" previous: "); Serial.println(previous_time);
if ((actual - previous_full_update) > full_update_period_s * 1000)
{
#if defined(__AVR) && defined(_GxGDEW042T2_H_)
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1), GxEPD::bm_default | GxEPD::bm_partial_update);
#else
display.update();
#endif
previous_full_update = actual;
}
previous_time = actual;
next_time += uint32_t(partial_update_period_s * 1000);
total_seconds += partial_update_period_s;
seconds = total_seconds % 60;
minutes = (total_seconds / 60) % 60;
hours = (total_seconds / 3600) % 24;
days = (total_seconds / 3600) / 24;
#if defined(__AVR)
showPartialUpdate_AVR();
#else
showPartialUpdate();
#endif
}
void print02d(uint32_t d)
{
if (d < 10) display.print("0");
display.print(d);
}
#if !defined(__AVR)
void showPartialUpdate()
{
uint16_t box_x = 10;
uint16_t box_y = 15;
uint16_t box_w = 170;
uint16_t box_h = 20;
uint16_t cursor_y = box_y + 16;
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.setCursor(box_x, cursor_y);
display.print(days); display.print("d "); print02d(hours); display.print(":"); print02d(minutes); display.print(":"); print02d(seconds);
display.updateWindow(box_x, box_y, box_w, box_h, true);
}
#else
void drawCallback()
{
uint16_t box_x = 10;
uint16_t box_y = 15;
uint16_t box_w = 170;
uint16_t box_h = 20;
uint16_t cursor_y = box_y + 16;
display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
display.setCursor(box_x, cursor_y);
display.print(days); display.print("d "); print02d(hours); display.print(":"); print02d(minutes); display.print(":"); print02d(seconds);
}
void showPartialUpdate_AVR()
{
uint16_t box_x = 10;
uint16_t box_y = 15;
uint16_t box_w = 170;
uint16_t box_h = 20;
uint16_t cursor_y = box_y + 14;
display.drawPagedToWindow(drawCallback, box_x, box_y, box_w, box_h);
}
#endif