|
@@ -1,8 +1,16 @@
|
|
|
|
|
|
+#define VERSION "0.1.1"
|
|
|
|
|
|
#include <ESP8266WiFi.h> //ESP8266 Core WiFi Library (you most likely already have this in your sketch)
|
|
|
+#include <WiFiClient.h>
|
|
|
+#include <ESP8266WebServer.h>
|
|
|
+#include <ESP8266mDNS.h>
|
|
|
+#include <ESP8266HTTPUpdateServer.h>
|
|
|
#include <PubSubClient.h>
|
|
|
|
|
|
+ESP8266WebServer httpServer(80);
|
|
|
+ESP8266HTTPUpdateServer httpUpdater;
|
|
|
+
|
|
|
#include <Wire.h>
|
|
|
#include "LiquidCrystal_I2C.h"
|
|
|
|
|
@@ -17,12 +25,19 @@
|
|
|
#define LCDADDR 0x27
|
|
|
#define LUXSENSORADDR 0x23
|
|
|
|
|
|
-const int DHTPin = 13;
|
|
|
-const int RelaisPin = 16;
|
|
|
-const int PlusButtonPin = 0;
|
|
|
-const int MinusButtonPin = 2;
|
|
|
-const int ModeButtonPin = 14;
|
|
|
-const int PIRPin = 12;
|
|
|
+#define PIN_DHTSENSOR 13
|
|
|
+#define PIN_RELAIS 16
|
|
|
+#define PIN_BUTTON_PLUS 0
|
|
|
+#define PIN_BUTTON_MINUS 2
|
|
|
+#define PIN_BUTTON_MODE 14
|
|
|
+#define PIN_PIRSENSOR 12
|
|
|
+
|
|
|
+/*const int PIN_DHTSENSOR = 13;
|
|
|
+ const int PIN_RELAIS = 16;
|
|
|
+ const int PIN_BUTTON_PLUS = 0;
|
|
|
+ const int PIN_BUTTON_MINUS = 2;
|
|
|
+ const int PIN_BUTTON_MODE = 14;
|
|
|
+ const int PIN_PIRSENSOR = 12;*/
|
|
|
|
|
|
const bool RelaisOnState = LOW;
|
|
|
const bool ButtonOnState = LOW;
|
|
@@ -55,7 +70,9 @@ byte heatingMode = 1;
|
|
|
bool turnHeatingOn = false;
|
|
|
|
|
|
float humidity, temperature;
|
|
|
+//int humidity, temperature;
|
|
|
|
|
|
+const char* host = "espthermostat";
|
|
|
const char* ssid = "KS61T5SH"; // WiFi SSID
|
|
|
const char* password = "Gurken651salat"; // WiFi PWD
|
|
|
|
|
@@ -75,7 +92,12 @@ const char* mqtt_topic_heating_lastontime = "Test/Thermostat/HeatingLastOnTime";
|
|
|
// subscribe topic
|
|
|
const char* mqtt_topic_in = "Test/Thermostat/in";
|
|
|
|
|
|
-DHT dht(DHTPin, DHTTYPE);
|
|
|
+DHT dht(PIN_DHTSENSOR, DHTTYPE);
|
|
|
+
|
|
|
+// global variables from other modules
|
|
|
+extern bool displayActive;
|
|
|
+
|
|
|
+
|
|
|
|
|
|
//AS_BH1750 lightMeter; // Lichtstärkemessung mit BH1750
|
|
|
|
|
@@ -89,24 +111,21 @@ char msg[50];
|
|
|
|
|
|
char topic[50];
|
|
|
|
|
|
-// LCD
|
|
|
-byte customCharSun[8] = {0b00100, 0b10001, 0b01110, 0b11111, 0b11111, 0b01110, 0b10001, 0b00100};
|
|
|
-byte customCharMoon[8] = {0b11000, 0b01110, 0b00110, 0b00111, 0b00111, 0b00110, 0b01110, 0b11000};
|
|
|
-byte customCharArrowRight[8] = {0b00000, 0b00100, 0b00110, 0b11111, 0b11111, 0b00110, 0b00100, 0b00000};
|
|
|
-bool displayActive = false;
|
|
|
-unsigned long displayLastOnMillis = 0;
|
|
|
int displayTimeout = 10000;
|
|
|
|
|
|
//bool lightMeter_present;
|
|
|
|
|
|
void setup_wifi() {
|
|
|
-
|
|
|
delay(10);
|
|
|
// We start by connecting to a WiFi network
|
|
|
Serial.println();
|
|
|
Serial.print("Connecting to ");
|
|
|
Serial.println(ssid);
|
|
|
|
|
|
+ /////
|
|
|
+ WiFi.mode(WIFI_STA);
|
|
|
+ /////
|
|
|
+
|
|
|
WiFi.begin(ssid, password);
|
|
|
|
|
|
while (WiFi.status() != WL_CONNECTED) {
|
|
@@ -258,12 +277,16 @@ void setup() {
|
|
|
//wifiManager.setConfigPortalTimeout(180);
|
|
|
Serial.begin(115200);
|
|
|
delay(300);
|
|
|
+ Serial.print("WiFi Thermostat v");
|
|
|
+ Serial.print(VERSION);
|
|
|
+ Serial.println(" by Flo Kra");
|
|
|
+ Serial.println("starting...");
|
|
|
|
|
|
- pinMode(RelaisPin, OUTPUT);
|
|
|
- digitalWrite(RelaisPin, HIGH);
|
|
|
- pinMode(PlusButtonPin, INPUT_PULLUP);
|
|
|
- pinMode(MinusButtonPin, INPUT_PULLUP);
|
|
|
- pinMode(ModeButtonPin, INPUT_PULLUP);
|
|
|
+ pinMode(PIN_RELAIS, OUTPUT);
|
|
|
+ digitalWrite(PIN_RELAIS, HIGH);
|
|
|
+ pinMode(PIN_BUTTON_PLUS, INPUT_PULLUP);
|
|
|
+ pinMode(PIN_BUTTON_MINUS, INPUT_PULLUP);
|
|
|
+ pinMode(PIN_BUTTON_MODE, INPUT_PULLUP);
|
|
|
|
|
|
// DHT11/22 Temp/Hum-Sensor initialisieren
|
|
|
dht.begin();
|
|
@@ -282,114 +305,29 @@ void setup() {
|
|
|
// }
|
|
|
|
|
|
setup_wifi();
|
|
|
- client.setServer(mqtt_server, mqtt_port);
|
|
|
- client.setCallback(callback);
|
|
|
-
|
|
|
- lcd.init();
|
|
|
- lcd.createChar(0, customCharMoon);
|
|
|
- lcd.createChar(1, customCharSun);
|
|
|
- lcd.createChar(2, customCharArrowRight);
|
|
|
-
|
|
|
- lcd.setCursor(0, 0);
|
|
|
-
|
|
|
- lcd.print("WiFi-Thermostat ");
|
|
|
- lcd.setCursor(0, 1);
|
|
|
- lcd.print(" by Flo Kra");
|
|
|
-
|
|
|
- // 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();
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-bool plusButtonCurrentState = HIGH;
|
|
|
-bool plusButtonLastState = HIGH;
|
|
|
-unsigned long plusButtonDownMillis = 0;
|
|
|
-unsigned long plusButtonRepeatMillis = 0;
|
|
|
-unsigned long plusButtonHoldTime = 0;
|
|
|
-bool plusButtonFired = false;
|
|
|
-
|
|
|
-bool minusButtonCurrentState = HIGH;
|
|
|
-bool minusButtonLastState = HIGH;
|
|
|
-unsigned long minusButtonDownMillis = 0;
|
|
|
-unsigned long minusButtonRepeatMillis = 0;
|
|
|
-unsigned long minusButtonHoldTime = 0;
|
|
|
-bool minusButtonFired = false;
|
|
|
-
|
|
|
-bool modeButtonCurrentState = HIGH;
|
|
|
-bool modeButtonLastState = HIGH;
|
|
|
-unsigned long modeButtonDownMillis = 0;
|
|
|
-unsigned long modeButtonHoldTime = 0;
|
|
|
-bool modeButtonFired = false;
|
|
|
-bool modeButtonHoldFired = false;
|
|
|
-
|
|
|
-void enableDisplay() {
|
|
|
- lcd.backlight();
|
|
|
- displayActive = true;
|
|
|
- displayLastOnMillis = millis();
|
|
|
-}
|
|
|
|
|
|
-void disableDisplay() {
|
|
|
- lcd.noBacklight();
|
|
|
- displayActive = false;
|
|
|
-}
|
|
|
+ MDNS.begin(host);
|
|
|
|
|
|
-void extendDisplayTimeout() {
|
|
|
- displayLastOnMillis = millis();
|
|
|
-}
|
|
|
+ httpUpdater.setup(&httpServer);
|
|
|
|
|
|
+ httpServer.on("/", handleRoot);
|
|
|
+ httpServer.onNotFound(handleNotFound);
|
|
|
+
|
|
|
+ httpServer.begin();
|
|
|
|
|
|
+ MDNS.addService("http", "tcp", 80);
|
|
|
+ Serial.printf("HTTPUpdateServer ready! Open http://%s.local/update in your browser\n", host);
|
|
|
+
|
|
|
+ client.setServer(mqtt_server, mqtt_port);
|
|
|
+ client.setCallback(callback);
|
|
|
|
|
|
-void plusButtonAction() {
|
|
|
- if(heatingMode == 1 && heatingEnabled) {
|
|
|
- Serial.println("+");
|
|
|
- if ( setTempDay <= (setTempMax - 0.5)) setTempDay += 0.5;
|
|
|
- }
|
|
|
- extendDisplayTimeout();
|
|
|
- lastMsg = 0; // to enforce immediate display update
|
|
|
-}
|
|
|
-
|
|
|
-void minusButtonAction() {
|
|
|
- if(heatingMode == 1 && heatingEnabled) {
|
|
|
- Serial.println("-");
|
|
|
- if ( setTempDay >= (setTempMin + 0.5)) setTempDay -= 0.5;
|
|
|
- }
|
|
|
- extendDisplayTimeout();
|
|
|
- lastMsg = 0; // to enforce immediate display update
|
|
|
-}
|
|
|
-
|
|
|
-void modeButtonAction() {
|
|
|
- extendDisplayTimeout();
|
|
|
- if (heatingEnabled) {
|
|
|
- Serial.print("switch mode to ");
|
|
|
- if (heatingMode == 1) heatingMode = 2;
|
|
|
- else if (heatingMode == 2) heatingMode = 1;
|
|
|
- Serial.println(heatingMode);
|
|
|
- //lastMsg = lastMsg + measureinterval; // force update
|
|
|
- lastMsg = 0; // to enforce immediate display update
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void modeButtonHoldAction() {
|
|
|
- Serial.println("switch off/on");
|
|
|
- extendDisplayTimeout();
|
|
|
- if (heatingEnabled) heatingEnabled = false;
|
|
|
- else heatingEnabled = true;
|
|
|
- //lastMsg = lastMsg + measureinterval; // force update
|
|
|
- lastMsg = 0; // to enforce immediate display update
|
|
|
+ initDisplay();
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
void loop() {
|
|
|
+ httpServer.handleClient();
|
|
|
+
|
|
|
|
|
|
if (!client.connected()) {
|
|
|
reconnect();
|
|
@@ -397,131 +335,11 @@ void loop() {
|
|
|
client.loop();
|
|
|
|
|
|
|
|
|
- // Buttons einlesen
|
|
|
-
|
|
|
- // plus button
|
|
|
- plusButtonCurrentState = digitalRead(PlusButtonPin);
|
|
|
- if (plusButtonCurrentState == LOW && plusButtonLastState == HIGH) { // button was unpressed and is now pressed
|
|
|
- plusButtonDownMillis = millis();
|
|
|
- plusButtonLastState = plusButtonCurrentState;
|
|
|
- }
|
|
|
- else if (plusButtonCurrentState == LOW && plusButtonLastState == LOW) { // button is held
|
|
|
- plusButtonHoldTime = millis() - plusButtonDownMillis;
|
|
|
- if ( plusButtonHoldTime > 50 ) {
|
|
|
- plusButtonLastState = plusButtonCurrentState;
|
|
|
- if (!displayActive && !plusButtonFired ) {
|
|
|
- enableDisplay();
|
|
|
- plusButtonFired = true;
|
|
|
- }
|
|
|
- // else if (displayActive && !plusButtonFired ) {
|
|
|
- // plusButtonAction();
|
|
|
- // plusButtonFired = true;
|
|
|
- // }
|
|
|
- }
|
|
|
- if ( plusButtonHoldTime > 1250 ) {
|
|
|
- // button is held longer - repeating
|
|
|
- if ( (millis() - plusButtonRepeatMillis) > 300 ) {
|
|
|
- plusButtonAction();
|
|
|
- plusButtonRepeatMillis = millis();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else if (plusButtonCurrentState == HIGH && plusButtonLastState == LOW) { // button is released again
|
|
|
- plusButtonLastState = plusButtonCurrentState;
|
|
|
-
|
|
|
- if (displayActive && !plusButtonFired) {
|
|
|
- plusButtonAction();
|
|
|
- }
|
|
|
- plusButtonFired = false;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- // minus button
|
|
|
- minusButtonCurrentState = digitalRead(MinusButtonPin);
|
|
|
- if (minusButtonCurrentState == LOW && minusButtonLastState == HIGH) { // button was unpressed and is now pressed
|
|
|
- minusButtonDownMillis = millis();
|
|
|
- minusButtonLastState = minusButtonCurrentState;
|
|
|
- }
|
|
|
- else if (minusButtonCurrentState == LOW && minusButtonLastState == LOW) { // button is held
|
|
|
- minusButtonHoldTime = millis() - minusButtonDownMillis;
|
|
|
- if ( minusButtonHoldTime > 50 ) {
|
|
|
- minusButtonLastState = minusButtonCurrentState;
|
|
|
- if (!displayActive && !minusButtonFired ) {
|
|
|
- enableDisplay();
|
|
|
- minusButtonFired = true;
|
|
|
- }
|
|
|
- // else if (displayActive && !minusButtonFired ) {
|
|
|
- // minusButtonAction();
|
|
|
- // minusButtonFired = true;
|
|
|
- // }
|
|
|
- }
|
|
|
- if ( minusButtonHoldTime > 1250 ) {
|
|
|
- // button is held longer - repeating
|
|
|
- if ( (millis() - minusButtonRepeatMillis) > 300 ) {
|
|
|
- minusButtonAction();
|
|
|
- minusButtonRepeatMillis = millis();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else if (minusButtonCurrentState == HIGH && minusButtonLastState == LOW) { // button is released again
|
|
|
- minusButtonLastState = minusButtonCurrentState;
|
|
|
-
|
|
|
- if (displayActive && !minusButtonFired) {
|
|
|
- minusButtonAction();
|
|
|
- }
|
|
|
- minusButtonFired = false;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- // mode button
|
|
|
- modeButtonCurrentState = digitalRead(ModeButtonPin);
|
|
|
- if (modeButtonCurrentState == LOW && modeButtonLastState == HIGH) { // button was unpressed and is now pressed
|
|
|
- modeButtonDownMillis = millis();
|
|
|
- modeButtonLastState = modeButtonCurrentState;
|
|
|
- }
|
|
|
- else if (modeButtonCurrentState == LOW && modeButtonLastState == LOW) { // button is held
|
|
|
- modeButtonHoldTime = millis() - modeButtonDownMillis;
|
|
|
- if ( modeButtonHoldTime > 50 ) {
|
|
|
- modeButtonLastState = modeButtonCurrentState;
|
|
|
- if (!displayActive && !modeButtonFired ) {
|
|
|
- enableDisplay();
|
|
|
- modeButtonFired = true;
|
|
|
- }
|
|
|
- // else if (displayActive && !modeButtonFired ) {
|
|
|
- // modeButtonAction();
|
|
|
- // modeButtonFired = true;
|
|
|
- // }
|
|
|
- }
|
|
|
- if ( modeButtonHoldTime > 2000 && !modeButtonHoldFired ) {
|
|
|
- // button is held longer
|
|
|
- modeButtonHoldFired = true;
|
|
|
- modeButtonHoldAction();
|
|
|
- }
|
|
|
- }
|
|
|
- else if (modeButtonCurrentState == HIGH && modeButtonLastState == LOW) { // button is released again
|
|
|
- modeButtonLastState = modeButtonCurrentState;
|
|
|
- if (displayActive && !modeButtonFired) {
|
|
|
- modeButtonAction();
|
|
|
- }
|
|
|
- modeButtonFired = false;
|
|
|
- modeButtonHoldFired = false;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- unsigned long now = millis();
|
|
|
-
|
|
|
- if (displayActive && (now - displayLastOnMillis) > displayTimeout) {
|
|
|
- disableDisplay();
|
|
|
- }
|
|
|
-
|
|
|
+ checkButtonStates();
|
|
|
+ handleDisplayTimeout();
|
|
|
|
|
|
- if ( (now - lastMsg) > measureinterval) {
|
|
|
- lastMsg = now;
|
|
|
+ if ( (millis() - lastMsg) > measureinterval) {
|
|
|
+ lastMsg = millis();
|
|
|
|
|
|
humidity = dht.readHumidity();
|
|
|
temperature = dht.readTemperature(); // Read temperature as Celsius (the default)
|
|
@@ -529,13 +347,13 @@ void loop() {
|
|
|
unsigned long heatingOnTime, heatingOffTime;
|
|
|
|
|
|
if (heatingEnabled && turnHeatingOn) {
|
|
|
- heatingOnTime = (now - heatingLastOffMillis) / 1000;
|
|
|
+ heatingOnTime = (millis() - heatingLastOffMillis) / 1000;
|
|
|
Serial.print("heatingOnTime: ");
|
|
|
Serial.print(heatingOnTime);
|
|
|
Serial.println();
|
|
|
}
|
|
|
else if (heatingEnabled && !turnHeatingOn) {
|
|
|
- heatingOffTime = (now - heatingLastOnMillis) / 1000;
|
|
|
+ heatingOffTime = (millis() - heatingLastOnMillis) / 1000;
|
|
|
Serial.print("heatingOffTime: ");
|
|
|
Serial.print(heatingOffTime);
|
|
|
Serial.println();
|
|
@@ -543,8 +361,8 @@ void loop() {
|
|
|
|
|
|
if ( temperature >= setTemp ) {
|
|
|
turnHeatingOn = false;
|
|
|
- heatingLastOnMillis = now;
|
|
|
- digitalWrite(RelaisPin, !RelaisOnState);
|
|
|
+ heatingLastOnMillis = millis();
|
|
|
+ digitalWrite(PIN_RELAIS, !RelaisOnState);
|
|
|
Serial.println("heating off");
|
|
|
|
|
|
Serial.print("last onTime: ");
|
|
@@ -557,7 +375,7 @@ void loop() {
|
|
|
}
|
|
|
else if ( heatingEnabled && ( temperature < (setTemp - hysteresis) ) && ( heatingOffTime > minOffTime ) ) {
|
|
|
turnHeatingOn = true;
|
|
|
- digitalWrite(RelaisPin, RelaisOnState);
|
|
|
+ digitalWrite(PIN_RELAIS, RelaisOnState);
|
|
|
Serial.println("heating on");
|
|
|
|
|
|
Serial.print("last offTime: ");
|