Display.ino 10 KB

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