Guest User

Untitled

a guest
Mar 1st, 2020
366
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.67 KB | None | 0 0
  1. /*******************************************************************
  2. Tetris clock that fetches its time Using the EzTimeLibrary
  3.  
  4. For use with the ESP32 or TinyPICO
  5. * *
  6. Written by Brian Lough
  7. YouTube: https://www.youtube.com/brianlough
  8. Tindie: https://www.tindie.com/stores/brianlough/
  9. Twitter: https://twitter.com/witnessmenow
  10. *******************************************************************/
  11.  
  12. // ----------------------------
  13. // Standard Libraries - Already Installed if you have ESP32 set up
  14. // ----------------------------
  15.  
  16. #include <WiFi.h>
  17.  
  18. // ----------------------------
  19. // Additional Libraries - each one of these will need to be installed.
  20. // ----------------------------
  21.  
  22. // Enabling this is meant to have a performance
  23. // improvement but its worse for me.
  24. // https://github.com/2dom/PxMatrix/pull/103
  25. //#define double_buffer
  26.  
  27. #include <PxMatrix.h>
  28. // The library for controlling the LED Matrix
  29. // At time of writing this my changes for the TinyPICO
  30. // Have been merged into the main PxMatrix library,
  31. // but have not been released, so you will need to install
  32. // from Github
  33. //
  34. // If you are using a regular ESP32 you may be able to use
  35. // the library manager version
  36. // https://github.com/2dom/PxMatrix
  37.  
  38. // Adafruit GFX library is a dependancy for the PxMatrix Library
  39. // Can be installed from the library manager
  40. // https://github.com/adafruit/Adafruit-GFX-Library
  41.  
  42. #include <TetrisMatrixDraw.h>
  43. // This library draws out characters using a tetris block
  44. // amimation
  45. // Can be installed from the library manager
  46. // https://github.com/toblum/TetrisAnimation
  47.  
  48. #include <ezTime.h>
  49. // Library used for getting the time and adjusting for DST
  50. // Search for "ezTime" in the Arduino Library manager
  51. // https://github.com/ropg/ezTime
  52.  
  53. // ---- Stuff to configure ----
  54.  
  55. // Initialize Wifi connection to the router
  56. char ssid[] = "SSID"; // your network SSID (name)
  57. char password[] = "PASSWORD"; // your network key
  58.  
  59. // Set a timezone using the following list
  60. // https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
  61. #define MYTIMEZONE "Europe/Dublin"
  62.  
  63. // Sets whether the clock should be 12 hour format or not.
  64. bool twelveHourFormat = false;
  65.  
  66. // If this is set to false, the number will only change if the value behind it changes
  67. // e.g. the digit representing the least significant minute will be replaced every minute,
  68. // but the most significant number will only be replaced every 10 minutes.
  69. // When true, all digits will be replaced every minute.
  70. bool forceRefresh = true;
  71. // -----------------------------
  72.  
  73. // ----- Wiring -------
  74. #define P_LAT 22
  75. #define P_A 19
  76. #define P_B 23
  77. #define P_C 18
  78. #define P_D 5
  79. #define P_E 15
  80. //#define P_OE 26 //TinyPICO
  81. //#define P_OE 21 //Huzzah32
  82. #define P_OE 2 // Generic ESP32
  83. // ---------------------
  84.  
  85. portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
  86. hw_timer_t * timer = NULL;
  87. hw_timer_t * animationTimer = NULL;
  88.  
  89. // PxMATRIX display(32,16,P_LAT, P_OE,P_A,P_B,P_C);
  90. // PxMATRIX display(64,32,P_LAT, P_OE,P_A,P_B,P_C,P_D);
  91. PxMATRIX display(64, 32, P_LAT, P_OE, P_A, P_B, P_C, P_D, P_E);
  92.  
  93. TetrisMatrixDraw tetris(display); // Main clock
  94. TetrisMatrixDraw tetris2(display); // The "M" of AM/PM
  95. TetrisMatrixDraw tetris3(display); // The "P" or "A" of AM/PM
  96.  
  97. Timezone myTZ;
  98. unsigned long oneSecondLoopDue = 0;
  99.  
  100. bool showColon = true;
  101. volatile bool finishedAnimating = false;
  102. bool displayIntro = true;
  103.  
  104. String lastDisplayedTime = "";
  105. String lastDisplayedAmPm = "";
  106.  
  107. // This method is needed for driving the display
  108. void IRAM_ATTR display_updater() {
  109. portENTER_CRITICAL_ISR(&timerMux);
  110. display.display(10);
  111. portEXIT_CRITICAL_ISR(&timerMux);
  112. }
  113.  
  114. // This method is for controlling the tetris library draw calls
  115. void animationHandler()
  116. {
  117. #ifndef double_buffer
  118. portENTER_CRITICAL_ISR(&timerMux);
  119. #endif
  120.  
  121. // Not clearing the display and redrawing it when you
  122. // dont need to improves how the refresh rate appears
  123. if (!finishedAnimating) {
  124. #ifdef double_buffer
  125. display.fillScreen(tetris.tetrisBLACK);
  126. #else
  127. display.clearDisplay();
  128. #endif
  129. //display.fillScreen(tetris.tetrisBLACK);
  130. if (displayIntro) {
  131. finishedAnimating = tetris.drawText(1, 21);
  132. } else {
  133. if (twelveHourFormat) {
  134. // Place holders for checking are any of the tetris objects
  135. // currently still animating.
  136. bool tetris1Done = false;
  137. bool tetris2Done = false;
  138. bool tetris3Done = false;
  139.  
  140. tetris1Done = tetris.drawNumbers(-6, 26, showColon);
  141. tetris2Done = tetris2.drawText(56, 25);
  142.  
  143. // Only draw the top letter once the bottom letter is finished.
  144. if (tetris2Done) {
  145. tetris3Done = tetris3.drawText(56, 15);
  146. }
  147.  
  148. finishedAnimating = tetris1Done && tetris2Done && tetris3Done;
  149.  
  150. } else {
  151. finishedAnimating = tetris.drawNumbers(2, 26, showColon);
  152. }
  153. }
  154. #ifdef double_buffer
  155. display.showBuffer();
  156. #endif
  157. }
  158. #ifndef double_buffer
  159. portEXIT_CRITICAL_ISR(&timerMux);
  160. #endif
  161. }
  162.  
  163. void drawIntro(int x = 0, int y = 0)
  164. {
  165. tetris.drawChar("P", x, y, tetris.tetrisCYAN);
  166. tetris.drawChar("o", x + 5, y, tetris.tetrisMAGENTA);
  167. tetris.drawChar("w", x + 11, y, tetris.tetrisYELLOW);
  168. tetris.drawChar("e", x + 17, y, tetris.tetrisGREEN);
  169. tetris.drawChar("r", x + 22, y, tetris.tetrisBLUE);
  170. tetris.drawChar("e", x + 27, y, tetris.tetrisRED);
  171. tetris.drawChar("d", x + 32, y, tetris.tetrisWHITE);
  172. tetris.drawChar(" ", x + 37, y, tetris.tetrisMAGENTA);
  173. tetris.drawChar("b", x + 42, y, tetris.tetrisYELLOW);
  174. tetris.drawChar("y", x + 47, y, tetris.tetrisGREEN);
  175. }
  176.  
  177. void drawConnecting(int x = 0, int y = 0)
  178. {
  179. tetris.drawChar("C", x, y, tetris.tetrisCYAN);
  180. tetris.drawChar("o", x + 5, y, tetris.tetrisMAGENTA);
  181. tetris.drawChar("n", x + 11, y, tetris.tetrisYELLOW);
  182. tetris.drawChar("n", x + 17, y, tetris.tetrisGREEN);
  183. tetris.drawChar("e", x + 22, y, tetris.tetrisBLUE);
  184. tetris.drawChar("c", x + 27, y, tetris.tetrisRED);
  185. tetris.drawChar("t", x + 32, y, tetris.tetrisWHITE);
  186. tetris.drawChar("i", x + 37, y, tetris.tetrisMAGENTA);
  187. tetris.drawChar("n", x + 42, y, tetris.tetrisYELLOW);
  188. tetris.drawChar("g", x + 47, y, tetris.tetrisGREEN);
  189. }
  190.  
  191. void setup() {
  192. Serial.begin(115200);
  193.  
  194. // Attempt to connect to Wifi network:
  195. Serial.print("Connecting Wifi: ");
  196. Serial.println(ssid);
  197.  
  198. // Set WiFi to station mode and disconnect from an AP if it was Previously
  199. // connected
  200. WiFi.mode(WIFI_STA);
  201. WiFi.begin(ssid, password);
  202.  
  203. while (WiFi.status() != WL_CONNECTED) {
  204. Serial.print(".");
  205. delay(500);
  206. }
  207.  
  208. Serial.println("");
  209. Serial.println("WiFi connected");
  210. Serial.print("IP address: ");
  211. Serial.println(WiFi.localIP());
  212.  
  213. // Do not set up display before WiFi connection
  214. // as it will crash!
  215.  
  216. // Intialise display library
  217. //display.begin(16, SPI_BUS_CLK, 27, SPI_BUS_MISO, SPI_BUS_SS); // TinyPICO
  218. display.begin(16); // Generic ESP32 including Huzzah
  219. display.flushDisplay();
  220.  
  221. // Setup timer for driving display
  222. timer = timerBegin(0, 80, true);
  223. timerAttachInterrupt(timer, &display_updater, true);
  224. timerAlarmWrite(timer, 2000, true);
  225. timerAlarmEnable(timer);
  226. yield();
  227. #ifdef double_buffer
  228. display.fillScreen(tetris.tetrisBLACK);
  229. #else
  230. display.clearDisplay();
  231. #endif
  232.  
  233. // "connecting"
  234. drawConnecting(5, 10);
  235. #ifdef double_buffer
  236. display.showBuffer();
  237. #endif
  238.  
  239. // Setup EZ Time
  240. setDebug(INFO);
  241. waitForSync();
  242.  
  243. Serial.println();
  244. Serial.println("UTC: " + UTC.dateTime());
  245.  
  246. myTZ.setLocation(F(MYTIMEZONE));
  247. Serial.print(F("Time in your set timezone: "));
  248. Serial.println(myTZ.dateTime());
  249.  
  250. #ifdef double_buffer
  251. display.fillScreen(tetris.tetrisBLACK);
  252. #else
  253. display.clearDisplay();
  254. #endif
  255. // "Powered By"
  256. drawIntro(6, 12);
  257. #ifdef double_buffer
  258. display.showBuffer();
  259. #endif
  260. delay(2000);
  261.  
  262. // Start the Animation Timer
  263. tetris.setText("TINY PICO");
  264. animationTimer = timerBegin(1, 80, true);
  265. timerAttachInterrupt(animationTimer, &animationHandler, true);
  266. timerAlarmWrite(animationTimer, 100000, true);
  267. timerAlarmEnable(animationTimer);
  268.  
  269. // Wait for the animation to finish
  270. while (!finishedAnimating)
  271. {
  272. delay(10); //waiting for intro to finish
  273. }
  274. delay(2000);
  275. finishedAnimating = false;
  276. displayIntro = false;
  277. tetris.scale = 2;
  278. }
  279.  
  280. void setMatrixTime() {
  281. String timeString = "";
  282. String AmPmString = "";
  283. if (twelveHourFormat) {
  284. // Get the time in format "1:15" or 11:15 (12 hour, no leading 0)
  285. // Check the EZTime Github page for info on
  286. // time formatting
  287. timeString = myTZ.dateTime("g:i");
  288.  
  289. //If the length is only 4, pad it with
  290. // a space at the beginning
  291. if (timeString.length() == 4) {
  292. timeString = " " + timeString;
  293. }
  294.  
  295. //Get if its "AM" or "PM"
  296. AmPmString = myTZ.dateTime("A");
  297. if (lastDisplayedAmPm != AmPmString) {
  298. Serial.println(AmPmString);
  299. lastDisplayedAmPm = AmPmString;
  300. // Second character is always "M"
  301. // so need to parse it out
  302. tetris2.setText("M", forceRefresh);
  303.  
  304. // Parse out first letter of String
  305. tetris3.setText(AmPmString.substring(0, 1), forceRefresh);
  306. }
  307. } else {
  308. // Get time in format "01:15" or "22:15"(24 hour with leading 0)
  309. timeString = myTZ.dateTime("H:i");
  310. }
  311.  
  312. // Only update Time if its different
  313. if (lastDisplayedTime != timeString) {
  314. Serial.println(timeString);
  315. lastDisplayedTime = timeString;
  316. tetris.setTime(timeString, forceRefresh);
  317.  
  318. // Must set this to false so animation knows
  319. // to start again
  320. finishedAnimating = false;
  321. }
  322. }
  323.  
  324. void handleColonAfterAnimation() {
  325.  
  326. // It will draw the colon every time, but when the colour is black it
  327. // should look like its clearing it.
  328. uint16_t colour = showColon ? tetris.tetrisWHITE : tetris.tetrisBLACK;
  329. // The x position that you draw the tetris animation object
  330. int x = twelveHourFormat ? -6 : 2;
  331. // The y position adjusted for where the blocks will fall from
  332. // (this could be better!)
  333. int y = 26 - (TETRIS_Y_DROP_DEFAULT * tetris.scale);
  334. tetris.drawColon(x, y, colour);
  335. }
  336.  
  337.  
  338. void loop() {
  339. unsigned long now = millis();
  340. if (now > oneSecondLoopDue) {
  341. // We can call this often, but it will only
  342. // update when it needs to
  343. setMatrixTime();
  344. showColon = !showColon;
  345.  
  346. // To reduce flicker on the screen we stop clearing the screen
  347. // when the animation is finished, but we still need the colon to
  348. // to blink
  349. if (finishedAnimating) {
  350. handleColonAfterAnimation();
  351. }
  352. oneSecondLoopDue = now + 1000;
  353. }
  354. }
Advertisement
Add Comment
Please, Sign In to add comment