Display.ino 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. // LCD
  2. unsigned char customCharSun[] = {B00100, B10001, B01110, B11111, B11111, B01110, B10001, B00100};
  3. //unsigned char customCharMoon[] = {B11000, B01110, B00110, B00111, B00111, B00110, B01110, B11000};
  4. unsigned char customCharMoon[] = {B00011, B01110, B01100, B11100, B11100, B01100, B01110, B00011};
  5. unsigned char customCharArrowRight[] = {B01000, B01100, B01110, B01111, B01110, B01100, B01000, B00000};
  6. unsigned char customCharDegC[] = {B01000, B10100, B01000, B00011, B00100, B00100, B00011, B00000};
  7. unsigned char customCharConn[] = {B00000, B00000, B11100, B00010, B11001, B00101, B10101, B00000};
  8. unsigned char customCharDisconn[] = {B10001, B01010, B00100, B01010, B10001, B00000, B10000, B00000};
  9. unsigned char customCharReduction2[] = {B00000, B11111, B01110, B00100, B00000, B11111, B01110, B00100}; //(2 arrows down)
  10. unsigned char customCharFlame[] = {B00100, B00100, B01010, B01010, B10101, B10101, B10101, B01110};
  11. unsigned char customCharLock[] = {B01110, B10001, B10001, B11111, B11011, B11011, B11111, B00000};
  12. unsigned char customCharPause[] = {B11011, B11011, B11011, B11011, B11011, B11011, B11011, B11011};
  13. // boolean displayActive = false;
  14. unsigned long displayLastOnMillis = 0;
  15. void enableDisplay()
  16. {
  17. lcd.backlight();
  18. displayActive = true;
  19. displayLastOnMillis = millis();
  20. }
  21. void disableDisplay()
  22. {
  23. lcd.noBacklight();
  24. displayActive = false;
  25. }
  26. void extendDisplayTimeout() { displayLastOnMillis = millis(); }
  27. void handleDisplayTimeout()
  28. {
  29. if (displayActive && (millis() - displayLastOnMillis) > (confBas.displayTimeout * 1000)) { disableDisplay(); }
  30. }
  31. void initDisplay()
  32. {
  33. lcd.init();
  34. lcd.createChar(0, customCharMoon);
  35. lcd.createChar(1, customCharSun);
  36. lcd.createChar(2, customCharArrowRight); // replaced by > char
  37. lcd.createChar(3, customCharDegC);
  38. lcd.createChar(4, customCharConn);
  39. lcd.createChar(5, customCharDisconn);
  40. lcd.createChar(6, customCharReduction2);
  41. lcd.createChar(7, customCharFlame);
  42. //lcd.createChar(7, customCharLock);
  43. // only 8 custom chars are possible :-/
  44. lcd.setCursor(0, 0);
  45. lcd.print("WiFiThermostat ");
  46. lcd.setCursor(0, 1);
  47. lcd.print("(c) by FloKra.at");
  48. // for ( int i = 0; i < 3; i++) {
  49. // lcd.backlight();
  50. // delay(200);
  51. // lcd.noBacklight();
  52. // delay(200);
  53. // }
  54. lcd.backlight();
  55. // delay(1000);
  56. /// lcd.clear();
  57. displayActive = true;
  58. displayLastOnMillis = millis();
  59. }
  60. void displayShowWifiConnected()
  61. {
  62. lcd.setCursor(0, 0);
  63. lcd.print("WiFi connected ");
  64. lcd.setCursor(0, 1);
  65. lcd.print(" ");
  66. lcd.setCursor(0, 1);
  67. lcd.print(WiFi.localIP());
  68. lcd.backlight();
  69. displayActive = true;
  70. displayLastOnMillis = millis();
  71. delay(2000);
  72. }
  73. void displayShowWifiConnectionError()
  74. {
  75. lcd.setCursor(0, 0);
  76. lcd.print("WiFi connecting ");
  77. lcd.setCursor(0, 1);
  78. lcd.print("FAILED ");
  79. lcd.backlight();
  80. displayActive = true;
  81. displayLastOnMillis = millis();
  82. delay(2000);
  83. lcd.setCursor(0, 0);
  84. lcd.print("AP mode active ");
  85. lcd.setCursor(0, 1);
  86. lcd.print(" ");
  87. lcd.setCursor(0, 1);
  88. lcd.print(persWM.getApSsid());
  89. lcd.backlight();
  90. displayActive = true;
  91. displayLastOnMillis = millis();
  92. delay(2000);
  93. lcd.setCursor(0, 0);
  94. lcd.print("Password: ");
  95. lcd.setCursor(0, 1);
  96. lcd.print(" ");
  97. lcd.setCursor(0, 1);
  98. lcd.print(confDevWiFi.WiFiAPModePassword);
  99. lcd.backlight();
  100. displayActive = true;
  101. displayLastOnMillis = millis();
  102. delay(2000);
  103. }
  104. void displayShowMQTTConnected()
  105. {
  106. lcd.setCursor(0, 0);
  107. lcd.print("MQTT conn. to: ");
  108. lcd.setCursor(0, 1);
  109. lcd.print(" ");
  110. lcd.setCursor(0, 1);
  111. lcd.print(confMqtt.mqtt_server);
  112. lcd.backlight();
  113. displayActive = true;
  114. displayLastOnMillis = millis();
  115. displayShowFullscreenMsg = true;
  116. countDisplayInterval = 0;
  117. displayInterval = displayOverlayMsgTimeout;
  118. }
  119. void displayShowMQTTConnectionError()
  120. {
  121. lcd.setCursor(0, 0);
  122. lcd.print("MQTT connection ");
  123. lcd.setCursor(0, 1);
  124. lcd.print("FAILED ");
  125. lcd.backlight();
  126. displayActive = true;
  127. displayLastOnMillis = millis();
  128. displayShowFullscreenMsg = true;
  129. countDisplayInterval = 0;
  130. displayInterval = displayOverlayMsgTimeout;
  131. }
  132. void displayShowLine2OverlayMessage(char *msg)
  133. {
  134. lcd.setCursor(0, 1);
  135. lcd.print(" ");
  136. lcd.setCursor(0, 1);
  137. lcd.write((uint8_t)2); // arrow right symbol
  138. lcd.print(" ");
  139. lcd.print(msg);
  140. for (int i = strlen(msg); i < 14; i++)
  141. {
  142. lcd.print(" ");
  143. }
  144. displayShowLine2OverlayMsg = true;
  145. countDisplayInterval = 0;
  146. displayInterval = displayOverlayMsgTimeout;
  147. }
  148. void displayAddConnectionIcon()
  149. {
  150. lcd.setCursor(14, 1);
  151. lcd.print(" ");
  152. if (mqttConnected)
  153. lcd.write((uint8_t)4); // connected symbol
  154. else
  155. lcd.write((uint8_t)5); // disconnected symbol
  156. }
  157. void updateDisplay()
  158. {
  159. if (displayShowFullscreenMsg)
  160. {
  161. displayShowFullscreenMsg = false;
  162. displayInterval = confBas.displayInterval;
  163. updateDisplayImmediately = true;
  164. }
  165. else
  166. {
  167. boolean showTemp = false;
  168. char ch_temp[6];
  169. long now = millis();
  170. if (confBas.togglingTempHumAIDisplay)
  171. {
  172. char ch_hum[4];
  173. char tempLabel[2];
  174. if (((now - outTempHumLastUpdate) < maxMeasurementAgeOut) && outTempHumLastUpdate != 0 && whichTempToDisplay == 1 &&
  175. ((now - lastDisplayToggle) > (displayInterval * 1000)))
  176. {
  177. // outside temp has been updated < 5 min ago, last displayed temp was INSIDE and display interval is overdue
  178. whichTempToDisplay = 2; // 1= I, 2= O
  179. lastDisplayToggle = now;
  180. }
  181. else if (whichTempToDisplay != 1 && ((now - lastDisplayToggle) > (displayInterval * 1000)))
  182. {
  183. whichTempToDisplay = 1; // 1= I, 2= O
  184. lastDisplayToggle = now;
  185. }
  186. lastDisplayUpdate = now;
  187. if (whichTempToDisplay == 2)
  188. { // 2 = outside temp/hum received via MQTT
  189. if (outTempHumLastUpdate != 0 && (now - outTempHumLastUpdate) < maxMeasurementAgeOut)
  190. {
  191. showTemp = true;
  192. dtostrf(outTemp, 5, 1, ch_temp);
  193. sprintf(ch_hum, "%2i", outHum);
  194. strcpy(tempLabel, confAdv.oTempLabel);
  195. }
  196. }
  197. else
  198. {
  199. if (lastTempUpdate != 0 && (now - lastTempUpdate) < maxMeasurementAge)
  200. {
  201. showTemp = true;
  202. dtostrf(currTemp, 5, 1, ch_temp);
  203. sprintf(ch_hum, "%2i", currHum);
  204. strcpy(tempLabel, confAdv.iTempLabel);
  205. }
  206. }
  207. // 12345667890123456
  208. // =20.0° 35% >22.5°
  209. // A -10.2° 95% N
  210. // A 22.2° 95% N
  211. // A 5.2° 95% N
  212. // LCD line 1
  213. // print temperature incl = and ° symbol + humidity to lcd, line 1, first 11 chars
  214. lcd.setCursor(0, 0);
  215. if (showTemp)
  216. {
  217. // lcd.write(0x3D); // = Zeichen
  218. lcd.print(tempLabel);
  219. lcd.print(ch_temp);
  220. // lcd.write(0xDF); // degree symbol
  221. lcd.write((uint8_t)3); // °C symbol
  222. lcd.print(" ");
  223. if (currHum == 0)
  224. lcd.print("--");
  225. else if (currHum < 10)
  226. {
  227. lcd.print(" ");
  228. lcd.print(ch_hum);
  229. }
  230. else
  231. {
  232. lcd.print(ch_hum);
  233. }
  234. lcd.print("%");
  235. lcd.print(" ");
  236. }
  237. else
  238. {
  239. lcd.print(" ");
  240. }
  241. }
  242. else
  243. { // non toggling temperature I + A display without humidity in line 1
  244. lcd.setCursor(0, 0);
  245. lcd.print(confAdv.iTempLabel);
  246. if (lastTempUpdate != 0 && (now - lastTempUpdate) < maxMeasurementAge)
  247. {
  248. dtostrf(currTemp, 5, 1, ch_temp);
  249. lcd.print(ch_temp);
  250. }
  251. else
  252. {
  253. lcd.print(" --.-");
  254. }
  255. lcd.write((uint8_t)3); // °C symbol
  256. lcd.print(" ");
  257. if (outTempHumLastUpdate != 0 && (now - outTempHumLastUpdate) < maxMeasurementAgeOut)
  258. {
  259. lcd.print(" ");
  260. lcd.print(confAdv.oTempLabel);
  261. dtostrf(outTemp, 5, 1, ch_temp);
  262. lcd.print(ch_temp);
  263. lcd.write((uint8_t)3); // °C symbol
  264. }
  265. else
  266. {
  267. lcd.print(" ");
  268. }
  269. }
  270. updateCurrSetTemp();
  271. char ch_currSetTemp[6];
  272. dtostrf(currSetTemp, 5, 1, ch_currSetTemp);
  273. // LCD line 2
  274. // display target temperature to line 2, 8 chars length incl space at the end
  275. lcd.setCursor(0, 1);
  276. if (doRestart) { lcd.print("Restarting... "); }
  277. else if (pendingRestart)
  278. {
  279. lcd.print("Restart? ");
  280. }
  281. else if (heatingMode == 0)
  282. { // when the heating mode is OFF, do not display target temp - instead show "Heating off" info in line 2
  283. // 1234567890123456
  284. lcd.print(" ");
  285. lcd.setCursor(0, 1);
  286. lcd.print(confAdv.offMessage);
  287. // for(int i=strlen(offMessage); i < 14; i++) {
  288. // lcd.print(" ");
  289. //}
  290. displayAddConnectionIcon();
  291. }
  292. //else if (heatingPause > 0)
  293. //{ // when heating pause mode is active, do not display target temp - instead show "PAUSE" info in line 2
  294. // // 1234567890123456
  295. // lcd.print(" ");
  296. // lcd.setCursor(0, 1);
  297. // //lcd.print(confAdv.pauseMessage);
  298. // lcd.print("PAUSE 0:");
  299. //
  300. // unsigned int _pauseMin = heatingPause / 60;
  301. // if(_pauseMin < 10) lcd.print("0");
  302. // lcd.print(_pauseMin);
  303. //
  304. // displayAddConnectionIcon();
  305. //}
  306. else if (displayShowLine2OverlayMsg)
  307. {
  308. displayShowLine2OverlayMsg = false;
  309. displayInterval = confBas.displayInterval;
  310. if (pendingPresetToggle)
  311. {
  312. preset = pendingPreset;
  313. updateCurrentPresetName();
  314. pendingPresetToggle = false;
  315. }
  316. updateDisplayImmediately = true;
  317. }
  318. else
  319. {
  320. lcd.write((uint8_t)2); // arrow right symbol
  321. //lcd.print(">");
  322. // lcd.print(" ");
  323. lcd.print(ch_currSetTemp);
  324. // lcd.write(0xDF); // degree symbol
  325. lcd.write((uint8_t)3); // °C symbol
  326. lcd.print(" ");
  327. lcd.setCursor(8, 1);
  328. lcd.print(" ");
  329. // display status info to line 2 from char 9 -> 8 chars length
  330. lcd.setCursor(9, 1);
  331. if (preset == 0)
  332. { // day/normal mode
  333. lcd.write((uint8_t)1); // sun symbol if mode is day/normal
  334. }
  335. else if (preset == 1)
  336. { // night/reduction mode
  337. lcd.write((uint8_t)0); // moon symbol if mode is night/reduction
  338. }
  339. else if (preset == 2)
  340. { // night/reduction mode
  341. lcd.write((uint8_t)6); // reduction 2 (2 arrows down) symbol if mode is reduction 2
  342. }
  343. if (heatingPause > 0)
  344. {
  345. lcd.createChar(7, customCharPause);
  346. lcd.setCursor(12, 1);
  347. lcd.write((uint8_t)7); // pause symbol if heating is paused
  348. }
  349. else if (heatingLockTime > 0)
  350. {
  351. lcd.createChar(7, customCharLock);
  352. lcd.setCursor(12, 1);
  353. lcd.write((uint8_t)7); // lock symbol if heating should run BUT lockout time is active
  354. }
  355. else if (turnHeatingOn)
  356. {
  357. lcd.createChar(7, customCharFlame);
  358. lcd.setCursor(12, 1);
  359. lcd.write((uint8_t)7); // flame symbol if heating is active
  360. }
  361. else
  362. {
  363. lcd.setCursor(12, 1);
  364. lcd.print(" ");
  365. }
  366. displayAddConnectionIcon();
  367. }
  368. }
  369. }