GxEPD2_GFX_MultiDisplayExample.ino 30 KB

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