GxEPD2_RefreshTests.ino 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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: these e-papers require 3.3V supply AND data lines!
  3. //
  4. // Display Library based on Demo Example from Good Display: http://www.e-paper-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. // see GxEPD2_wiring_examples.h for wiring suggestions and examples
  12. // uncomment next line to use HSPI for EPD (and VSPI for SD), e.g. with Waveshare ESP32 Driver Board
  13. //#define USE_HSPI_FOR_EPD
  14. // uncomment next line to use class GFX of library GFX_Root instead of Adafruit_GFX
  15. //#include <GFX.h>
  16. // Note: if you use this with ENABLE_GxEPD2_GFX 1:
  17. // uncomment it in GxEPD2_GFX.h too, or add #include <GFX.h> before any #include <GxEPD2_GFX.h>
  18. #include <GxEPD2_BW.h>
  19. #include <GxEPD2_3C.h>
  20. // select the display constructor line in one of the following files (old style):
  21. #include "GxEPD2_display_selection.h"
  22. #include "GxEPD2_display_selection_added.h"
  23. //#include "GxEPD2_display_selection_more.h" // private
  24. // or select the display class and display driver class in the following file (new style):
  25. #include "GxEPD2_display_selection_new_style.h"
  26. #include "Open_Sans_ExtraBold_120.h"
  27. //const uint32_t partial_update_period_s = 2;
  28. const uint32_t partial_update_period_s = 60;
  29. const uint32_t full_update_period_s = 1 * 60 * 60;
  30. const uint32_t speed_up_factor = 20; // for simulation
  31. const uint32_t millis_per_second = 1000 / speed_up_factor;
  32. uint32_t start_time;
  33. uint32_t next_time;
  34. uint32_t previous_time;
  35. uint32_t previous_full_update;
  36. uint32_t total_seconds = 0;
  37. uint32_t seconds, minutes, hours, days;
  38. #if defined(ESP32) && defined(USE_HSPI_FOR_EPD)
  39. SPIClass hspi(HSPI);
  40. #endif
  41. void setup()
  42. {
  43. Serial.begin(115200);
  44. Serial.println();
  45. Serial.println("setup");
  46. delay(100);
  47. #if defined(ESP32) && defined(USE_HSPI_FOR_EPD)
  48. hspi.begin(13, 12, 14, 15); // remap hspi for EPD (swap pins)
  49. display.epd2.selectSPI(hspi, SPISettings(4000000, MSBFIRST, SPI_MODE0));
  50. #endif
  51. display.init(115200);
  52. // cleanup
  53. for (int i = 0; i < 1; i++)
  54. {
  55. full_black();
  56. delay(500);
  57. full_white();
  58. delay(500);
  59. }
  60. // stripes test
  61. for (int i = 0; i < 1; i++)
  62. {
  63. horizontal_stripes(8);
  64. delay(1000);
  65. vertical_stripes(8);
  66. delay(3000);
  67. }
  68. full_white();
  69. delay(1000);
  70. // clock simulation test, for limited length
  71. start_time = next_time = previous_time = previous_full_update = millis();
  72. for (int i = 0; i < 50; i++)
  73. {
  74. clock_test();
  75. }
  76. delay(3000);
  77. full_white();
  78. delay(1000);
  79. display.powerOff();
  80. delay(1000);
  81. start_time = next_time = previous_time = previous_full_update = millis();
  82. Serial.println("setup done");
  83. }
  84. void loop()
  85. {
  86. // uncomment for continuous clock simulation test
  87. //clock_test();
  88. }
  89. void full_white()
  90. {
  91. display.setFullWindow();
  92. display.firstPage();
  93. do
  94. {
  95. display.fillScreen(GxEPD_WHITE);
  96. }
  97. while (display.nextPage());
  98. }
  99. void full_black()
  100. {
  101. display.setFullWindow();
  102. display.firstPage();
  103. do
  104. {
  105. display.fillScreen(GxEPD_BLACK);
  106. }
  107. while (display.nextPage());
  108. }
  109. void partial_white()
  110. {
  111. display.setPartialWindow(0, 0, display.width(), display.height());
  112. display.firstPage();
  113. do
  114. {
  115. display.fillScreen(GxEPD_WHITE);
  116. }
  117. while (display.nextPage());
  118. }
  119. void partial_black()
  120. {
  121. display.setPartialWindow(0, 0, display.width(), display.height());
  122. display.firstPage();
  123. do
  124. {
  125. display.fillScreen(GxEPD_BLACK);
  126. }
  127. while (display.nextPage());
  128. }
  129. void horizontal_stripes(uint16_t nr)
  130. {
  131. uint16_t h = display.height() / nr;
  132. display.setPartialWindow(0, 0, display.width(), display.height());
  133. display.firstPage();
  134. do
  135. {
  136. uint16_t y = 0;
  137. do
  138. {
  139. display.fillRect(0, y, display.width(), h, GxEPD_BLACK);
  140. y += h;
  141. if (y >= display.height()) break;
  142. display.fillRect(0, y, display.width(), h, GxEPD_WHITE);
  143. y += h;
  144. } while (y < display.height());
  145. }
  146. while (display.nextPage());
  147. }
  148. void vertical_stripes(uint16_t nr)
  149. {
  150. uint16_t w = display.width() / nr;
  151. display.setPartialWindow(0, 0, display.width(), display.height());
  152. display.firstPage();
  153. do
  154. {
  155. uint16_t x = 0;
  156. do
  157. {
  158. display.fillRect(x, 0, w, display.height(), GxEPD_BLACK);
  159. x += w;
  160. if (x >= display.width()) break;
  161. display.fillRect(x, 0, w, display.height(), GxEPD_WHITE);
  162. x += w;
  163. } while (x < display.width());
  164. }
  165. while (display.nextPage());
  166. }
  167. void clock_test()
  168. {
  169. uint32_t actual = millis();
  170. while (actual < next_time)
  171. {
  172. // the "BlinkWithoutDelay" method works also for overflowed millis
  173. if ((actual - previous_time) > (partial_update_period_s * 1000))
  174. {
  175. //Serial.print(actual - previous_time); Serial.print(" > "); Serial.println(partial_update_period_s * 1000);
  176. break;
  177. }
  178. delay(100);
  179. actual = millis();
  180. }
  181. if ((actual - previous_full_update) > full_update_period_s * millis_per_second)
  182. {
  183. //display.clearScreen();
  184. previous_full_update = actual;
  185. }
  186. previous_time = actual;
  187. next_time += uint32_t(partial_update_period_s * millis_per_second);
  188. total_seconds += partial_update_period_s;
  189. seconds = total_seconds % 60;
  190. minutes = (total_seconds / 60) % 60;
  191. hours = (total_seconds / 3600) % 24;
  192. days = (total_seconds / 3600) / 24;
  193. if ((display.width() >= 400) && (display.height() >= 300))
  194. {
  195. showDays();
  196. showTime();
  197. }
  198. else showMinutes();
  199. display.powerOff();
  200. }
  201. String str02(uint32_t v)
  202. {
  203. return (v < 10 ? String(0) + String(v) : String(v));
  204. }
  205. void showMinutes()
  206. {
  207. static int16_t bbx = 400;
  208. static int16_t bby = 300;
  209. static uint16_t bbw = 0;
  210. static uint16_t bbh = 0;
  211. //Serial.println("showMinutes");
  212. String str = str02(minutes);
  213. display.setRotation(display.epd2.WIDTH > display.epd2.HEIGHT ? 0 : 1);
  214. display.setFont(&Open_Sans_ExtraBold_120);
  215. display.setTextColor(GxEPD_BLACK);
  216. int16_t tbx, tby; uint16_t tbw, tbh;
  217. display.getTextBounds(str, 0, 0, &tbx, &tby, &tbw, &tbh);
  218. // place the bounding box, cover any previous ones
  219. int16_t tx = max(0, ((display.width() - tbw) / 2));
  220. int16_t ty = max(0, ((display.height() - tbh) / 2));
  221. bbx = min(bbx, tx);
  222. bby = min(bby, ty);
  223. bbw = max(bbw, tbw);
  224. bbh = max(bbh, tbh);
  225. // calculate the cursor
  226. int16_t x = bbx - tbx;
  227. int16_t y = bby - tby;
  228. display.setPartialWindow(bbx, bby, bbw, bbh);
  229. display.firstPage();
  230. do
  231. {
  232. display.fillScreen(GxEPD_WHITE);
  233. //display.drawRect(bbx, bby, bbw, bbh, GxEPD_BLACK);
  234. display.setCursor(x, y);
  235. display.print(str);
  236. }
  237. while (display.nextPage());
  238. delay(1000);
  239. //Serial.println("showMinutes done");
  240. }
  241. void showDays()
  242. {
  243. static int16_t bbx = 400;
  244. static int16_t bby = 300;
  245. static uint16_t bbw = 0;
  246. static uint16_t bbh = 0;
  247. //Serial.println("showDays");
  248. String str(days); str += " days";
  249. display.setRotation(0);
  250. display.setFont(&Open_Sans_ExtraBold_120);
  251. display.setTextColor(GxEPD_BLACK);
  252. int16_t tbx, tby; uint16_t tbw, tbh;
  253. display.getTextBounds(str, 0, 0, &tbx, &tby, &tbw, &tbh);
  254. // place the bounding box
  255. int16_t tx = max(0, ((display.width() - tbw) / 2));
  256. int16_t ty = max(0, (display.height() / 4 - tbh / 2));
  257. bbx = min(bbx, tx);
  258. bby = min(bby, ty);
  259. bbw = max(bbw, tbw);
  260. bbh = max(bbh, tbh);
  261. // calculate the cursor
  262. uint16_t x = bbx - tbx;
  263. uint16_t y = bby - tby;
  264. display.setPartialWindow(bbx, bby, bbw, bbh);
  265. display.firstPage();
  266. do
  267. {
  268. display.fillScreen(GxEPD_WHITE);
  269. //display.drawRect(bbx, bby, bbw, bbh, GxEPD_BLACK);
  270. display.setCursor(x, y);
  271. display.print(str);
  272. }
  273. while (display.nextPage());
  274. delay(1000);
  275. //Serial.println("showDays done");
  276. }
  277. void showTime()
  278. {
  279. static int16_t bbx = 400;
  280. static int16_t bby = 300;
  281. static uint16_t bbw = 0;
  282. static uint16_t bbh = 0;
  283. //Serial.println("showTime");
  284. //String str = str02(minutes) + ":" + str02(seconds);
  285. String str = str02(hours) + ":" + str02(minutes);
  286. display.setRotation(0);
  287. display.setFont(&Open_Sans_ExtraBold_120);
  288. display.setTextColor(GxEPD_BLACK);
  289. int16_t tbx, tby; uint16_t tbw, tbh;
  290. display.getTextBounds(str, 0, 0, &tbx, &tby, &tbw, &tbh);
  291. // place the bounding box
  292. int16_t tx = max(0, ((display.width() - tbw) / 2));
  293. int16_t ty = max(0, (display.height() * 3 / 4 - tbh / 2));
  294. bbx = min(bbx, tx);
  295. bby = min(bby, ty);
  296. bbw = max(bbw, tbw);
  297. bbh = max(bbh, tbh);
  298. // calculate the cursor
  299. uint16_t x = bbx - tbx;
  300. uint16_t y = bby - tby;
  301. display.setPartialWindow(bbx, bby, bbw, bbh);
  302. display.firstPage();
  303. do
  304. {
  305. display.fillScreen(GxEPD_WHITE);
  306. //display.drawRect(bbx, bby, bbw, bbh, GxEPD_BLACK);
  307. display.setCursor(x, y);
  308. display.print(str);
  309. }
  310. while (display.nextPage());
  311. //Serial.println("showTime done");
  312. }