|
@@ -10,26 +10,31 @@
|
|
|
//#include <ESP8266WebServer.h> //Local WebServer used to serve the configuration portal
|
|
|
//#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager WiFi Configuration Magic
|
|
|
|
|
|
-#define DHTPIN 13
|
|
|
-#define DHTTYPE DHT22
|
|
|
-
|
|
|
-#define RELAISPIN 16
|
|
|
-#define MINUSBUTTONPIN 14
|
|
|
-#define PLUSBUTTONPIN 12
|
|
|
-#define MODEBUTTONPIN 0
|
|
|
+#include <AS_BH1750.h> // BH1750 lux sensor
|
|
|
+#include "DHT.h"
|
|
|
|
|
|
+#define DHTTYPE DHT22
|
|
|
#define LCDADDR 0x27
|
|
|
#define LUXSENSORADDR 0x23
|
|
|
|
|
|
-#include "DHT.h"
|
|
|
-DHT dht(DHTPIN, DHTTYPE);
|
|
|
+const int DHTPin = 13;
|
|
|
+const int RelaisPin = 16;
|
|
|
+const int PlusButtonPin = 12;
|
|
|
+const int MinusButtonPin = 14;
|
|
|
+const int ModeButtonPin = 0;
|
|
|
+const int PIRPin = 15;
|
|
|
|
|
|
-LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
|
|
|
+const bool RelaisOnState = LOW;
|
|
|
+const bool ButtonOnState = LOW;
|
|
|
|
|
|
-float targetTemp;
|
|
|
-float targetTempDay = 23.5;
|
|
|
-float targetTempNight = 19.0;
|
|
|
+float setTemp;
|
|
|
+float setTempDay = 24.5;
|
|
|
+float setTempNight = 19.0;
|
|
|
float hysteresis = 0.5;
|
|
|
+int minOnTime = 300; //s
|
|
|
+//uint16_t lux;
|
|
|
+//int lux;
|
|
|
+float lux;
|
|
|
|
|
|
int measureinterval = 10000;
|
|
|
|
|
@@ -51,8 +56,20 @@ const int mqtt_port = 1883;
|
|
|
const char* mqtt_topic_prefix = "Test/Thermostat/";
|
|
|
const char* mqtt_topic_temp = "Test/Thermostat/Temp";
|
|
|
const char* mqtt_topic_hum = "Test/Thermostat/Hum";
|
|
|
+const char* mqtt_topic_lux = "Test/Thermostat/Lux";
|
|
|
+
|
|
|
+int domoticz_idx_temphum = 987;
|
|
|
+int domoticz_idx_lux = 876;
|
|
|
+int domoticz_idx_heatingon = 765;
|
|
|
+int domoticz_idx_thermostat = 654;
|
|
|
|
|
|
|
|
|
+DHT dht(DHTPin, DHTTYPE);
|
|
|
+
|
|
|
+AS_BH1750 lightMeter; // Lichtstärkemessung mit BH1750
|
|
|
+
|
|
|
+LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
|
|
|
+
|
|
|
WiFiClient espClient;
|
|
|
PubSubClient client(espClient);
|
|
|
//PubSubClient client(server, port, callback, wifiClient);
|
|
@@ -63,17 +80,13 @@ char msg[50];
|
|
|
|
|
|
char topic[50];
|
|
|
|
|
|
-// Variables for printing temp and humidity
|
|
|
-String temp_str; //see last code block below use these to convert the float that you get back from DHT to a string =str
|
|
|
-String hum_str;
|
|
|
-char temp[50];
|
|
|
-char hum[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 lightMeter_present;
|
|
|
+
|
|
|
void setup_wifi() {
|
|
|
|
|
|
delay(10);
|
|
@@ -146,8 +159,30 @@ void setup() {
|
|
|
//wifiManager.autoConnect("Thermostat", "configesp");
|
|
|
//wifiManager.setConfigPortalTimeout(180);
|
|
|
Serial.begin(115200);
|
|
|
+ delay(300);
|
|
|
+
|
|
|
+ pinMode(RelaisPin, OUTPUT);
|
|
|
+ digitalWrite(RelaisPin, HIGH);
|
|
|
+ pinMode(PlusButtonPin, INPUT_PULLUP);
|
|
|
+ pinMode(MinusButtonPin, INPUT_PULLUP);
|
|
|
+ pinMode(ModeButtonPin, INPUT_PULLUP);
|
|
|
+
|
|
|
+ // DHT11/22 Temp/Hum-Sensor initialisieren
|
|
|
dht.begin();
|
|
|
|
|
|
+ // lightMeter BH1750
|
|
|
+ //if (! lightMeter.begin(BH1750_CONTINUOUS_HIGH_RES_MODE_2)) {
|
|
|
+ if (! lightMeter.begin(RESOLUTION_AUTO_HIGH)) {
|
|
|
+ lightMeter_present = false;
|
|
|
+ delay(50);
|
|
|
+ Serial.println(F("ERROR: no BH1750 light meter found"));
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ lightMeter_present = true;
|
|
|
+ delay(50);
|
|
|
+ Serial.println(F("BH1750 light meter found"));
|
|
|
+ }
|
|
|
+
|
|
|
setup_wifi();
|
|
|
client.setServer(mqtt_server, mqtt_port);
|
|
|
client.setCallback(callback);
|
|
@@ -166,6 +201,18 @@ void setup() {
|
|
|
}
|
|
|
|
|
|
|
|
|
+bool plusButtonState = HIGH;
|
|
|
+bool lastPlusButtonState = HIGH;
|
|
|
+unsigned long plusButtonlastDebounceTime = 0;
|
|
|
+
|
|
|
+bool minusButtonState = HIGH;
|
|
|
+bool lastMinusButtonState = HIGH;
|
|
|
+unsigned long minusButtonlastDebounceTime = 0;
|
|
|
+
|
|
|
+bool modeButtonState = HIGH;
|
|
|
+bool lastModeButtonState = HIGH;
|
|
|
+unsigned long modeButtonlastDebounceTime = 0;
|
|
|
+
|
|
|
void loop() {
|
|
|
|
|
|
if (!client.connected()) {
|
|
@@ -173,6 +220,70 @@ void loop() {
|
|
|
}
|
|
|
client.loop();
|
|
|
|
|
|
+
|
|
|
+ // Buttons einlesen
|
|
|
+
|
|
|
+ // plus button
|
|
|
+ plusButtonState = digitalRead(PlusButtonPin);
|
|
|
+ if (plusButtonState != lastPlusButtonState) {
|
|
|
+ plusButtonlastDebounceTime = millis();
|
|
|
+ }
|
|
|
+ if ((millis() - plusButtonlastDebounceTime) > 50) {
|
|
|
+ // whatever the reading is at, it's been there for longer than the debounce
|
|
|
+ // delay, so take it as the actual current state:
|
|
|
+ // if the button state has changed:
|
|
|
+ if (plusButtonState != lastPlusButtonState) {
|
|
|
+ lastPlusButtonState = plusButtonState;
|
|
|
+ if (plusButtonState == LOW) {
|
|
|
+ Serial.println("+");
|
|
|
+ setTemp+=0.5;
|
|
|
+ lastMsg = lastMsg + measureinterval; // force update
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // minus button
|
|
|
+ minusButtonState = digitalRead(MinusButtonPin);
|
|
|
+ if (minusButtonState != lastMinusButtonState) {
|
|
|
+ minusButtonlastDebounceTime = millis();
|
|
|
+ }
|
|
|
+ if ((millis() - minusButtonlastDebounceTime) > 50) {
|
|
|
+ // whatever the reading is at, it's been there for longer than the debounce
|
|
|
+ // delay, so take it as the actual current state:
|
|
|
+ // if the button state has changed:
|
|
|
+ if (minusButtonState != lastMinusButtonState) {
|
|
|
+ lastMinusButtonState = minusButtonState;
|
|
|
+ if (minusButtonState == LOW) {
|
|
|
+ Serial.println("-");
|
|
|
+ setTemp-=0.5;
|
|
|
+ lastMsg = lastMsg + measureinterval; // force update
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // mode button
|
|
|
+ modeButtonState = digitalRead(ModeButtonPin);
|
|
|
+ if (modeButtonState != lastModeButtonState) {
|
|
|
+ modeButtonlastDebounceTime = millis();
|
|
|
+ }
|
|
|
+ if ((millis() - modeButtonlastDebounceTime) > 50) {
|
|
|
+ // whatever the reading is at, it's been there for longer than the debounce
|
|
|
+ // delay, so take it as the actual current state:
|
|
|
+ // if the button state has changed:
|
|
|
+ if (modeButtonState != lastModeButtonState) {
|
|
|
+ lastModeButtonState = modeButtonState;
|
|
|
+ if (modeButtonState == LOW) {
|
|
|
+ Serial.println("modeswitch");
|
|
|
+ if(heatingMode>=2) heatingMode=0;
|
|
|
+ else heatingMode++;
|
|
|
+ lastMsg = lastMsg + measureinterval; // force update
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
long now = millis();
|
|
|
if (now - lastMsg > measureinterval) {
|
|
|
lastMsg = now;
|
|
@@ -180,46 +291,48 @@ void loop() {
|
|
|
humidity = dht.readHumidity();
|
|
|
temperature = dht.readTemperature(); // Read temperature as Celsius (the default)
|
|
|
|
|
|
- hum_str = String(humidity); //converting humidity (the float variable above) to a string
|
|
|
- hum_str.toCharArray(hum, hum_str.length() + 1); //packaging up the data to publish to mqtt whoa...
|
|
|
+ if (lightMeter_present) {
|
|
|
+ delay(50);
|
|
|
+ lux = lightMeter.readLightLevel();
|
|
|
|
|
|
- temp_str = String(temperature); //converting Temperature (the float variable above) to a string
|
|
|
- temp_str.toCharArray(temp, temp_str.length() + 1); //packaging up the data to publish to mqtt whoa...
|
|
|
+ String lux_str = String(lux, 1); //converting humidity (the float variable above) to a string with 0 decimals
|
|
|
+ char lux_chararr[lux_str.length() + 1];
|
|
|
+ lux_str.toCharArray(lux_chararr, lux_str.length() + 1); //packaging up the data to publish to mqtt whoa...
|
|
|
|
|
|
- char tempstr2[5]; //result string 4 positions + \0 at the end
|
|
|
- //
|
|
|
- // convert float to fprintf type string
|
|
|
- // format 5 positions with 3 decimal places
|
|
|
- //
|
|
|
- dtostrf(temperature, 2, 1, tempstr2 );
|
|
|
+ Serial.print("Lux: ");
|
|
|
+ Serial.println(lux_str);
|
|
|
+ client.publish(mqtt_topic_lux, lux_chararr);
|
|
|
+ }
|
|
|
|
|
|
- char humstr2[3]; //result string 4 positions + \0 at the end
|
|
|
- //
|
|
|
- // convert float to fprintf type string
|
|
|
- // format 5 positions with 3 decimal places
|
|
|
- //
|
|
|
- dtostrf(humidity, 2, 0, humstr2 );
|
|
|
+ String hum_str = String(humidity, 0); //converting humidity (the float variable above) to a string with 0 decimals
|
|
|
+ char hum_chararr[hum_str.length() + 1];
|
|
|
+ hum_str.toCharArray(hum_chararr, hum_str.length() + 1); //packaging up the data to publish to mqtt whoa...
|
|
|
|
|
|
+ String temp_str = String(temperature, 1); //converting Temperature (the float variable above) to a string with 1 decimal
|
|
|
+ char temp_chararr[temp_str.length() + 1];
|
|
|
+ temp_str.toCharArray(temp_chararr, temp_str.length() + 1); //packaging up the data to publish to mqtt whoa...
|
|
|
|
|
|
- //snprintf (msg, 75, "hello world #%ld", value);
|
|
|
- Serial.println("Publish messages temp/hum ");
|
|
|
+ char setTemp_chararr[5]; //result string 4 positions + \0 at the end
|
|
|
+ // convert float to fprintf type string format 2 positions with 1 decimal place
|
|
|
+ dtostrf(setTemp, 2, 1, setTemp_chararr );
|
|
|
|
|
|
- client.publish(mqtt_topic_temp, temp);
|
|
|
- client.publish(mqtt_topic_hum, hum);
|
|
|
+ Serial.println("Publish messages temp/hum ");
|
|
|
|
|
|
- if ( heatingMode == 1 ) targetTemp = targetTempDay;
|
|
|
- else if ( heatingMode == 2 ) targetTemp = targetTempNight;
|
|
|
- else targetTemp = 0;
|
|
|
+ client.publish(mqtt_topic_temp, temp_chararr);
|
|
|
+ client.publish(mqtt_topic_hum, hum_chararr);
|
|
|
|
|
|
- Serial.print("Target temp: ");
|
|
|
- Serial.println(targetTemp);
|
|
|
- Serial.print("Current temp: ");
|
|
|
- Serial.println(temperature);
|
|
|
+ if ( heatingMode == 1 ) setTemp = setTempDay;
|
|
|
+ else if ( heatingMode == 2 ) setTemp = setTempNight;
|
|
|
+ else setTemp = 0;
|
|
|
|
|
|
+ Serial.print("set temp: ");
|
|
|
+ Serial.println(setTemp_chararr);
|
|
|
+ Serial.print("current temp: ");
|
|
|
+ Serial.println(temp_str);
|
|
|
|
|
|
+ lcd.clear();
|
|
|
|
|
|
lcd.setCursor(0, 0);
|
|
|
- //lcd.print("Ist:");
|
|
|
lcd.write(0x3D); // = Zeichen
|
|
|
|
|
|
// if (temperature < -9) lcd.print(" ");
|
|
@@ -227,56 +340,64 @@ void loop() {
|
|
|
// else if (temperature < 10) lcd.print(" ");
|
|
|
// else lcd.print(" ");
|
|
|
|
|
|
- lcd.print(tempstr2);
|
|
|
+ lcd.print(" ");
|
|
|
+
|
|
|
+ //lcd.print(tempstr2);
|
|
|
+ lcd.print(temp_str);
|
|
|
lcd.write(0xDF); // Grad-Symbol
|
|
|
lcd.print(" ");
|
|
|
- lcd.print(humstr2);
|
|
|
- lcd.print("% ");
|
|
|
+ //lcd.print(humstr2);
|
|
|
+ lcd.print(hum_str);
|
|
|
+ lcd.print("% ");
|
|
|
|
|
|
- if (turnHeatingOn) lcd.print("HEIZT");
|
|
|
- else lcd.print(" ");
|
|
|
+ if ( heatingMode == 1 ) lcd.write((uint8_t)1); // Sonne
|
|
|
+ else if ( heatingMode == 2 ) lcd.write((uint8_t)0); // Mond
|
|
|
+ else lcd.print("0");
|
|
|
|
|
|
|
|
|
|
|
|
- char targettempstr[5]; //result string 4 positions + \0 at the end
|
|
|
- //
|
|
|
- // convert float to fprintf type string
|
|
|
- // format 5 positions with 3 decimal places
|
|
|
- //
|
|
|
- dtostrf(targetTemp, 2, 1, targettempstr );
|
|
|
-
|
|
|
lcd.setCursor(0, 1);
|
|
|
//lcd.print("Soll: ");
|
|
|
lcd.write((uint8_t)2); // Pfeil rechts
|
|
|
- lcd.print(targettempstr);
|
|
|
+ lcd.print(" ");
|
|
|
+ lcd.print(setTemp_chararr);
|
|
|
lcd.write(0xDF); // Grad-Symbol
|
|
|
|
|
|
lcd.print(" ");
|
|
|
|
|
|
-// if ( heatingMode == 1 ) lcd.write((uint8_t)1); // Sonne
|
|
|
-// else if ( heatingMode == 2 ) lcd.write((uint8_t)0); // Mond
|
|
|
-// else lcd.write(0x2D); // -
|
|
|
+ // if ( heatingMode == 1 ) lcd.print("Tag ");
|
|
|
+ // else if ( heatingMode == 2 ) lcd.print("Nacht");
|
|
|
+ // else lcd.print("Aus ");
|
|
|
+
|
|
|
+ if (turnHeatingOn) lcd.print("heizen..");
|
|
|
+ else lcd.print(" ");
|
|
|
|
|
|
- if ( heatingMode == 1 ) lcd.print(" Tag");
|
|
|
- else if ( heatingMode == 2 ) lcd.print(" Nacht");
|
|
|
- else lcd.print(" Aus");
|
|
|
|
|
|
// lcd.print(" ");
|
|
|
//
|
|
|
// if(turnHeatingOn) lcd.print("1");
|
|
|
// else lcd.print("0");
|
|
|
|
|
|
- if ( temperature >= targetTemp ) {
|
|
|
+ if ( temperature >= setTemp ) {
|
|
|
turnHeatingOn = false;
|
|
|
Serial.println("heating off");
|
|
|
}
|
|
|
- else if ( temperature < ( targetTemp - hysteresis) ) {
|
|
|
+ else if ( temperature < ( setTemp - hysteresis) ) {
|
|
|
turnHeatingOn = true;
|
|
|
Serial.println("heating on");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
+ // Relais für Heizung ansteuern
|
|
|
+ bool relaisCurrentState = digitalRead(RelaisPin);
|
|
|
+ if ( turnHeatingOn && relaisCurrentState != RelaisOnState ) {
|
|
|
+ digitalWrite(RelaisPin, RelaisOnState);
|
|
|
+ }
|
|
|
+ else if ( !turnHeatingOn && relaisCurrentState == RelaisOnState ) {
|
|
|
+ digitalWrite(RelaisPin, !RelaisOnState);
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
// Check if any reads failed and exit early (to try again).
|
|
|
//if (isnan(hum) || isnan(temp)) {
|