GxEPD2_MultiDisplayExample.ino 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  1. // GxEPD2_MultiDisplayExample : Display Library example for SPI e-paper panels from Dalian Good Display and boards from Waveshare.
  2. // Requires HW SPI and Adafruit_GFX. Caution: these e-papers require 3.3V supply AND data lines!
  3. //
  4. // Display Library based on Demo Example from Good Display: http://www.good-display.com/download_list/downloadcategoryid=34&isMode=false.html
  5. //
  6. // Author: Jean-Marc Zingg
  7. //
  8. // Version: see library.properties
  9. //
  10. // Library: https://github.com/ZinggJM/GxEPD2
  11. // Supporting Arduino Forum Topics:
  12. // Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
  13. // Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0
  14. // mapping suggestion from Waveshare SPI e-Paper to Wemos D1 mini
  15. // BUSY -> D2, RST -> D4, DC -> D3, CS -> D8, CLK -> D5, DIN -> D7, GND -> GND, 3.3V -> 3.3V
  16. // mapping suggestion from Waveshare SPI e-Paper to generic ESP8266
  17. // BUSY -> GPIO4, RST -> GPIO2, DC -> GPIO0, CS -> GPIO15, CLK -> GPIO14, DIN -> GPIO13, GND -> GND, 3.3V -> 3.3V
  18. // mapping of Waveshare e-Paper ESP8266 Driver Board
  19. // BUSY -> GPIO16, RST -> GPIO5, DC -> GPIO4, CS -> GPIO15, CLK -> GPIO14, DIN -> GPIO13, GND -> GND, 3.3V -> 3.3V
  20. // mapping suggestion for ESP32, e.g. LOLIN32, see .../variants/.../pins_arduino.h for your board
  21. // NOTE: there are variants with different pins for SPI ! CHECK SPI PINS OF YOUR BOARD
  22. // BUSY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V
  23. // new mapping suggestion for STM32F1, e.g. STM32F103C8T6 "BluePill"
  24. // BUSY -> A1, RST -> A2, DC -> A3, CS-> A4, CLK -> A5, DIN -> A7
  25. // mapping suggestion for AVR, UNO, NANO etc.
  26. // BUSY -> 7, RST -> 9, DC -> 8, CS-> 10, CLK -> 13, DIN -> 11
  27. #include <GxEPD2_BW.h>
  28. #include <GxEPD2_3C.h>
  29. #include <Fonts/FreeMonoBold9pt7b.h>
  30. // create display class instances for each display, each instance with different CS line, each instance with RST disabled,
  31. // (or use separate RST pins for each display),
  32. // each instance with different BUSY line, or BUSY lines or-ed to one pin
  33. // disable reset line to disable cross resets by multiple instances
  34. #if defined (ESP8266)
  35. #define RST_PIN 0 // D3(0)
  36. #define CS_1 SS // CS = D8(15)
  37. #define CS_2 16 // CS = D0(16)
  38. #define CS_3 5 // CS = D1(5)
  39. // BUSY lines can be or-ed with diodes and pulldown register for displays with BUSY active HIGH
  40. #define BUSY_H_x 4 // BUSY = D2(4)
  41. // BUSY lines can be or-ed with diodes and pullup resistor for displays with BUSY active LOW
  42. //#define BUSY_L_x 4 // BUSY = D2(4)
  43. // select one and adapt to your mapping, can use full buffer size (full HEIGHT)
  44. GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display1(GxEPD2_154(/*CS=*/ CS_1, /*DC=D3*/ 0, /*RST=*/ -1, /*BUSY=*/ BUSY_H_x));
  45. GxEPD2_BW<GxEPD2_213, GxEPD2_213::HEIGHT> display2(GxEPD2_213(/*CS=*/ CS_2, /*DC=D3*/ 0, /*RST=*/ -1, /*BUSY=*/ BUSY_H_x));
  46. GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display3(GxEPD2_290(/*CS=*/ CS_3, /*DC=D3*/ 0, /*RST=*/ -1, /*BUSY=*/ BUSY_H_x));
  47. //GxEPD2_BW<GxEPD2_270, GxEPD2_270::HEIGHT> display(GxEPD2_270(/*CS=*/ CS_x, /*DC=D3*/ 0, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  48. //GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=*/ CS_x, /*DC=D3*/ 0, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  49. // can use only half buffer size
  50. //GxEPD2_BW < GxEPD2_583, GxEPD2_583::HEIGHT / 2 > display(GxEPD2_583(/*CS=*/ CS_x, /*DC=D3*/ 0, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  51. //GxEPD2_BW < GxEPD2_750, GxEPD2_750::HEIGHT / 2 > display(GxEPD2_750(/*CS=*/ CS_x, /*DC=D3*/ 0, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  52. // 3-color e-papers
  53. //GxEPD2_3C<GxEPD2_154c, GxEPD2_154c::HEIGHT> display(GxEPD2_154c(/*CS=*/ CS_x, /*DC=D3*/ 0, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  54. //GxEPD2_3C<GxEPD2_213c, GxEPD2_213c::HEIGHT> display(GxEPD2_213c(/*CS=*/ CS_x, /*DC=D3*/ 0, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  55. //GxEPD2_3C<GxEPD2_290c, GxEPD2_290c::HEIGHT> display(GxEPD2_290c(/*CS=*/ CS_x, /*DC=D3*/ 0, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  56. //GxEPD2_3C<GxEPD2_270c, GxEPD2_270c::HEIGHT> display(GxEPD2_270c(/*CS=*/ CS_x, /*DC=D3*/ 0, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  57. // can use only half buffer size
  58. //GxEPD2_3C<GxEPD2_420c, GxEPD2_420c::HEIGHT / 2> display(GxEPD2_420c(/*CS=*/ CS_x, /*DC=D3*/ 0, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  59. // can use only quarter buffer size
  60. //GxEPD2_3C<GxEPD2_583c, GxEPD2_583c::HEIGHT / 4> display(GxEPD2_583c(/*CS=*/ CS_x, /*DC=D3*/ 0, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  61. //GxEPD2_3C<GxEPD2_750c, GxEPD2_750c::HEIGHT / 4> display3(GxEPD2_750c(/*CS=*/ CS_x, /*DC=D3*/ 0, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  62. #endif
  63. #if defined(ESP32)
  64. #define RST_PIN 16
  65. #define CS_1 SS // CS = 5(SS)
  66. #define CS_2 0 // CS = 0
  67. #define CS_3 2 // CS = 2
  68. #define CS_4 13 // CS = 13
  69. // BUSY lines can be or-ed with diodes and pulldown register for displays with BUSY active HIGH
  70. #define BUSY_H_x 4 // BUSY = 4
  71. // BUSY lines can be or-ed with diodes and pullup resistor for displays with BUSY active LOW
  72. #define BUSY_L_x 15 // BUSY = 15
  73. // select one and adapt to your mapping, can use full buffer size (full HEIGHT)
  74. GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display1(GxEPD2_154(/*CS=*/ CS_1, /*DC=*/ 17, /*RST=*/ -1, /*BUSY=*/ BUSY_H_x));
  75. GxEPD2_BW<GxEPD2_213, GxEPD2_213::HEIGHT> display2(GxEPD2_213(/*CS=*/ CS_2, /*DC=*/ 17, /*RST=*/ -1, /*BUSY=*/ BUSY_H_x));
  76. GxEPD2_BW<GxEPD2_290, GxEPD2_290::HEIGHT> display3(GxEPD2_290(/*CS=*/ CS_3, /*DC=*/ 17, /*RST=*/ -1, /*BUSY=*/ BUSY_H_x));
  77. //GxEPD2_BW<GxEPD2_270, GxEPD2_270::HEIGHT> display(GxEPD2_270(/*CS=*/ CS_x, /*DC=*/ 17, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  78. //GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display4(GxEPD2_420(/*CS=*/ CS_4, /*DC=*/ 17, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  79. //GxEPD2_BW<GxEPD2_750, GxEPD2_750::HEIGHT> display(GxEPD2_750(/*CS=*/ CS_x, /*DC=*/ 17, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  80. // 3-color e-papers
  81. //GxEPD2_3C<GxEPD2_154c, GxEPD2_154c::HEIGHT> display(GxEPD2_154c(/*CS=*/ CS_x, /*DC=*/ 17, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  82. //GxEPD2_3C<GxEPD2_213c, GxEPD2_213c::HEIGHT> display(GxEPD2_213c(/*CS=*/ CS_x, /*DC=*/ 17, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  83. //GxEPD2_3C<GxEPD2_290c, GxEPD2_290c::HEIGHT> display(GxEPD2_290c(/*CS=*/ CS_x, /*DC=*/ 17, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  84. //GxEPD2_3C<GxEPD2_270c, GxEPD2_270c::HEIGHT> display(GxEPD2_270c(/*CS=*/ CS_x, /*DC=*/ 17, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  85. //GxEPD2_3C<GxEPD2_420c, GxEPD2_420c::HEIGHT> display(GxEPD2_420c(/*CS=*/ CS_x, /*DC=*/ 17, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  86. GxEPD2_3C<GxEPD2_750c, GxEPD2_750c::HEIGHT> display4(GxEPD2_750c(/*CS=*/ CS_4, /*DC=*/ 17, /*RST=*/ -1, /*BUSY=*/ BUSY_L_x));
  87. #endif
  88. // comment out unused bitmaps to reduce code space used
  89. #include "bitmaps/Bitmaps200x200.h" // 1.54" b/w
  90. #include "bitmaps/Bitmaps128x250.h" // 2.13" b/w
  91. #include "bitmaps/Bitmaps128x296.h" // 2.9" b/w
  92. #include "bitmaps/Bitmaps176x264.h" // 2.7" b/w
  93. #include "bitmaps/Bitmaps400x300.h" // 4.2" b/w
  94. #include "bitmaps/Bitmaps640x384.h" // 7.5" b/w
  95. // 3-color
  96. #include "bitmaps/Bitmaps3c200x200.h" // 1.54" b/w/r
  97. #include "bitmaps/Bitmaps3c104x212.h" // 2.13" b/w/r
  98. #include "bitmaps/Bitmaps3c128x296.h" // 2.9" b/w/r
  99. #include "bitmaps/Bitmaps3c176x264.h" // 2.7" b/w/r
  100. #include "bitmaps/Bitmaps3c400x300.h" // 4.2" b/w/r
  101. // Ok, I will learn how to use nested templates in my next life, maybe
  102. // Ok, this works at least, maybe I learned enough for a start
  103. // the compiler needs separate declarations for template functions
  104. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  105. void helloWorld(T<GxEPD2_Type, page_height>& display);
  106. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  107. void helloFullScreenPartialMode(T<GxEPD2_Type, page_height>& display);
  108. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  109. void helloArduino(T<GxEPD2_Type, page_height>& display);
  110. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  111. void helloEpaper(T<GxEPD2_Type, page_height>& display);
  112. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  113. void showBox(T<GxEPD2_Type, page_height>& display, uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool partial);
  114. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  115. void drawCornerTest(T<GxEPD2_Type, page_height>& display);
  116. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  117. void showFont(T<GxEPD2_Type, page_height>& display, const char name[], const GFXfont* f);
  118. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  119. void drawBitmaps(T<GxEPD2_Type, page_height>& display);
  120. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  121. void showPartialUpdate(T<GxEPD2_Type, page_height>& display);
  122. void setup()
  123. {
  124. Serial.begin(115200);
  125. Serial.println();
  126. Serial.println("setup");
  127. // one common reset for all displays
  128. digitalWrite(RST_PIN, HIGH);
  129. pinMode(RST_PIN, OUTPUT);
  130. delay(20);
  131. digitalWrite(RST_PIN, LOW);
  132. delay(20);
  133. digitalWrite(RST_PIN, HIGH);
  134. delay(200);
  135. display1.init(115200); // enable diagnostic output on Serial
  136. display2.init(115200); // enable diagnostic output on Serial
  137. display3.init(115200); // enable diagnostic output on Serial
  138. #if defined(ESP32)
  139. display4.init(115200); // enable diagnostic output on Serial
  140. #endif
  141. // first update should be full refresh
  142. helloWorld(display1);
  143. helloWorld(display2);
  144. helloWorld(display3);
  145. #if defined(ESP32)
  146. helloWorld(display4);
  147. #endif
  148. delay(1000);
  149. // partial refresh mode can be used to full screen,
  150. // effective if display panel hasFastPartialUpdate
  151. helloFullScreenPartialMode(display1);
  152. helloFullScreenPartialMode(display2);
  153. helloFullScreenPartialMode(display3);
  154. #if defined(ESP32)
  155. helloFullScreenPartialMode(display4);
  156. #endif
  157. delay(1000);
  158. helloArduino(display1);
  159. helloArduino(display2);
  160. helloArduino(display3);
  161. #if defined(ESP32)
  162. helloArduino(display4);
  163. #endif
  164. delay(1000);
  165. helloEpaper(display1);
  166. helloEpaper(display2);
  167. helloEpaper(display3);
  168. #if defined(ESP32)
  169. helloEpaper(display4);
  170. #endif
  171. delay(1000);
  172. showFont(display1, "FreeMonoBold9pt7b", &FreeMonoBold9pt7b);
  173. showFont(display2, "FreeMonoBold9pt7b", &FreeMonoBold9pt7b);
  174. showFont(display3, "FreeMonoBold9pt7b", &FreeMonoBold9pt7b);
  175. #if defined(ESP32)
  176. showFont(display4, "FreeMonoBold9pt7b", &FreeMonoBold9pt7b);
  177. #endif
  178. delay(1000);
  179. drawBitmaps(display1);
  180. drawBitmaps(display2);
  181. drawBitmaps(display3);
  182. #if defined(ESP32)
  183. drawBitmaps(display4);
  184. #endif
  185. // if (display1.epd2.hasPartialUpdate)
  186. // {
  187. // showPartialUpdate(display1);
  188. // delay(1000);
  189. // } // else // on GDEW0154Z04 only full update available, doesn't look nice
  190. //drawCornerTest(display1);
  191. //showBox(display1, 16, 16, 48, 32, false);
  192. //showBox(display1, 16, 56, 48, 32, true);
  193. display1.powerOff();
  194. display2.powerOff();
  195. display3.powerOff();
  196. Serial.println("setup done");
  197. }
  198. void loop()
  199. {
  200. }
  201. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  202. void helloWorld(T<GxEPD2_Type, page_height>& display)
  203. {
  204. //Serial.println("helloWorld");
  205. display.setRotation(1);
  206. display.setFont(&FreeMonoBold9pt7b);
  207. display.setTextColor(GxEPD_BLACK);
  208. uint16_t x = (display.width() - 160) / 2;
  209. uint16_t y = display.height() / 2;
  210. display.setFullWindow();
  211. display.firstPage();
  212. do
  213. {
  214. display.fillScreen(GxEPD_WHITE);
  215. display.setCursor(x, y);
  216. display.println("Hello World!");
  217. }
  218. while (display.nextPage());
  219. //Serial.println("helloWorld done");
  220. }
  221. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  222. void helloFullScreenPartialMode(T<GxEPD2_Type, page_height>& display)
  223. {
  224. //Serial.println("helloFullScreenPartialMode");
  225. display.setPartialWindow(0, 0, display.width(), display.height());
  226. display.setRotation(1);
  227. display.setFont(&FreeMonoBold9pt7b);
  228. display.setTextColor(GxEPD_BLACK);
  229. display.firstPage();
  230. do
  231. {
  232. uint16_t x = (display.width() - 160) / 2;
  233. uint16_t y = display.height() / 2;
  234. display.fillScreen(GxEPD_WHITE);
  235. display.setCursor(x, y);
  236. display.println("Hello World!");
  237. y = display.height() / 4;
  238. display.setCursor(x, y);
  239. display.println("full screen");
  240. y = display.height() * 3 / 4;
  241. if (display.width() <= 200) x = 0;
  242. display.setCursor(x, y);
  243. if (display.epd2.hasFastPartialUpdate)
  244. {
  245. display.println("fast partial mode");
  246. }
  247. else if (display.epd2.hasPartialUpdate)
  248. {
  249. display.println("slow partial mode");
  250. }
  251. else
  252. {
  253. display.println("no partial mode");
  254. }
  255. }
  256. while (display.nextPage());
  257. //Serial.println("helloFullScreenPartialMode done");
  258. }
  259. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  260. void helloArduino(T<GxEPD2_Type, page_height>& display)
  261. {
  262. //Serial.println("helloArduino");
  263. display.setRotation(1);
  264. display.setFont(&FreeMonoBold9pt7b);
  265. display.setTextColor(display.epd2.hasColor ? GxEPD_RED : GxEPD_BLACK);
  266. uint16_t x = (display.width() - 160) / 2;
  267. uint16_t y = display.height() / 4;
  268. display.setPartialWindow(0, y - 14, display.width(), 20);
  269. display.firstPage();
  270. do
  271. {
  272. display.fillScreen(GxEPD_WHITE);
  273. display.setCursor(x, y);
  274. display.println("Hello Arduino!");
  275. }
  276. while (display.nextPage());
  277. delay(1000);
  278. //Serial.println("helloArduino done");
  279. }
  280. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  281. void helloEpaper(T<GxEPD2_Type, page_height>& display)
  282. {
  283. //Serial.println("helloEpaper");
  284. display.setRotation(1);
  285. display.setFont(&FreeMonoBold9pt7b);
  286. display.setTextColor(display.epd2.hasColor ? GxEPD_RED : GxEPD_BLACK);
  287. uint16_t x = (display.width() - 160) / 2;
  288. uint16_t y = display.height() * 3 / 4;
  289. display.setPartialWindow(0, y - 14, display.width(), 20);
  290. display.firstPage();
  291. do
  292. {
  293. display.fillScreen(GxEPD_WHITE);
  294. display.setCursor(x, y);
  295. display.println("Hello E-Paper!");
  296. }
  297. while (display.nextPage());
  298. //Serial.println("helloEpaper done");
  299. }
  300. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  301. void showBox(T<GxEPD2_Type, page_height>& display, uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool partial)
  302. {
  303. //Serial.println("showBox");
  304. display.setRotation(1);
  305. if (partial)
  306. {
  307. display.setPartialWindow(x, y, w, h);
  308. }
  309. else
  310. {
  311. display.setFullWindow();
  312. }
  313. display.firstPage();
  314. do
  315. {
  316. display.fillScreen(GxEPD_WHITE);
  317. display.fillRect(x, y, w, h, GxEPD_BLACK);
  318. }
  319. while (display.nextPage());
  320. //Serial.println("showBox done");
  321. }
  322. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  323. void drawCornerTest(T<GxEPD2_Type, page_height>& display)
  324. {
  325. display.setFullWindow();
  326. display.setFont(&FreeMonoBold9pt7b);
  327. display.setTextColor(GxEPD_BLACK);
  328. for (uint16_t r = 0; r <= 4; r++)
  329. {
  330. display.setRotation(r);
  331. display.firstPage();
  332. do
  333. {
  334. display.fillScreen(GxEPD_WHITE);
  335. display.fillRect(0, 0, 8, 8, GxEPD_BLACK);
  336. display.fillRect(display.width() - 18, 0, 16, 16, GxEPD_BLACK);
  337. display.fillRect(display.width() - 25, display.height() - 25, 24, 24, GxEPD_BLACK);
  338. display.fillRect(0, display.height() - 33, 32, 32, GxEPD_BLACK);
  339. display.setCursor(display.width() / 2, display.height() / 2);
  340. display.print(display.getRotation());
  341. }
  342. while (display.nextPage());
  343. delay(2000);
  344. }
  345. }
  346. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  347. void showFont(T<GxEPD2_Type, page_height>& display, const char name[], const GFXfont* f)
  348. {
  349. display.setFullWindow();
  350. display.setRotation(0);
  351. display.setTextColor(GxEPD_BLACK);
  352. display.firstPage();
  353. do
  354. {
  355. drawFont(display, name, f);
  356. }
  357. while (display.nextPage());
  358. }
  359. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  360. void drawFont(T<GxEPD2_Type, page_height>& display, const char name[], const GFXfont* f);
  361. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  362. void drawFont(T<GxEPD2_Type, page_height>& display, const char name[], const GFXfont* f)
  363. {
  364. //display.setRotation(0);
  365. display.fillScreen(GxEPD_WHITE);
  366. display.setTextColor(GxEPD_BLACK);
  367. display.setFont(f);
  368. display.setCursor(0, 0);
  369. display.println();
  370. display.println(name);
  371. display.println(" !\"#$%&'()*+,-./");
  372. display.println("0123456789:;<=>?");
  373. display.println("@ABCDEFGHIJKLMNO");
  374. display.println("PQRSTUVWXYZ[\\]^_");
  375. if (display.epd2.hasColor)
  376. {
  377. display.setTextColor(GxEPD_RED);
  378. }
  379. display.println("`abcdefghijklmno");
  380. display.println("pqrstuvwxyz{|}~ ");
  381. }
  382. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  383. void showPartialUpdate(T<GxEPD2_Type, page_height>& display)
  384. {
  385. // some useful background
  386. helloWorld(display);
  387. // use asymmetric values for test
  388. uint16_t box_x = 10;
  389. uint16_t box_y = 15;
  390. uint16_t box_w = 70;
  391. uint16_t box_h = 20;
  392. uint16_t cursor_y = box_y + box_h - 6;
  393. float value = 13.95;
  394. uint16_t incr = display.epd2.hasFastPartialUpdate ? 1 : 3;
  395. display.setFont(&FreeMonoBold9pt7b);
  396. display.setTextColor(GxEPD_BLACK);
  397. // show where the update box is
  398. for (uint16_t r = 0; r < 4; r++)
  399. {
  400. display.setRotation(r);
  401. display.setPartialWindow(box_x, box_y, box_w, box_h);
  402. display.firstPage();
  403. do
  404. {
  405. display.fillRect(box_x, box_y, box_w, box_h, GxEPD_BLACK);
  406. //display.fillScreen(GxEPD_BLACK);
  407. }
  408. while (display.nextPage());
  409. delay(2000);
  410. display.firstPage();
  411. do
  412. {
  413. display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
  414. }
  415. while (display.nextPage());
  416. delay(1000);
  417. }
  418. //return;
  419. // show updates in the update box
  420. for (uint16_t r = 0; r < 4; r++)
  421. {
  422. display.setRotation(r);
  423. display.setPartialWindow(box_x, box_y, box_w, box_h);
  424. for (uint16_t i = 1; i <= 10; i += incr)
  425. {
  426. display.firstPage();
  427. do
  428. {
  429. display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
  430. display.setCursor(box_x, cursor_y);
  431. display.print(value * i, 2);
  432. }
  433. while (display.nextPage());
  434. delay(500);
  435. }
  436. delay(1000);
  437. display.firstPage();
  438. do
  439. {
  440. display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
  441. }
  442. while (display.nextPage());
  443. delay(1000);
  444. }
  445. }
  446. #ifdef _GxBitmaps200x200_H_
  447. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  448. void drawBitmaps200x200(T<GxEPD2_Type, page_height>& display);
  449. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  450. void drawBitmaps200x200(T<GxEPD2_Type, page_height>& display)
  451. {
  452. #if defined(__AVR)
  453. const unsigned char* bitmaps[] =
  454. {
  455. logo200x200, first200x200 //, second200x200, third200x200, fourth200x200, fifth200x200, sixth200x200, senventh200x200, eighth200x200
  456. };
  457. #elif defined(_BOARD_GENERIC_STM32F103C_H_)
  458. const unsigned char* bitmaps[] =
  459. {
  460. logo200x200, first200x200, second200x200, third200x200, fourth200x200, fifth200x200 //, sixth200x200, senventh200x200, eighth200x200
  461. };
  462. #else
  463. const unsigned char* bitmaps[] =
  464. {
  465. logo200x200, first200x200, second200x200, third200x200, fourth200x200, fifth200x200, sixth200x200, senventh200x200, eighth200x200
  466. };
  467. #endif
  468. if (display.epd2.panel == GxEPD2::GDEP015OC1)
  469. {
  470. bool m = display.mirror(true);
  471. for (uint16_t i = 0; i < sizeof(bitmaps) / sizeof(char*); i++)
  472. {
  473. display.firstPage();
  474. do
  475. {
  476. display.fillScreen(GxEPD_WHITE);
  477. display.drawInvertedBitmap(0, 0, bitmaps[i], display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_BLACK);
  478. }
  479. while (display.nextPage());
  480. delay(2000);
  481. }
  482. display.mirror(m);
  483. }
  484. //else
  485. {
  486. bool mirror_y = (display.epd2.panel != GxEPD2::GDE0213B1);
  487. display.clearScreen(); // use default for white
  488. int16_t x = (int16_t(display.epd2.WIDTH) - 200) / 2;
  489. int16_t y = (int16_t(display.epd2.HEIGHT) - 200) / 2;
  490. for (uint16_t i = 0; i < sizeof(bitmaps) / sizeof(char*); i++)
  491. {
  492. display.drawImage(bitmaps[i], x, y, 200, 200, false, mirror_y, true);
  493. delay(2000);
  494. }
  495. }
  496. bool mirror_y = (display.epd2.panel != GxEPD2::GDE0213B1);
  497. for (uint16_t i = 0; i < sizeof(bitmaps) / sizeof(char*); i++)
  498. {
  499. int16_t x = -60;
  500. int16_t y = -60;
  501. for (uint16_t j = 0; j < 10; j++)
  502. {
  503. display.writeScreenBuffer(); // use default for white
  504. display.writeImage(bitmaps[i], x, y, 200, 200, false, mirror_y, true);
  505. display.refresh(true);
  506. delay(2000);
  507. x += 40;
  508. y += 40;
  509. if ((x >= int16_t(display.epd2.WIDTH)) || (y >= int16_t(display.epd2.HEIGHT))) break;
  510. }
  511. if (!display.epd2.hasFastPartialUpdate) break; // comment out for full show
  512. break; // comment out for full show
  513. }
  514. display.writeScreenBuffer(); // use default for white
  515. display.writeImage(bitmaps[0], int16_t(0), 0, 200, 200, false, mirror_y, true);
  516. display.writeImage(bitmaps[0], int16_t(int16_t(display.epd2.WIDTH) - 200), int16_t(display.epd2.HEIGHT) - 200, 200, 200, false, mirror_y, true);
  517. display.refresh(true);
  518. delay(2000);
  519. }
  520. #endif
  521. #ifdef _GxBitmaps128x250_H_
  522. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  523. void drawBitmaps128x250(T<GxEPD2_Type, page_height>& display);
  524. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  525. void drawBitmaps128x250(T<GxEPD2_Type, page_height>& display)
  526. {
  527. #if !defined(__AVR)
  528. const unsigned char* bitmaps[] =
  529. {
  530. Bitmap128x250_1, logo128x250, first128x250, second128x250, third128x250
  531. };
  532. #else
  533. const unsigned char* bitmaps[] =
  534. {
  535. Bitmap128x250_1, logo128x250, first128x250, second128x250, third128x250
  536. };
  537. #endif
  538. if (display.epd2.panel == GxEPD2::GDE0213B1)
  539. {
  540. bool m = display.mirror(true);
  541. for (uint16_t i = 0; i < sizeof(bitmaps) / sizeof(char*); i++)
  542. {
  543. display.firstPage();
  544. do
  545. {
  546. display.fillScreen(GxEPD_WHITE);
  547. display.drawInvertedBitmap(0, 0, bitmaps[i], display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_BLACK);
  548. }
  549. while (display.nextPage());
  550. delay(2000);
  551. }
  552. display.mirror(m);
  553. }
  554. }
  555. #endif
  556. #ifdef _GxBitmaps128x296_H_
  557. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  558. void drawBitmaps128x296(T<GxEPD2_Type, page_height>& display);
  559. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  560. void drawBitmaps128x296(T<GxEPD2_Type, page_height>& display)
  561. {
  562. #if !defined(__AVR)
  563. const unsigned char* bitmaps[] =
  564. {
  565. Bitmap128x296_1, logo128x296, first128x296, second128x296, third128x296
  566. };
  567. #else
  568. const unsigned char* bitmaps[] =
  569. {
  570. Bitmap128x296_1, logo128x296 //, first128x296, second128x296, third128x296
  571. };
  572. #endif
  573. if (display.epd2.panel == GxEPD2::GDEH029A1)
  574. {
  575. bool m = display.mirror(true);
  576. for (uint16_t i = 0; i < sizeof(bitmaps) / sizeof(char*); i++)
  577. {
  578. display.firstPage();
  579. do
  580. {
  581. display.fillScreen(GxEPD_WHITE);
  582. display.drawInvertedBitmap(0, 0, bitmaps[i], display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_BLACK);
  583. }
  584. while (display.nextPage());
  585. delay(2000);
  586. }
  587. display.mirror(m);
  588. }
  589. }
  590. #endif
  591. #ifdef _GxBitmaps176x264_H_
  592. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  593. void drawBitmaps176x264(T<GxEPD2_Type, page_height>& display);
  594. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  595. void drawBitmaps176x264(T<GxEPD2_Type, page_height>& display)
  596. {
  597. const unsigned char* bitmaps[] =
  598. {
  599. Bitmap176x264_1, Bitmap176x264_2
  600. };
  601. if (display.epd2.panel == GxEPD2::GDEW027W3)
  602. {
  603. for (uint16_t i = 0; i < sizeof(bitmaps) / sizeof(char*); i++)
  604. {
  605. display.firstPage();
  606. do
  607. {
  608. display.fillScreen(GxEPD_WHITE);
  609. display.drawInvertedBitmap(0, 0, bitmaps[i], display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_BLACK);
  610. }
  611. while (display.nextPage());
  612. delay(2000);
  613. }
  614. }
  615. }
  616. #endif
  617. #ifdef _GxBitmaps400x300_H_
  618. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  619. void drawBitmaps400x300(T<GxEPD2_Type, page_height>& display);
  620. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  621. void drawBitmaps400x300(T<GxEPD2_Type, page_height>& display)
  622. {
  623. #if !defined(__AVR)
  624. const unsigned char* bitmaps[] =
  625. {
  626. Bitmap400x300_1, Bitmap400x300_2
  627. };
  628. #else
  629. const unsigned char* bitmaps[] = {}; // not enough code space
  630. #endif
  631. if (display.epd2.panel == GxEPD2::GDEW042T2)
  632. {
  633. for (uint16_t i = 0; i < sizeof(bitmaps) / sizeof(char*); i++)
  634. {
  635. display.firstPage();
  636. do
  637. {
  638. display.fillScreen(GxEPD_WHITE);
  639. display.drawInvertedBitmap(0, 0, bitmaps[i], display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_BLACK);
  640. }
  641. while (display.nextPage());
  642. delay(2000);
  643. }
  644. }
  645. }
  646. #endif
  647. #ifdef _GxBitmaps640x384_H_
  648. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  649. void drawBitmaps640x384(T<GxEPD2_Type, page_height>& display);
  650. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  651. void drawBitmaps640x384(T<GxEPD2_Type, page_height>& display)
  652. {
  653. #if !defined(__AVR)
  654. const unsigned char* bitmaps[] =
  655. {
  656. Bitmap640x384_1, Bitmap640x384_2
  657. };
  658. #else
  659. const unsigned char* bitmaps[] = {}; // not enough code space
  660. #endif
  661. if (display.epd2.panel == GxEPD2::GDEW075T8)
  662. {
  663. for (uint16_t i = 0; i < sizeof(bitmaps) / sizeof(char*); i++)
  664. {
  665. display.firstPage();
  666. do
  667. {
  668. display.fillScreen(GxEPD_WHITE);
  669. display.drawInvertedBitmap(0, 0, bitmaps[i], display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_BLACK);
  670. }
  671. while (display.nextPage());
  672. delay(2000);
  673. }
  674. }
  675. }
  676. #endif
  677. struct bitmap_pair
  678. {
  679. const unsigned char* black;
  680. const unsigned char* red;
  681. };
  682. #ifdef _GxBitmaps3c200x200_H_
  683. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  684. void drawBitmaps3c200x200(T<GxEPD2_Type, page_height>& display);
  685. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  686. void drawBitmaps3c200x200(T<GxEPD2_Type, page_height>& display)
  687. {
  688. bitmap_pair bitmap_pairs[] =
  689. {
  690. //{Bitmap3c200x200_black, Bitmap3c200x200_red},
  691. {WS_Bitmap3c200x200_black, WS_Bitmap3c200x200_red}
  692. };
  693. if (display.epd2.panel == GxEPD2::GDEW0154Z04)
  694. {
  695. display.firstPage();
  696. do
  697. {
  698. display.fillScreen(GxEPD_WHITE);
  699. // Bitmap3c200x200_black has 2 bits per pixel
  700. // taken from Adafruit_GFX.cpp, modified
  701. int16_t byteWidth = (display.epd2.WIDTH + 7) / 8; // Bitmap scanline pad = whole byte
  702. uint8_t byte = 0;
  703. for (int16_t j = 0; j < display.epd2.HEIGHT; j++)
  704. {
  705. for (int16_t i = 0; i < display.epd2.WIDTH; i++)
  706. {
  707. if (i & 3) byte <<= 2;
  708. else
  709. {
  710. #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
  711. byte = pgm_read_byte(&Bitmap3c200x200_black[j * byteWidth * 2 + i / 4]);
  712. #else
  713. byte = Bitmap3c200x200_black[j * byteWidth * 2 + i / 4];
  714. #endif
  715. }
  716. if (!(byte & 0x80))
  717. {
  718. display.drawPixel(i, j, GxEPD_BLACK);
  719. }
  720. }
  721. }
  722. display.drawInvertedBitmap(0, 0, Bitmap3c200x200_red, display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_RED);
  723. }
  724. while (display.nextPage());
  725. delay(2000);
  726. for (uint16_t i = 0; i < sizeof(bitmap_pairs) / sizeof(bitmap_pair); i++)
  727. {
  728. display.firstPage();
  729. do
  730. {
  731. display.fillScreen(GxEPD_WHITE);
  732. display.drawInvertedBitmap(0, 0, bitmap_pairs[i].black, display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_BLACK);
  733. display.drawInvertedBitmap(0, 0, bitmap_pairs[i].red, display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_RED);
  734. }
  735. while (display.nextPage());
  736. delay(2000);
  737. }
  738. }
  739. if (display.epd2.hasColor)
  740. {
  741. display.clearScreen(); // use default for white
  742. int16_t x = (int16_t(display.epd2.WIDTH) - 200) / 2;
  743. int16_t y = (int16_t(display.epd2.HEIGHT) - 200) / 2;
  744. for (uint16_t i = 0; i < sizeof(bitmap_pairs) / sizeof(bitmap_pair); i++)
  745. {
  746. display.drawImage(bitmap_pairs[i].black, bitmap_pairs[i].red, x, y, 200, 200, false, false, true);
  747. delay(2000);
  748. }
  749. for (uint16_t i = 0; i < sizeof(bitmap_pairs) / sizeof(bitmap_pair); i++)
  750. {
  751. int16_t x = -60;
  752. int16_t y = -60;
  753. for (uint16_t j = 0; j < 10; j++)
  754. {
  755. display.writeScreenBuffer(); // use default for white
  756. display.writeImage(bitmap_pairs[i].black, bitmap_pairs[i].red, x, y, 200, 200, false, false, true);
  757. display.refresh();
  758. delay(2000);
  759. x += 40;
  760. y += 40;
  761. if ((x >= int16_t(display.epd2.WIDTH)) || (y >= int16_t(display.epd2.HEIGHT))) break;
  762. }
  763. }
  764. display.writeScreenBuffer(); // use default for white
  765. display.writeImage(bitmap_pairs[0].black, bitmap_pairs[0].red, 0, 0, 200, 200, false, false, true);
  766. display.writeImage(bitmap_pairs[0].black, bitmap_pairs[0].red, int16_t(display.epd2.WIDTH) - 200, int16_t(display.epd2.HEIGHT) - 200, 200, 200, false, false, true);
  767. display.refresh();
  768. delay(2000);
  769. }
  770. }
  771. #endif
  772. #ifdef _GxBitmaps3c104x212_H_
  773. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  774. void drawBitmaps3c104x212(T<GxEPD2_Type, page_height>& display);
  775. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  776. void drawBitmaps3c104x212(T<GxEPD2_Type, page_height>& display)
  777. {
  778. #if !defined(__AVR)
  779. bitmap_pair bitmap_pairs[] =
  780. {
  781. {Bitmap3c104x212_1_black, Bitmap3c104x212_1_red},
  782. {Bitmap3c104x212_2_black, Bitmap3c104x212_2_red},
  783. {WS_Bitmap3c104x212_black, WS_Bitmap3c104x212_red}
  784. };
  785. #else
  786. bitmap_pair bitmap_pairs[] =
  787. {
  788. {Bitmap3c104x212_1_black, Bitmap3c104x212_1_red},
  789. //{Bitmap3c104x212_2_black, Bitmap3c104x212_2_red},
  790. {WS_Bitmap3c104x212_black, WS_Bitmap3c104x212_red}
  791. };
  792. #endif
  793. if (display.epd2.panel == GxEPD2::GDEW0213Z16)
  794. {
  795. for (uint16_t i = 0; i < sizeof(bitmap_pairs) / sizeof(bitmap_pair); i++)
  796. {
  797. display.firstPage();
  798. do
  799. {
  800. display.fillScreen(GxEPD_WHITE);
  801. display.drawInvertedBitmap(0, 0, bitmap_pairs[i].black, display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_BLACK);
  802. if (bitmap_pairs[i].red == WS_Bitmap3c104x212_red)
  803. {
  804. display.drawInvertedBitmap(0, 0, bitmap_pairs[i].red, display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_RED);
  805. }
  806. else display.drawBitmap(0, 0, bitmap_pairs[i].red, display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_RED);
  807. }
  808. while (display.nextPage());
  809. delay(2000);
  810. }
  811. }
  812. }
  813. #endif
  814. #ifdef _GxBitmaps3c128x296_H_
  815. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  816. void drawBitmaps3c128x296(T<GxEPD2_Type, page_height>& display);
  817. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  818. void drawBitmaps3c128x296(T<GxEPD2_Type, page_height>& display)
  819. {
  820. #if !defined(__AVR)
  821. bitmap_pair bitmap_pairs[] =
  822. {
  823. {Bitmap3c128x296_1_black, Bitmap3c128x296_1_red},
  824. {Bitmap3c128x296_2_black, Bitmap3c128x296_2_red},
  825. {WS_Bitmap3c128x296_black, WS_Bitmap3c128x296_red}
  826. };
  827. #else
  828. bitmap_pair bitmap_pairs[] =
  829. {
  830. //{Bitmap3c128x296_1_black, Bitmap3c128x296_1_red},
  831. //{Bitmap3c128x296_2_black, Bitmap3c128x296_2_red},
  832. {WS_Bitmap3c128x296_black, WS_Bitmap3c128x296_red}
  833. };
  834. #endif
  835. if (display.epd2.panel == GxEPD2::GDEW029Z10)
  836. {
  837. for (uint16_t i = 0; i < sizeof(bitmap_pairs) / sizeof(bitmap_pair); i++)
  838. {
  839. display.firstPage();
  840. do
  841. {
  842. display.fillScreen(GxEPD_WHITE);
  843. display.drawInvertedBitmap(0, 0, bitmap_pairs[i].black, display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_BLACK);
  844. if (bitmap_pairs[i].red == WS_Bitmap3c128x296_red)
  845. {
  846. display.drawInvertedBitmap(0, 0, bitmap_pairs[i].red, display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_RED);
  847. }
  848. else display.drawBitmap(0, 0, bitmap_pairs[i].red, display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_RED);
  849. }
  850. while (display.nextPage());
  851. delay(2000);
  852. }
  853. }
  854. }
  855. #endif
  856. #ifdef _GxBitmaps3c176x264_H_
  857. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  858. void drawBitmaps3c176x264(T<GxEPD2_Type, page_height>& display);
  859. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  860. void drawBitmaps3c176x264(T<GxEPD2_Type, page_height>& display)
  861. {
  862. bitmap_pair bitmap_pairs[] =
  863. {
  864. {Bitmap3c176x264_black, Bitmap3c176x264_red}
  865. };
  866. if (display.epd2.panel == GxEPD2::GDEW027C44)
  867. {
  868. for (uint16_t i = 0; i < sizeof(bitmap_pairs) / sizeof(bitmap_pair); i++)
  869. {
  870. display.firstPage();
  871. do
  872. {
  873. display.fillScreen(GxEPD_WHITE);
  874. display.drawBitmap(0, 0, bitmap_pairs[i].black, display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_BLACK);
  875. display.drawBitmap(0, 0, bitmap_pairs[i].red, display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_RED);
  876. }
  877. while (display.nextPage());
  878. delay(2000);
  879. }
  880. }
  881. }
  882. #endif
  883. #ifdef _GxBitmaps3c400x300_H_
  884. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  885. void drawBitmaps3c400x300(T<GxEPD2_Type, page_height>& display);
  886. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  887. void drawBitmaps3c400x300(T<GxEPD2_Type, page_height>& display)
  888. {
  889. #if !defined(__AVR)
  890. bitmap_pair bitmap_pairs[] =
  891. {
  892. {Bitmap3c400x300_1_black, Bitmap3c400x300_1_red},
  893. {Bitmap3c400x300_2_black, Bitmap3c400x300_2_red},
  894. {WS_Bitmap3c400x300_black, WS_Bitmap3c400x300_red}
  895. };
  896. #else
  897. bitmap_pair bitmap_pairs[] = {}; // not enough code space
  898. #endif
  899. if (display.epd2.panel == GxEPD2::GDEW042Z15)
  900. {
  901. for (uint16_t i = 0; i < sizeof(bitmap_pairs) / sizeof(bitmap_pair); i++)
  902. {
  903. display.firstPage();
  904. do
  905. {
  906. display.fillScreen(GxEPD_WHITE);
  907. display.drawInvertedBitmap(0, 0, bitmap_pairs[i].black, display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_BLACK);
  908. display.drawInvertedBitmap(0, 0, bitmap_pairs[i].red, display.epd2.WIDTH, display.epd2.HEIGHT, GxEPD_RED);
  909. }
  910. while (display.nextPage());
  911. delay(2000);
  912. }
  913. }
  914. }
  915. #endif
  916. template<typename GxEPD2_Type, const uint16_t page_height, template<typename, const uint16_t> class T>
  917. void drawBitmaps(T<GxEPD2_Type, page_height>& display)
  918. {
  919. display.setFullWindow();
  920. display.setRotation(0);
  921. #ifdef _GxBitmaps128x250_H_
  922. drawBitmaps128x250(display);
  923. #endif
  924. #ifdef _GxBitmaps128x296_H_
  925. drawBitmaps128x296(display);
  926. #endif
  927. #ifdef _GxBitmaps176x264_H_
  928. drawBitmaps176x264(display);
  929. #endif
  930. #ifdef _GxBitmaps400x300_H_
  931. drawBitmaps400x300(display);
  932. #endif
  933. #ifdef _GxBitmaps640x384_H_
  934. drawBitmaps640x384(display);
  935. #endif
  936. // 3-color
  937. #ifdef _GxBitmaps3c104x212_H_
  938. drawBitmaps3c104x212(display);
  939. #endif
  940. #ifdef _GxBitmaps3c128x296_H_
  941. drawBitmaps3c128x296(display);
  942. #endif
  943. #ifdef _GxBitmaps3c176x264_H_
  944. drawBitmaps3c176x264(display);
  945. #endif
  946. #ifdef _GxBitmaps3c400x300_H_
  947. drawBitmaps3c400x300(display);
  948. #endif
  949. // show these after the specific bitmaps
  950. #ifdef _GxBitmaps200x200_H_
  951. drawBitmaps200x200(display);
  952. #endif
  953. // 3-color
  954. #ifdef _GxBitmaps3c200x200_H_
  955. drawBitmaps3c200x200(display);
  956. #endif
  957. }