GxEPD2_GFX_Example.ino 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. // Display Library example for SPI e-paper panels from Dalian Good Display and boards from Waveshare.
  2. // Requires HW SPI and Adafruit_GFX. Caution: the e-paper panels require 3.3V supply AND data lines!
  3. //
  4. // Display Library based on Demo Example from Good Display: https://www.good-display.com/companyfile/32/
  5. //
  6. // Author: Jean-Marc Zingg
  7. //
  8. // Version: see library.properties
  9. //
  10. // Library: https://github.com/ZinggJM/GxEPD2
  11. //
  12. // Purpose: show uses of GxEPD2_GFX base class for references to a display instance
  13. // Supporting Arduino Forum Topics (closed, read only):
  14. // Good Display ePaper for Arduino: https://forum.arduino.cc/t/good-display-epaper-for-arduino/419657
  15. // Waveshare e-paper displays with SPI: https://forum.arduino.cc/t/waveshare-e-paper-displays-with-spi/467865
  16. //
  17. // Add new topics in https://forum.arduino.cc/c/using-arduino/displays/23 for new questions and issues
  18. // see GxEPD2_wiring_examples.h for wiring suggestions and examples
  19. // base class GxEPD2_GFX can be used to pass references or pointers to the display instance as parameter, uses ~1.2k more code
  20. // enable GxEPD2_GFX base class
  21. #define ENABLE_GxEPD2_GFX 1
  22. // uncomment next line to use class GFX of library GFX_Root instead of Adafruit_GFX
  23. //#include <GFX.h>
  24. // Note: if you use this with ENABLE_GxEPD2_GFX 1:
  25. // uncomment it in GxEPD2_GFX.h too, or add #include <GFX.h> before any #include <GxEPD2_GFX.h>
  26. // !!!! ============================================================================================ !!!!
  27. #include <GxEPD2_BW.h>
  28. #include <GxEPD2_3C.h>
  29. #include <GxEPD2_4C.h>
  30. #include <GxEPD2_7C.h>
  31. #include <Fonts/FreeMonoBold9pt7b.h>
  32. #include "BitmapDisplay.h"
  33. #include "TextDisplay.h"
  34. // select the display constructor line in one of the following files (old style):
  35. #include "GxEPD2_display_selection.h"
  36. #include "GxEPD2_display_selection_added.h"
  37. //#include "GxEPD2_display_selection_more.h" // private
  38. // or select the display class and display driver class in the following file (new style):
  39. #include "GxEPD2_display_selection_new_style.h"
  40. // for handling alternative SPI pins (ESP32, RP2040) see example GxEPD2_Example.ino
  41. BitmapDisplay bitmaps(display);
  42. void setup()
  43. {
  44. Serial.begin(115200);
  45. Serial.println();
  46. Serial.println("setup");
  47. delay(100);
  48. //display.init(115200); // default 10ms reset pulse, e.g. for bare panels with DESPI-C02
  49. display.init(115200, true, 2, false); // USE THIS for Waveshare boards with "clever" reset circuit, 2ms reset pulse
  50. // first update should be full refresh
  51. helloWorld(display);
  52. delay(1000);
  53. // partial refresh mode can be used to full screen,
  54. // effective if display panel hasFastPartialUpdate
  55. helloFullScreenPartialMode(display);
  56. delay(1000);
  57. helloArduino(display);
  58. delay(1000);
  59. helloEpaper(display);
  60. delay(1000);
  61. //helloValue(display, 123.9, 1);
  62. //delay(1000);
  63. showFont(display, "FreeMonoBold9pt7b", &FreeMonoBold9pt7b);
  64. delay(1000);
  65. //BitmapDisplay(display).drawBitmaps();
  66. bitmaps.drawBitmaps();
  67. //return;
  68. if (display.epd2.hasPartialUpdate)
  69. {
  70. showPartialUpdate();
  71. delay(1000);
  72. } // else // on GDEW0154Z04 only full update available, doesn't look nice
  73. //drawCornerTest();
  74. //showBox(16, 16, 48, 32, false);
  75. //showBox(16, 56, 48, 32, true);
  76. display.powerOff();
  77. deepSleepTest();
  78. Serial.println("setup done");
  79. }
  80. void loop()
  81. {
  82. }
  83. void deepSleepTest()
  84. {
  85. //Serial.println("deepSleepTest");
  86. const char hibernating[] = "hibernating ...";
  87. const char wokeup[] = "woke up";
  88. const char from[] = "from deep sleep";
  89. const char again[] = "again";
  90. display.setRotation(1);
  91. display.setFont(&FreeMonoBold9pt7b);
  92. display.setTextColor(GxEPD_BLACK);
  93. int16_t tbx, tby; uint16_t tbw, tbh;
  94. // center text
  95. display.getTextBounds(hibernating, 0, 0, &tbx, &tby, &tbw, &tbh);
  96. uint16_t x = ((display.width() - tbw) / 2) - tbx;
  97. uint16_t y = ((display.height() - tbh) / 2) - tby;
  98. display.setFullWindow();
  99. display.firstPage();
  100. do
  101. {
  102. display.fillScreen(GxEPD_WHITE);
  103. display.setCursor(x, y);
  104. display.print(hibernating);
  105. }
  106. while (display.nextPage());
  107. display.hibernate();
  108. delay(5000);
  109. display.getTextBounds(wokeup, 0, 0, &tbx, &tby, &tbw, &tbh);
  110. uint16_t wx = (display.width() - tbw) / 2;
  111. uint16_t wy = (display.height() / 3) + tbh / 2; // y is base line!
  112. display.getTextBounds(from, 0, 0, &tbx, &tby, &tbw, &tbh);
  113. uint16_t fx = (display.width() - tbw) / 2;
  114. uint16_t fy = (display.height() * 2 / 3) + tbh / 2; // y is base line!
  115. display.firstPage();
  116. do
  117. {
  118. display.fillScreen(GxEPD_WHITE);
  119. display.setCursor(wx, wy);
  120. display.print(wokeup);
  121. display.setCursor(fx, fy);
  122. display.print(from);
  123. }
  124. while (display.nextPage());
  125. delay(5000);
  126. display.getTextBounds(hibernating, 0, 0, &tbx, &tby, &tbw, &tbh);
  127. uint16_t hx = (display.width() - tbw) / 2;
  128. uint16_t hy = (display.height() / 3) + tbh / 2; // y is base line!
  129. display.getTextBounds(again, 0, 0, &tbx, &tby, &tbw, &tbh);
  130. uint16_t ax = (display.width() - tbw) / 2;
  131. uint16_t ay = (display.height() * 2 / 3) + tbh / 2; // y is base line!
  132. display.firstPage();
  133. do
  134. {
  135. display.fillScreen(GxEPD_WHITE);
  136. display.setCursor(hx, hy);
  137. display.print(hibernating);
  138. display.setCursor(ax, ay);
  139. display.print(again);
  140. }
  141. while (display.nextPage());
  142. display.hibernate();
  143. //Serial.println("deepSleepTest done");
  144. }
  145. void showBox(uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool partial)
  146. {
  147. //Serial.println("showBox");
  148. display.setRotation(1);
  149. if (partial)
  150. {
  151. display.setPartialWindow(x, y, w, h);
  152. }
  153. else
  154. {
  155. display.setFullWindow();
  156. }
  157. display.firstPage();
  158. do
  159. {
  160. display.fillScreen(GxEPD_WHITE);
  161. display.fillRect(x, y, w, h, GxEPD_BLACK);
  162. }
  163. while (display.nextPage());
  164. //Serial.println("showBox done");
  165. }
  166. void drawCornerTest()
  167. {
  168. display.setFullWindow();
  169. display.setFont(&FreeMonoBold9pt7b);
  170. display.setTextColor(GxEPD_BLACK);
  171. for (uint16_t r = 0; r <= 4; r++)
  172. {
  173. display.setRotation(r);
  174. display.firstPage();
  175. do
  176. {
  177. display.fillScreen(GxEPD_WHITE);
  178. display.fillRect(0, 0, 8, 8, GxEPD_BLACK);
  179. display.fillRect(display.width() - 18, 0, 16, 16, GxEPD_BLACK);
  180. display.fillRect(display.width() - 25, display.height() - 25, 24, 24, GxEPD_BLACK);
  181. display.fillRect(0, display.height() - 33, 32, 32, GxEPD_BLACK);
  182. display.setCursor(display.width() / 2, display.height() / 2);
  183. display.print(display.getRotation());
  184. }
  185. while (display.nextPage());
  186. delay(2000);
  187. }
  188. }
  189. // note for partial update window and setPartialWindow() method:
  190. // partial update window size and position is on byte boundary in physical x direction
  191. // the size is increased in setPartialWindow() if x or w are not multiple of 8 for even rotation, y or h for odd rotation
  192. // see also comment in GxEPD2_BW.h, GxEPD2_3C.h or GxEPD2_GFX.h for method setPartialWindow()
  193. // showPartialUpdate() purposely uses values that are not multiples of 8 to test this
  194. void showPartialUpdate()
  195. {
  196. // some useful background
  197. helloWorld(display);
  198. // use asymmetric values for test
  199. uint16_t box_x = 10;
  200. uint16_t box_y = 15;
  201. uint16_t box_w = 70;
  202. uint16_t box_h = 20;
  203. uint16_t cursor_y = box_y + box_h - 6;
  204. float value = 13.95;
  205. uint16_t incr = display.epd2.hasFastPartialUpdate ? 1 : 3;
  206. display.setFont(&FreeMonoBold9pt7b);
  207. display.setTextColor(GxEPD_BLACK);
  208. // show where the update box is
  209. for (uint16_t r = 0; r < 4; r++)
  210. {
  211. display.setRotation(r);
  212. display.setPartialWindow(box_x, box_y, box_w, box_h);
  213. display.firstPage();
  214. do
  215. {
  216. display.fillRect(box_x, box_y, box_w, box_h, GxEPD_BLACK);
  217. //display.fillScreen(GxEPD_BLACK);
  218. }
  219. while (display.nextPage());
  220. delay(2000);
  221. display.firstPage();
  222. do
  223. {
  224. display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
  225. }
  226. while (display.nextPage());
  227. delay(1000);
  228. }
  229. //return;
  230. // show updates in the update box
  231. for (uint16_t r = 0; r < 4; r++)
  232. {
  233. display.setRotation(r);
  234. display.setPartialWindow(box_x, box_y, box_w, box_h);
  235. for (uint16_t i = 1; i <= 10; i += incr)
  236. {
  237. display.firstPage();
  238. do
  239. {
  240. display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
  241. display.setCursor(box_x, cursor_y);
  242. display.print(value * i, 2);
  243. }
  244. while (display.nextPage());
  245. delay(500);
  246. }
  247. delay(1000);
  248. display.firstPage();
  249. do
  250. {
  251. display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
  252. }
  253. while (display.nextPage());
  254. delay(1000);
  255. }
  256. }