Display.ino 10.0 KB

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