First commit

This commit is contained in:
2020-08-01 13:47:02 +03:00
commit ac18805ff4
142 changed files with 8325 additions and 0 deletions

780
esp8266-KUH/src/main.cpp Normal file
View File

@@ -0,0 +1,780 @@
#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,
"<html>\
<head>\
<meta http-equiv='refresh' content='5'/>\
<title>ESP8266 Demo</title>\
<style>\
body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
</style>\
</head>\
<body>\
<h1>Hello from ESP8266!</h1>\
<p>Uptime: %02d:%02d:%02d</p>\
</body>\
</html>",
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<float>("temp1", temp1);
root.set<float>("temp2", temp2);
root.set<float>("press", pres);
root.set<float>("hum", hum);
root.set<float>("vlzem", 0.0);
root.set<float>("qc", float(wcC.i) / 100.0);
root.set<float>("qh", float(wcH.i) / 100.0);
root.set<float>("sp", ls.i);
root.set<float>("db", ld.i);
root.set<int>("vlsp", adc);
root.set<bool>("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 += "<p>Write to wcc value: " + server.arg(i) + "</p>";
}
if (server.argName(i).equals("wch")){
wcH.i = int(server.arg(i).toFloat() * 100.0f) ;
writeEEPROM("ch", wcH);
//inArgs += "<p>Write to wcc value: " + server.arg(i) + "</p>";
}
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 += "<head>";
html += "<meta http-equiv='refresh' content='5'/>";
html += "<title>ESP8266 Demo</title>";
html += "<style>body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }</style>";
html += "</head>";
html += "<body>";
html += "<h1>Hello from ESP8266!</h1>";
snprintf(tm, 3, "%02d", hr);
html += "<p>Uptime: " + String(tm);
snprintf(tm, 3, "%02d", min % 60);
html += ":" + String(tm);
snprintf(tm, 3, "%02d", sec % 60);
html += ":" + String(tm) + String("</p>");
sprintf(temp, "<p>Cold Water: %6.2f m3</p><p>Hot Water: %6.2f m3</p><p>Temp: %3.3fC</p><p>LSet: %d, LDB: %d</p>", float(wcC.i) / 100.0, float(wcH.i) / 100.0, temp1, ls.i, ld.i);
html += String(temp);
html += "</body></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);
}
}