summaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp484
1 files changed, 484 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..390a297
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,484 @@
+/*
+ Система контроля температуры для управления котлом
+ * СЕРВЕР * = vlapa = 20221127 - 20231130
+ v.017
+*/
+#include <Arduino.h>
+#include <OneWire.h>
+#include <DallasTemperature.h>
+#include <EEPROM.h>
+#define ONE_WIRE_BUS 2
+OneWire oneWire(ONE_WIRE_BUS);
+DallasTemperature sensors(&oneWire);
+
+#include <WiFi.h>
+// #include <WebServer.h>
+// #include <HTTPUpdateServer.h>
+#include <PubSubClient.h>
+
+//-----------------------------------
+// const char *ssid = "TP-Link_77C4";
+// const char *pass = "14697272";
+// const char *mqtt_client = "GasBoilerServer_Maxx";
+// const char *mqtt_client2 = "GasBoiler_Maxx";
+
+const char *ssid = "MikroTik-2";
+const char *pass = "dkfgf#*12091997";
+const char *mqtt_client = "mqtt_client-esp32-c3_001";
+const char *mqtt_client2 = "GasBoiler_Villa";
+
+// const char *ssid = "link";
+// const char *pass = "dkfgf#*12091997";
+// const char *mqtt_client = "mqtt_client-011";
+// const char *mqtt_client2 = "GasBoiler_TEST";
+
+const char *mqtt_user = "mqtt";
+const char *mqtt_pass = "qwe#*1243";
+const char *mqtt_server = "178.20.46.157";
+const uint16_t mqtt_port = 1883;
+
+const char *inTopicTempRoom = "/Temp_Room";
+const char *inTopicTempDS18b20 = "/Room_ds18b20";
+const char *inTopicTempDHT11_1 = "/Room_dht11_1";
+const char *inTopicTempDHT11_2 = "/Room_dht11_2";
+const char *inTopicReboot = "/Reboot";
+const char *outTopicIP = "/IP_Boiler";
+const char *outTopicRSSI = "/RSSI_Boiler";
+const char *outTopicHeating = "/Heating";
+const char *outTopicTempDS18b20 = "/Kotel_ds18b20";
+const char *outTopicUpTime = "/UpTime";
+const char *outTopicReconnectTime = "/ReconnectTime";
+const char *outTopicHeap = "/Heap";
+
+const uint8_t sensorNumRoom_1 = 99; // 1 номер датчика температуры комнаты
+const uint8_t sensorNumRoom_2 = 11; // 2 номер датчика температуры комнаты
+const uint8_t sensorNumRoom_3 = 21; // 3 номер датчика температуры комнаты
+const uint8_t pinReley = 0;
+const uint8_t pinDS18b20 = 2;
+int16_t quality_RSSI = 0;
+
+float temperRoom = 0.0;
+float dataTempBase = 23.0; // температура в комнате по умолчанию
+float dataTempKotel = 60.0; // температура теплоносителя по умолчанию
+float temperRoom_ds18b20 = 0.0;
+String temperRoom_dht11_1 = "___";
+String temperRoom_dht11_2 = "___";
+float temperBoiler_ds18b20 = 0.0;
+uint32_t millisOld = 0;
+uint32_t millisOldReconnect = 0;
+uint32_t millisReconnect = 0;
+uint32_t pauseTimeTemp = 30000;
+float gisteresis = 0.1;
+bool conditionHeater = true;
+float k = 0.1; // коэффициент фильтрации, 0.0-1.0
+
+WiFiClient espClient;
+PubSubClient client(espClient);
+
+// WebServer server(80);
+// HTTPUpdateServer httpUpdater;
+
+//-----------------------------------
+String timeCalc(uint32_t t)
+{
+ uint32_t timer = t / 1000;
+ uint32_t timeSec = (timer % 3600) % 60;
+ uint32_t timeMin = (timer % 3600) / 60;
+ uint32_t timeHour = timer / 3600 % 24;
+ uint32_t timeDay = timer / 60 / 60 / 24;
+
+ String s = "";
+ s += timeDay;
+ s += ":";
+ if (timeHour < 10)
+ s += "0";
+ s += timeHour;
+ s += ":";
+ if (timeMin < 10)
+ s += "0";
+ s += timeMin;
+ s += ":";
+ if (timeSec < 10)
+ s += "0";
+ s += timeSec;
+
+ return s;
+}
+
+//-----------------------------------
+inline bool mqtt_subscribe(PubSubClient &client, const String &topic)
+{
+ Serial.print("Subscribing to: ");
+ Serial.println(topic);
+ return client.subscribe(topic.c_str());
+}
+
+//-----------------------------------
+inline bool mqtt_publish(PubSubClient &client, const String &topic, const String &value)
+{
+ Serial.print("Publishing topic ");
+ Serial.print(topic);
+ Serial.print(" = ");
+ Serial.println(value);
+ return client.publish(topic.c_str(), value.c_str());
+}
+
+//-----------------------------------
+void mqttReconnectOut()
+{
+ String topic = "/";
+ topic += mqtt_client2;
+ topic += outTopicIP;
+ mqtt_publish(client, topic, WiFi.localIP().toString());
+
+ topic = "/";
+ topic += mqtt_client2;
+ topic += outTopicRSSI;
+ mqtt_publish(client, topic, (String)quality_RSSI + '%');
+
+ topic = "/";
+ topic += mqtt_client2;
+ topic += inTopicReboot;
+ mqtt_publish(client, topic, "0");
+}
+
+//-----------------------------------
+void mqttDataOut()
+{
+ String topic = "/";
+ topic += mqtt_client2;
+ topic += outTopicHeating;
+ mqtt_publish(client, topic, (!conditionHeater) ? "OFF" : "ON");
+
+ topic = "/";
+ topic += mqtt_client2;
+ topic += outTopicTempDS18b20;
+ mqtt_publish(client, topic, (String)temperBoiler_ds18b20);
+
+ topic = "/";
+ topic += mqtt_client2;
+ topic += inTopicTempRoom;
+ mqtt_publish(client, topic, (String)temperRoom);
+
+ topic = "/";
+ topic += mqtt_client2;
+ topic += inTopicTempDS18b20;
+ mqtt_publish(client, topic, (String)temperRoom_ds18b20);
+
+ topic = "/";
+ topic += mqtt_client2;
+ topic += outTopicUpTime;
+ mqtt_publish(client, topic, timeCalc(millis()));
+
+ // topic = "/";
+ // topic += mqtt_client2;
+ // topic += outTopicReconnectTime;
+ // mqtt_publish(client, topic, timeCalc(millisReconnect));
+
+ topic = "/";
+ topic += mqtt_client2;
+ topic += inTopicTempDHT11_1;
+ mqtt_publish(client, topic, temperRoom_dht11_1);
+
+ topic = "/";
+ topic += mqtt_client2;
+ topic += inTopicTempDHT11_2;
+ mqtt_publish(client, topic, temperRoom_dht11_2);
+
+ // String heap_data = "";
+ // heap_data += (conditionHeater) ? 30 : 27;
+ // heap_data += ",";
+ // heap_data += temperBoiler_ds18b20;
+ // heap_data += ",";
+ // heap_data += temperRoom;
+ // heap_data += ",";
+ // heap_data += temperRoom_ds18b20;
+ // heap_data += ",";
+ // heap_data += temperRoom_dht11_1;
+ // heap_data += ",";
+ // heap_data += temperRoom_dht11_2;
+ // topic = "/";
+ // topic += mqtt_client2;
+ // topic += outTopicHeap;
+ // mqtt_publish(client, topic, heap_data);
+}
+
+//-----------------------------------
+bool reconnect()
+{
+ Serial.print("MQTT connect : ");
+ Serial.println(mqtt_server);
+ uint8_t countMQTT = 20;
+ while (!(client.connect(mqtt_client, mqtt_user, mqtt_pass)) && countMQTT--)
+ {
+ Serial.print(countMQTT);
+ Serial.print('>');
+ delay(500);
+ }
+ if (client.connected())
+ {
+ Serial.println("MQTT connected - OK !");
+
+ String topic = "/";
+ topic += mqtt_client2;
+ topic += inTopicTempRoom;
+ mqtt_subscribe(client, topic);
+
+ // topic = "/";
+ // topic += mqtt_client2;
+ // topic += inTopicTempDS18b20;
+ // mqtt_subscribe(client, topic);
+
+ topic = "/";
+ topic += mqtt_client2;
+ topic += inTopicReboot;
+ mqtt_subscribe(client, topic);
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//-----------------------------------
+bool setupWiFi(const char *wifi_ssid, const char *wifi_pass)
+{
+ digitalWrite(LED_BUILTIN, LOW); // включаем светодиод
+ Serial.print("\n\nSetup WiFi: ");
+ Serial.println(ssid);
+ WiFi.mode(WIFI_STA);
+ uint8_t countWiFi = 20; // кол-во попыток соединения
+ uint8_t countPause = 500; // пауза между попытками
+ WiFi.begin(wifi_ssid, wifi_pass);
+ while ((WiFi.status() != WL_CONNECTED) && countWiFi--)
+ {
+ Serial.print(countWiFi);
+ Serial.print('>');
+ delay(countPause);
+ }
+ digitalWrite(LED_BUILTIN, HIGH); // выключаем светодиод
+
+ if (WiFi.status() == WL_CONNECTED)
+ {
+ // индикация IP
+ Serial.print("\nWiFi connected - OK !\n");
+ Serial.println(WiFi.localIP());
+ // индикация силы сигнала
+ int16_t dBm = WiFi.RSSI();
+ Serial.print("RSSI dBm = ");
+ Serial.println(dBm);
+ quality_RSSI = 2 * (dBm + 100);
+ if (quality_RSSI >= 100)
+ quality_RSSI = 100;
+ Serial.print("RSSI % = ");
+ Serial.println(quality_RSSI);
+ Serial.println();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//-----------------------------------
+void releWork()
+{
+ if ((temperRoom - gisteresis) > temperRoom_ds18b20)
+ {
+ conditionHeater = true;
+ digitalWrite(pinReley, conditionHeater);
+ }
+ else if ((temperRoom + gisteresis) < temperRoom_ds18b20)
+ {
+ conditionHeater = false;
+ digitalWrite(pinReley, conditionHeater);
+ }
+ // if ((WiFi.status() == WL_CONNECTED) && client.connected())
+ // {
+ // String topic = "/";
+ // topic += mqtt_client2;
+ // topic += outTopicHeating;
+ // mqtt_publish(client, topic, (!conditionHeater) ? "OFF" : "ON");
+ // }
+}
+
+//-----------------------------------
+void mqtt_callback(char *topic, byte *payload, unsigned int length)
+{
+ // for (uint8_t i = 0; i < length; i++)
+ // {
+ // Serial.print((char)payload[i]);
+ // }
+ // Serial.println();
+ String temp = "";
+
+ char *topicBody = topic + strlen(mqtt_client2) + 1;
+ if (!strncmp(topicBody, inTopicReboot, strlen(inTopicReboot)))
+ {
+ for (uint8_t i = 0; i < length; i++)
+ temp += (char)payload[i];
+ if (temp.toInt())
+ {
+ ESP.restart();
+ Serial.println("REBOOT !");
+ }
+ }
+ if (!strncmp(topicBody, inTopicTempRoom, strlen(inTopicTempRoom)))
+ {
+ for (uint8_t i = 0; i < length; i++)
+ temp += (char)payload[i];
+ temperRoom = temp.toFloat();
+
+ byte raw[4];
+ (float &)raw = temperRoom;
+ for (byte i = 0; i < 4; i++)
+ EEPROM.write(0 + i, raw[i]);
+ EEPROM.commit();
+
+ Serial.print("TempRoom: ");
+ Serial.print(temperRoom);
+ Serial.print("\t");
+ Serial.println(millis() / 1000);
+ releWork();
+ }
+ // if (!strncmp(topicBody, inTopicTempDS18b20, strlen(inTopicTempDS18b20)))
+ // {
+ // for (uint8_t i = 0; i < length; i++)
+ // temp += (char)payload[i];
+ // temperRoom_ds18b20 = temp.toFloat();
+
+ // Serial.print("TempDs18b20: ");
+ // Serial.println(temperRoom_ds18b20);
+ // }
+}
+
+//-----------------------------------
+// бегущее среднее
+float expRunningAverage(float newVal)
+{
+ static float filVal = 0;
+ filVal += (newVal - filVal) * k;
+ return filVal;
+}
+
+// медиана на 3 значения со своим буфером
+float medianRoom(float newValRoom)
+{
+ static float bufRoom[3] = {0, 0, 0};
+ if (!(bufRoom[0] + bufRoom[1] + bufRoom[2]))
+ bufRoom[0] = bufRoom[1] = bufRoom[2] = newValRoom;
+ static byte countRoom = 0;
+ bufRoom[countRoom] = newValRoom;
+ if (++countRoom >= 3)
+ countRoom = 0;
+ float dataRoom = (max(bufRoom[0], bufRoom[1]) == max(bufRoom[1], bufRoom[2]))
+ ? max(bufRoom[0], bufRoom[2])
+ : max(bufRoom[1], min(bufRoom[0], bufRoom[2]));
+ // return expRunningAverage(data);
+ return dataRoom;
+}
+
+float medianBoiler(float newValBoiler)
+{
+ static float bufBoiler[3] = {0, 0, 0};
+ if (!(bufBoiler[0] + bufBoiler[1] + bufBoiler[2]))
+ bufBoiler[0] = bufBoiler[1] = bufBoiler[2] = newValBoiler;
+ static byte countBoiler = 0;
+ bufBoiler[countBoiler] = newValBoiler;
+ if (++countBoiler >= 3)
+ countBoiler = 0;
+ float dataBoiler = (max(bufBoiler[0], bufBoiler[1]) == max(bufBoiler[1], bufBoiler[2]))
+ ? max(bufBoiler[0], bufBoiler[2])
+ : max(bufBoiler[1], min(bufBoiler[0], bufBoiler[2]));
+ // return expRunningAverage(data);
+ return dataBoiler;
+}
+
+//-----------------------------------
+void setup()
+{
+ Serial.begin(9600);
+ Serial.setTimeout(100);
+ pinMode(pinReley, OUTPUT);
+ digitalWrite(pinReley, LOW);
+ // pinMode(pinDS18b20, OUTPUT);
+ // digitalWrite(pinDS18b20, HIGH);
+
+ client.setServer(mqtt_server, mqtt_port);
+ client.setCallback(mqtt_callback);
+
+ EEPROM.begin(4);
+ byte raw[4];
+ for (byte i = 0; i < 4; i++)
+ raw[i] = EEPROM.read(0 + i);
+ float &num = (float &)raw;
+ (num >= 10.0 && num <= 30.0) ? temperRoom = num : temperRoom = dataTempBase;
+
+ // server.begin();
+ // httpUpdater.setup(&server);
+}
+
+//-----------------------------------
+void loop()
+{
+ if ((WiFi.status() != WL_CONNECTED) || !client.connected())
+ {
+ if (setupWiFi(ssid, pass))
+ if (reconnect())
+ {
+ mqttReconnectOut();
+ // millisReconnect = millis() - millisOldReconnect;
+ // millisOldReconnect = millis();
+ millisOld = millis() - pauseTimeTemp;
+ }
+ }
+
+ //-----------------------------------
+ if (Serial.available())
+ {
+ String bufString = Serial.readString(); // читаем как строку
+ uint8_t num_room_sensor = bufString.substring(0, 2).toInt();
+
+ if (num_room_sensor == sensorNumRoom_1)
+ {
+ temperRoom_ds18b20 = bufString.substring(3, 8).toFloat(); // medianRoom(bufString.substring(3, 8).toFloat());
+ }
+ else if (num_room_sensor == sensorNumRoom_2)
+ {
+ temperRoom_dht11_1 = bufString.substring(2, 15);
+ }
+ else if (num_room_sensor == sensorNumRoom_3)
+ {
+ temperRoom_dht11_2 = bufString.substring(2, 15);
+ }
+ }
+ //---------------------------------------------
+ if (millis() >= millisOld + pauseTimeTemp)
+ {
+ sensors.requestTemperatures();
+ temperBoiler_ds18b20 = sensors.getTempCByIndex(0); // medianBoiler(sensors.getTempCByIndex(0));
+
+ if (dataTempKotel <= temperBoiler_ds18b20)
+ {
+ conditionHeater = true;
+ digitalWrite(pinReley, conditionHeater);
+ }
+ else
+ {
+ releWork();
+ }
+
+ if ((WiFi.status() == WL_CONNECTED) && client.connected())
+ mqttDataOut();
+
+ millisOld = millis();
+ }
+
+ //---------------------------------------------
+ // server.handleClient();
+ client.loop();
+ delay(1);
+} \ No newline at end of file