#include "main.h" const char* host = "esp8266"; const char* ssid = "wf-home"; const char* password = "0ndthnrf"; const char* mqtt_server = "192.168.1.250"; //ESP8266WebServer server(80); // инициализируем espClient: WiFiClient espClient; PubSubClient client(espClient); LiquidCrystal_PCF8574 lcd(0x27); // set the LCD address to 0x27 for a 16 chars and 2 line display int nDevs; DeviceAddress da[4] = { {0x28, 0xFF, 0x75, 0x3f, 0x93, 0x16, 0x04, 0xce}, {0x28, 0x85, 0xcd, 0x1b, 0x05, 0x00, 0x00, 0x48}, {0x28, 0xff, 0x79, 0x41, 0x88, 0x16, 0x03, 0x5a}, {0x28, 0x20, 0xbe, 0x1b, 0x05, 0x00, 0x00, 0xdc} }; // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); float temp1, tHolTop, tHolDown, tMoroz; //float hum; float hic; //float temp2; //float pres, bmpTemp; int old_wcC, old_wcH; int adc; float temp[4]; const int led = LED_BUILTIN; const int HOT_SENS = D5; const int COLD_SENS = D6; const int LED_STRIPE = D7; const int LCD_MODE = D8; const int RSET_FLOOD = D4; unsigned long oldRun = millis(); bool Flood = false; TwoWire testWire; PCF857x pcf8574(0x38, &testWire); /*const int MB_LED = 0; const int VLZEM_LED = 1; const int BOX_LED = 2; const int FLOOD_LED = 3; */ //Bounce modeLCD_dbnc = Bounce(); //Bounce hot_dbnc = Bounce(); //Bounce cold_dbnc = Bounce(); //Bounce rset_dbnc = Bounce(); bool bMLCD; short sLCDPage; BME280I2C::Settings settings( BME280::OSR_X1, BME280::OSR_X2, BME280::OSR_X16, BME280::Mode_Normal, BME280::StandbyTime_1000ms, BME280::Filter_16, BME280::SpiEnable_False, BME280I2C::I2CAddr_0x76 // I2C address. I2C specific. ); BME280I2C bme(settings); // Default : forced mode, standby time = 1000 ms // Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off, float temp2(NAN), hum(NAN), pres(NAN); bool movSensor = 0; bool MS = 0; void setup() { Serial.begin(115200); Serial.println("Init LCD"); initLCD(); delay(500); Serial.println("Init BME280"); int nt = 0; while (!bme.begin()) { Serial.println("Could not find a valid BMe280 sensor, check wiring!"); delay(1000); nt++; if (nt > 10) break; } delay(500); Serial.println("Init Temperature"); initTemp(); bme.read(pres, temp2, hum, BME280::TempUnit_Celsius, BME280::PresUnit_torr); pinMode(led, OUTPUT); digitalWrite(led, 1); pinMode(HOT_SENS, INPUT_PULLUP); pinMode(COLD_SENS, INPUT_PULLUP); pinMode(LED_STRIPE, OUTPUT); pinMode(LCD_MODE, INPUT_PULLUP); pinMode(D4, INPUT_PULLUP); //hot_dbnc.attach(HOT_SENS); //hot_dbnc.interval(5); // interval in ms //cold_dbnc.attach(COLD_SENS); //cold_dbnc.interval(5); // interval in ms /*modeLCD_dbnc.attach(LCD_MODE); modeLCD_dbnc.interval(5); // interval in ms rset_dbnc.attach(RSET_FLOOD); rset_dbnc.interval(5); // interval in ms*/ EEPROM.begin(16); //readEEPROM(); //Serial.print("Hot water: "); //Serial.print(float(wcH.i) / 100.0); //Serial.print("Cold water: "); //Serial.println(float(wcC.i) / 100.0); //Serial.print("LS Set: "); //Serial.println(ls.i); //Serial.print("LS DB: "); //Serial.println(ld.i); ls.i = 250; ld.i = 50; //old_wcC = wcC.i; //old_wcH = wcH.i; testWire.begin();//5, 4); testWire.setClock(100000L); pcf8574.begin(); bMLCD = false; readDI(); sLCDPage = 0; initWiFi(); client.setServer(mqtt_server, 1883); client.setCallback(callback); ArduinoOTA.onStart([]() { Serial.println("Start"); // "Начало OTA-апдейта" }); ArduinoOTA.onEnd([]() { Serial.println("\nEnd"); // "Завершение OTA-апдейта" }); ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); }); ArduinoOTA.onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); // "Ошибка при аутентификации" else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); // "Ошибка при начале OTA-апдейта" else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); // "Ошибка при подключении" else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); // "Ошибка при получении данных" else if (error == OTA_END_ERROR) Serial.println("End Failed"); // "Ошибка при завершении OTA-апдейта" }); ArduinoOTA.begin(); } // setup() void loop() { unsigned long curTime = millis(); if ((curTime - oldRun) >= 10){ wCycle(); oldRun = curTime; } //server.handleClient(); ArduinoOTA.handle(); //movSens(); } char strFVal[10]; void wCycle() { static int sec = 0; static short stp = 100; if(stp == 100){ stp = 0; sec++; if (sec == 59){ sec = 0; publishMin(); } getTemp(); publishSec(); } if((stp % 20) == 0){ showLCD(); } if((stp) == 60){ float p, t, h; bme.read(p, t, h, BME280::TempUnit_Celsius, BME280::PresUnit_torr); //if (isnan(pres)) pres = p; //else pres += (p - pres) * 0.05; //if (isnan(temp2)) temp2 = t; //else temp2 += (t - temp2) * 0.05; //if (isnan(hum)) hum = h; //else hum += (h - hum) * 0.05; } readDI(); movSens(); /* if (Flood == true) pcf8574.write(2, LOW); else pcf8574.write(2, HIGH);*/ stp++; } // loop() void movSens() { adc = analogRead(A0); if (MS != pcf8574.read(4)){ MS = pcf8574.read(4); client.publish("/esp8266/move", String(MS).c_str()); } //Dark if ((adc < (ls.i - ld.i)) && MS){ pcf8574.write(5, LOW); //digitalWrite(LED_STRIPE, LOW); } //Light if ((adc > (ls.i + ld.i)) || !MS){ pcf8574.write(5, HIGH); //digitalWrite(LED_STRIPE, HIGH); } if (MS == true) lcd.setBacklight(255); else lcd.setBacklight(0); } void getTemp() { static bool readTemp = false; static byte nSens = 0; if (readTemp){ sensors.setWaitForConversion(false); sensors.requestTemperatures(); readTemp = !readTemp; } else{ //float t = sensors.getTempC(outTemp); float t = sensors.getTempC(da[nSens]);//ByIndex(nSens); Serial.print(nSens); Serial.print(" Temp readed="); Serial.println(t); //to[0] = t; if ((t > -127) && (t < 85)){ switch(nSens){ case 0: temp1 += (t - temp1) * 0.05; break; case 1: tHolTop += (t - tHolTop) * 0.05; break; case 2: tHolDown += (t - tHolDown) * 0.05; break; case 3: tMoroz += (t - tMoroz) * 0.05; break; } } if (++nSens > 3){ nSens = 0; readTemp = !readTemp; } } //n++; } void showLCD() { char outS[16]; String s1, s2; //lcd.clear(); switch (sLCDPage){ case 0: s1 = String(temp1, 1); s2 = String(temp2, 1); snprintf(outS, 17, "O:%5sC I:%4sC ", s1.c_str(), s2.c_str()); lcd.setCursor(0, 0); lcd.print(outS); lcd.setCursor(0, 1); s1 = String(hum, 1); s2 = String(pres, 0); snprintf(outS, 17, "H:%4s%% Pr:%2smm", s1.c_str(), s2.c_str()); lcd.print(outS); break; case 1: snprintf(outS, 17, "L:%04d SP:%03d %d ", adc, ls.i, ld.i); lcd.setCursor(0, 0); lcd.print(outS); lcd.setCursor(0, 1); s1 = String(hum, 1); s2 = String(hic, 1); snprintf(outS, 17, "H:%4s%% HI:%4sC ", s1.c_str(), s2.c_str()); lcd.print(outS); break; case 2: snprintf(outS, 17, "L:%04d SP:%03d %d", adc, ls.i, ld.i); lcd.setCursor(0, 0); lcd.print(outS); lcd.setCursor(0, 1); snprintf(outS, 17, "C:%03.2fH:%03.2f", float(wcC.i) / 100.0, float(wcH.i) / 100.0); lcd.print(outS); break; case 3: s1 = String(temp1, 1); s2 = String(tMoroz, 1); snprintf(outS, 17, "O:%4sC M:%4sC ", s1.c_str(), s2.c_str()); lcd.setCursor(0, 0); lcd.print(outS); lcd.setCursor(0, 1); s1 = String(tHolTop, 1); s2 = String(tHolDown, 1); snprintf(outS, 17, "H:%4sC HM:%4sC", s1.c_str(), s2.c_str()); lcd.print(outS); break; } } void initLCD(){ int error; Serial.println("LCD..."); Serial.println("Dose: check for LCD"); // See http://playground.arduino.cc/Main/I2cScanner Wire.begin(); Wire.beginTransmission(0x38); error = Wire.endTransmission(); Serial.print("Error: "); Serial.print(error); if (error == 0) { Serial.println(": LCD found."); } else { Serial.println(": LCD not found."); } // if lcd.begin(16, 2); // initialize the lcd lcd.setBacklight(255); lcd.clear(); } /*void handleRoot() { digitalWrite ( led, 0 ); char temp[400]; int sec = millis() / 1000; int min = sec / 60; int hr = min / 60; snprintf ( temp, 400, "\ \ \ ESP8266 Demo\ \ \ \

Hello from ESP8266!

\

Uptime: %02d:%02d:%02d

\ \ ", hr, min % 60, sec % 60 ); server.send ( 200, "text/html", temp ); //digitalWrite ( led, 1 ); }*/ /*void handleNotFound() { // digitalWrite ( led, 0 ); String message = "File Not Found\n\n"; message += "URI: "; message += server.uri(); message += "\nMethod: "; message += ( server.method() == HTTP_GET ) ? "GET" : "POST"; message += "\nArguments: "; message += server.args(); message += "\n"; // message += test().c_str(); for ( uint8_t i = 0; i < server.args(); i++ ) { message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n"; } server.send ( 404, "text/plain", message ); //digitalWrite ( led, 1 ); }*/ /*void handleJSON() { //digitalWrite ( led, 0 ); pcf8574.write(7, LOW); // Allocate JsonBuffer // Use arduinojson.org/assistant to compute the capacity. StaticJsonBuffer<500> jsonBuffer; // Create the root object JsonObject& root = jsonBuffer.createObject(); root.set("temp1", temp1); root.set("temp2", temp2); root.set("press", pres); root.set("hum", hum); root.set("vlzem", 0.0); root.set("qc", float(wcC.i) / 100.0); root.set("qh", float(wcH.i) / 100.0); root.set("sp", ls.i); root.set("db", ld.i); root.set("vlsp", adc); root.set("flood", Flood); // Create the "analog" array String s; root.printTo(s); server.send(200, "application/json", s); pcf8574.write(7, HIGH); //digitalWrite ( led, 0 ); }*/ /*void handleData() { //String inArgs = ""; char temp[100]; char tm[3]; String html; pcf8574.write(7, LOW); int sec = millis() / 1000; int min = sec / 60; int hr = min / 60; if (server.args() > 0){ for (int i = 0; i < server.args(); i++) { if (server.argName(i).equals("wcc")){ wcC.i = int(server.arg(i).toFloat() * 100.0f); writeEEPROM("cc", wcC); //inArgs += "

Write to wcc value: " + server.arg(i) + "

"; } if (server.argName(i).equals("wch")){ wcH.i = int(server.arg(i).toFloat() * 100.0f) ; writeEEPROM("ch", wcH); //inArgs += "

Write to wcc value: " + server.arg(i) + "

"; } if (server.argName(i).equals("ls_set")){ ls.i = server.arg(i).toInt(); writeEEPROM("ls", ls); } if (server.argName(i).equals("ls_db")){ ld.i = server.arg(i).toInt(); writeEEPROM("ld", ld); } } } html = ""; html += ""; html += ""; html += "ESP8266 Demo"; html += ""; html += ""; html += ""; html += "

Hello from ESP8266!

"; snprintf(tm, 3, "%02d", hr); html += "

Uptime: " + String(tm); snprintf(tm, 3, "%02d", min % 60); html += ":" + String(tm); snprintf(tm, 3, "%02d", sec % 60); html += ":" + String(tm) + String("

"); sprintf(temp, "

Cold Water: %6.2f m3

Hot Water: %6.2f m3

Temp: %3.3fC

LSet: %d, LDB: %d

", float(wcC.i) / 100.0, float(wcH.i) / 100.0, temp1, ls.i, ld.i); html += String(temp); html += ""; server.send ( 200, "text/html", html ); pcf8574.write(7, HIGH); }*/ void initWiFi() { //WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); if(WiFi.waitForConnectResult() == WL_CONNECTED){ delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); if (MDNS.begin(host)) { Serial.println("MDNS responder started"); } /*server.on ("/", handleData); server.on("/data", handleData); server.on("/json", handleJSON); server.on ("/inline", []() { server.send ( 200, "text/plain", "this works as well" ); } ); server.onNotFound ( handleNotFound ); server.begin(); Serial.println ( "HTTP server started" );*/ Serial.println("Ready"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void initTemp() { //DeviceAddress da[4]; sensors.begin(); Serial.println("InitTemp"); //oneWire.reset_search(); for (int i = 0; i < 4; i++){ //sensors.getAddress(da[i], i); sensors.setResolution(da[i], 12); //printAddress(da[i]); } //sensors.getAddress(outTemp, 0); //sensors.setResolution(outTemp, 12); sensors.setWaitForConversion(true); sensors.requestTemperatures(); Serial.println("Request Temp"); /*printAddress(outTemp); printAddress(holTop); printAddress(holDown); printAddress(moroz);*/ temp1 = sensors.getTempC(da[0]); Serial.println(temp1); tHolTop = sensors.getTempC(da[1]); Serial.println(tHolTop); tHolDown = sensors.getTempC(da[2]); Serial.println(tHolDown); tMoroz = sensors.getTempC(da[3]); Serial.println(tMoroz); /*delay(100); tHolTop = sensors.getTempCByIndex(1); delay(100); tHolDown = sensors.getTempCByIndex(2); delay(100); tMoroz = sensors.getTempCByIndex(0);*/ } /*void readEEPROM() { wcC.b[0] = EEPROM.read(0); wcC.b[1] = EEPROM.read(1); wcC.b[2] = EEPROM.read(2); wcC.b[3] = EEPROM.read(3); wcH.b[0] = EEPROM.read(4); wcH.b[1] = EEPROM.read(5); wcH.b[2] = EEPROM.read(6); wcH.b[3] = EEPROM.read(7); ls.b[0] = EEPROM.read(8); ls.b[1] = EEPROM.read(9); ls.b[2] = EEPROM.read(10); ls.b[3] = EEPROM.read(11); ld.b[0] = EEPROM.read(12); ld.b[1] = EEPROM.read(13); ld.b[2] = EEPROM.read(14); ld.b[3] = EEPROM.read(15); }*/ /*void writeEEPROM(const char tip[2], uFloat val) { short shft = -1; if (strcmp(tip, "cc") == 0) { shft = 0; //Serial.print("Write cold counter: "); //Serial.println(val.f); } if (strcmp(tip, "ch") == 0) { shft = 4; //Serial.print("Write Hot counter: "); //Serial.println(val.f); } if (strcmp(tip, "ls") == 0) { shft = 8; //Serial.print("Light Sensor Set: "); //Serial.println(val.i); } if (strcmp(tip, "ld") == 0) { shft = 12; //Serial.print("Light Sensor DB: "); //Serial.println(val.i); } if (shft == -1) return; EEPROM.write(shft, val.b[0]); EEPROM.write(shft + 1, val.b[1]); EEPROM.write(shft + 2, val.b[2]); EEPROM.write(shft + 3, val.b[3]); EEPROM.commit(); }*/ void readDI() { /*if (hot_dbnc.update()){ if (hot_dbnc.read() == 1){ wcH.i += 1; //wcH.f += 0.01; if (fabs(old_wcH - wcH.i) >= 5){ writeEEPROM("ch", wcH); old_wcH = wcH.i; } } } if (cold_dbnc.update()){ if (cold_dbnc.read() == 1) wcC.i += 1; if (fabs(old_wcC - wcC.i) >= 5){ writeEEPROM("cc", wcC); old_wcC = wcC.i; } } if (!pcf8574.read(6)) Flood = true; if (!pcf8574.read(0)) Flood = false;*/ if (pcf8574.read(1) != bMLCD){ if (bMLCD == false){ sLCDPage++; if (sLCDPage > 3) sLCDPage = 0; } bMLCD = !bMLCD; } } void callback(String topic, byte* message, unsigned int length) { Serial.print("Message arrived on topic: "); // "Сообщение прибыло в топик: " Serial.print(topic); Serial.print(". Message: "); // ". Сообщение: " String messageTemp; for (unsigned int i = 0; i < length; i++) { Serial.print((char)message[i]); messageTemp += (char)message[i]; } Serial.println(); } void reconnect() { // заново запускаем цикл, пока не подключимся: //while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // "Попытка подключиться к MQTT-брокеру... " // Пытаемся подключиться: if (client.connect("ESP8266Client")) { Serial.println("connected"); // "подключен" // подписываемся или переподписываемся на топик; // можно подписаться не только на один, а на несколько топиков // (что касается конкретно этого примера, то это позволит // управлять большим количеством светодиодов): //client.subscribe("esp8266/qc"); //client.subscribe("esp8266/qh"); } else { Serial.print("failed, rc="); // "подключение не удалось" Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // "5 секунд до следующей попытки" // ждем 5 секунд перед тем, как попробовать снова: //delay(5000); } //} } void printAddress(DeviceAddress deviceAddress) { for (uint8_t i = 0; i < 8; i++) { // zero pad the address if necessary if (deviceAddress[i] < 16) Serial.print("0"); Serial.print(deviceAddress[i], HEX); } Serial.println(); } void publishSec() { if (!client.connected()) { reconnect(); } if(!client.loop()) client.connect("ESP8266Client"); if (client.connected()) { pcf8574.write(3, LOW); dtostrf(temp1, 6, 2, strFVal); client.publish("/esp8266/temp_out", strFVal); dtostrf(temp2, 6, 2, strFVal); client.publish("/esp8266/temp_in", strFVal); dtostrf(hum, 6, 2, strFVal); client.publish("/esp8266/humidity", strFVal); dtostrf(pres, 6, 2, strFVal); client.publish("/esp8266/pressure", strFVal); dtostrf(float(wcC.i) / 100.0, 6, 2, strFVal); /*client.publish("/esp8266/qCold", strFVal); dtostrf(float(wcH.i) / 100.0, 6, 2, strFVal); client.publish("/esp8266/qHot", strFVal); itoa(ls.i, strFVal, 10);*/ client.publish("/esp8266/light_sp", strFVal); itoa(ld.i, strFVal, 10); client.publish("/esp8266/light_db", strFVal); itoa(adc, strFVal, 10); client.publish("/esp8266/light_cur", strFVal); //client.publish("/esp8266/flood", String(Flood).c_str()); dtostrf(tHolTop, 6, 2, strFVal); client.publish("/esp8266/hol_top", strFVal); dtostrf(tHolDown, 6, 2, strFVal); client.publish("/esp8266/hol_down", strFVal); dtostrf(tMoroz, 6, 2, strFVal); client.publish("/esp8266/moroz", strFVal); pcf8574.write(3, HIGH); } } void publishMin() { if (!client.connected()) { reconnect(); } if(!client.loop()) client.connect("ESP8266Client"); if (client.connected()) { pcf8574.write(7, LOW); dtostrf(temp1, 6, 1, strFVal); client.publish("/home/kuh/temp_out", strFVal); dtostrf(temp2, 6, 1, strFVal); client.publish("/home/kuh/temp_in", strFVal); dtostrf(hum, 6, 1, strFVal); client.publish("/home/kuh/humidity", strFVal); dtostrf(pres, 6, 1, strFVal); client.publish("/home/kuh/pressure", strFVal); itoa(ls.i, strFVal, 10); client.publish("/home/kuh/light_sp", strFVal); itoa(ld.i, strFVal, 10); client.publish("/home/kuh/light_db", strFVal); itoa(adc, strFVal, 10); client.publish("/home/kuh/light_cur", strFVal); dtostrf(tHolTop, 6, 1, strFVal); client.publish("/home/kuh/hol_top", strFVal); dtostrf(tHolDown, 6, 1, strFVal); client.publish("/home/kuh/hol_down", strFVal); dtostrf(tMoroz, 6, 1, strFVal); client.publish("/home/kuh/moroz", strFVal); pcf8574.write(7, HIGH); } }