// LCD byte customCharSun[] = {B00100, B10001, B01110, B11111, B11111, B01110, B10001, B00100}; byte customCharMoon[] = {B11000, B01110, B00110, B00111, B00111, B00110, B01110, B11000}; byte customCharArrowRight[] = {B01000, B01100, B01110, B01111, B01110, B01100, B01000, B00000}; byte customCharDegC[] = {B01000, B10100, B01000, B00011, B00100, B00100, B00011, B00000}; byte customCharConn[] = {B00000, B00000, B11100, B00010, B11001, B00101, B10101, B00000}; byte customCharDisconn[] = {B10001, B01010, B00100, B01010, B10001, B00000, B10000, B00000}; byte customCharReduction2[] = {B00000, B11111, B01110, B00100, B00000, B11111, B01110, B00100}; //(2 arrows down) byte customCharFlame[] = {B00100, B00100, B01010, B01010, B10101, B10101, B10101, B01110}; //boolean displayActive = false; unsigned long displayLastOnMillis = 0; void enableDisplay() { lcd.backlight(); displayActive = true; displayLastOnMillis = millis(); } void disableDisplay() { lcd.noBacklight(); displayActive = false; } void extendDisplayTimeout() { displayLastOnMillis = millis(); } void handleDisplayTimeout() { if (displayActive && (millis() - displayLastOnMillis) > (displayTimeout * 1000)) { disableDisplay(); } } void initDisplay() { lcd.init(); lcd.createChar(0, customCharMoon); lcd.createChar(1, customCharSun); lcd.createChar(2, customCharArrowRight); lcd.createChar(3, customCharDegC); lcd.createChar(4, customCharConn); lcd.createChar(5, customCharDisconn); lcd.createChar(6, customCharReduction2); lcd.createChar(7, customCharFlame); lcd.setCursor(0, 0); lcd.print("WiFiThermostat "); lcd.setCursor(0, 1); lcd.print("(c) by FloKra.at"); // for ( int i = 0; i < 3; i++) { // lcd.backlight(); // delay(200); // lcd.noBacklight(); // delay(200); // } lcd.backlight(); //delay(1000); ///lcd.clear(); displayActive = true; displayLastOnMillis = millis(); } void displayShowWifiConnected() { lcd.setCursor(0, 0); lcd.print("WiFi connected "); lcd.setCursor(0, 1); lcd.print("IP: "); lcd.setCursor(4, 1); lcd.print(WiFi.localIP()); lcd.backlight(); displayActive = true; displayLastOnMillis = millis(); delay(2000); } void displayShowWifiConnectionError() { lcd.setCursor(0, 0); lcd.print("WiFi connecting "); lcd.setCursor(0, 1); lcd.print("FAILED "); lcd.backlight(); displayActive = true; displayLastOnMillis = millis(); delay(2000); lcd.setCursor(0, 0); lcd.print("AP mode active "); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(persWM.getApSsid()); lcd.backlight(); displayActive = true; displayLastOnMillis = millis(); delay(2000); lcd.setCursor(0, 0); lcd.print("Password: "); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(wifiAPModePassword); lcd.backlight(); displayActive = true; displayLastOnMillis = millis(); delay(2000); } void displayShowMQTTConnected() { lcd.setCursor(0, 0); lcd.print("MQTT connected "); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(mqtt_server); lcd.backlight(); displayActive = true; displayLastOnMillis = millis(); displayShowFullscreenMsg = true; countDisplayInterval = 0; //displayInterval_saved = displayInterval; //already done in loadconf2 displayInterval = displayOverlayMsgTimeout; //delay(2000); } void displayShowMQTTConnectionError() { lcd.setCursor(0, 0); lcd.print("MQTT connection "); lcd.setCursor(0, 1); lcd.print("FAILED "); lcd.backlight(); displayActive = true; displayLastOnMillis = millis(); displayShowFullscreenMsg = true; countDisplayInterval = 0; //displayInterval_saved = displayInterval; //already done in loadconf2 displayInterval = displayOverlayMsgTimeout; //delay(2000); } void displayShowLine2OverlayMessage(char* msg) { lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.write((uint8_t)2); // arrow right symbol lcd.print(" "); lcd.print(msg); for (int i = strlen(msg); i < 14; i++) { lcd.print(" "); } displayShowLine2OverlayMsg = true; countDisplayInterval = 0; //displayInterval_saved = displayInterval; //already done in loadconf2 displayInterval = displayOverlayMsgTimeout; } void displayAddConnectionIcon() { lcd.setCursor(14, 1); lcd.print(" "); if (mqttConnected) lcd.write((uint8_t)4); // connected symbol else lcd.write((uint8_t)5); // disconnected symbol } void updateDisplay() { if (displayShowFullscreenMsg) { displayShowFullscreenMsg = false; displayInterval = displayInterval_saved; updateDisplayImmediately = true; } else { boolean showTemp = false; char ch_temp[6]; char ch_hum[4]; char tempLabel[2]; long now = millis(); if (togglingTempHumAIDisplay) { if ( ((now - outTempHumLastUpdate) < maxMeasurementAge) && outTempHumLastUpdate != 0 && whichTempToDisplay == 1 && ((now - lastDisplayToggle) > (displayInterval * 1000)) ) { // outside temp has been updated < 5 min ago, last displayed temp was INSIDE and display interval is overdue whichTempToDisplay = 2; // 1= I, 2= A lastDisplayToggle = now; } else if ( whichTempToDisplay != 1 && ((now - lastDisplayToggle) > (displayInterval * 1000)) ) { whichTempToDisplay = 1; // 1= I, 2= A lastDisplayToggle = now; } lastDisplayUpdate = now; if (whichTempToDisplay == 2) { //2 = outside temp/hum received via MQTT if ( outTempHumLastUpdate != 0 && (now - outTempHumLastUpdate) < maxMeasurementAge ) { showTemp = true; dtostrf(outTemp, 5, 1, ch_temp); sprintf(ch_hum, "%2i", outHum); strcpy(tempLabel, otemplab); } } else { if ( lastTempUpdate != 0 && (now - lastTempUpdate) < maxMeasurementAge ) { showTemp = true; dtostrf(currTemp, 5, 1, ch_temp); sprintf(ch_hum, "%2i", currHum); strcpy(tempLabel, itemplab); } } // 12345667890123456 // =20.0° 35% >22.5° // A -10.2° 95% N // A 22.2° 95% N // A 5.2° 95% N // LCD line 1 // print temperature incl = and ° symbol + humidity to lcd, line 1, first 11 chars lcd.setCursor(0, 0); if (showTemp) { //lcd.write(0x3D); // = Zeichen lcd.print(tempLabel); lcd.print(" "); lcd.print(ch_temp); //lcd.write(0xDF); // degree symbol lcd.write((uint8_t)3); // °C symbol lcd.print(" "); if (currHum == 0) lcd.print("--"); else if (currHum < 10) { lcd.print(" "); lcd.print(ch_hum); } else { lcd.print(ch_hum); } lcd.print("%"); lcd.print(" "); } else { lcd.print(" "); } } else { // non toggling temperature I + A display without humidity in line 1 lcd.setCursor(0, 0); lcd.print(itemplab); if ( lastTempUpdate != 0 && (now - lastTempUpdate) < maxMeasurementAge ) { dtostrf(currTemp, 5, 1, ch_temp); lcd.print(ch_temp); } else { lcd.print(" --.-"); } lcd.write((uint8_t)3); // °C symbol lcd.print(" "); if ( outTempHumLastUpdate != 0 && (now - outTempHumLastUpdate) < maxMeasurementAge ) { lcd.print(" "); lcd.print(otemplab); dtostrf(outTemp, 5, 1, ch_temp); lcd.print(ch_temp); lcd.write((uint8_t)3); // °C symbol } else { lcd.print(" "); } } updateCurrSetTemp(); char ch_currSetTemp[6]; dtostrf(currSetTemp, 5, 1, ch_currSetTemp); // LCD line 2 // display target temperature to line 2, 8 chars length incl space at the end lcd.setCursor(0, 1); if ( doRestart ) { lcd.print("Restarting... "); } else if ( pendingRestart ) { lcd.print("Restart? "); } else if ( heatingMode == 0 ) { // when the heating mode is OFF, do not display target temp - instead show "Heating off" info in line 2 // 1234567890123456 lcd.print(" "); lcd.setCursor(0, 1); lcd.print(offMessage); //for(int i=strlen(offMessage); i < 14; i++) { //lcd.print(" "); //} displayAddConnectionIcon(); } else if ( displayShowLine2OverlayMsg ) { displayShowLine2OverlayMsg = false; displayInterval = displayInterval_saved; if (pendingPresetToggle) { preset = pendingPreset; updateCurrentPresetName(); pendingPresetToggle = false; } updateDisplayImmediately = true; } else { lcd.write((uint8_t)2); // arrow right symbol //lcd.print(" "); lcd.print(ch_currSetTemp); //lcd.write(0xDF); // degree symbol lcd.write((uint8_t)3); // °C symbol lcd.print(" "); lcd.setCursor(8, 1); lcd.print(" "); // display status info to line 2 from char 9 -> 8 chars length lcd.setCursor(9, 1); if ( preset == 0 ) { // day/normal mode lcd.write((uint8_t)1); // sun symbol if mode is day/normal } else if ( preset == 1 ) { // night/reduction mode lcd.write((uint8_t)0); // moon symbol if mode is night/reduction } else if ( preset == 2 ) { // night/reduction mode lcd.write((uint8_t)6); // reduction 2 (2 arrows down) symbol if mode is reduction 2 } lcd.setCursor(12, 1); if (turnHeatingOn) { lcd.write((uint8_t)7); // flame symbol if heating is active } else { lcd.print(" "); } displayAddConnectionIcon(); } } }