From efb921063db84c433d5b8d0fbfc72a5310253cd4 Mon Sep 17 00:00:00 2001 From: vlapa Date: Sat, 13 Jun 2026 22:12:51 +0300 Subject: First --- .gitignore | 6 + platformio.ini | 27 ++++ src/main.cpp | 395 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 428 insertions(+) create mode 100644 .gitignore create mode 100644 platformio.ini create mode 100644 src/main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..47fc253 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.pio +.vscode/ +include/ +lib/ +test/ +setenv.h diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..d143ed7 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,27 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +; [env:esp32-c3-devkitm-1] +; platform = espressif32 +; board = esp32-c3-devkitm-1 + +[env:esp32-c3-devkitc-02] +platform = espressif32 +board = esp32-c3-devkitc-02 + +framework = arduino + +monitor_speed = 115200 +upload_speed = 921600 ;460800 ; + +lib_deps = + adafruit/Adafruit BME280 Library + knolleary/PubSubClient + milesburton/DallasTemperature \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..cbbb916 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,395 @@ +#include +#include +#include +#include + +#include +#include +const uint8_t wire_bus = 1; +OneWire oneWire(wire_bus); + +DallasTemperature DS18B20(&oneWire); + +#include +TwoWire i2cBME280 = TwoWire(0); +Adafruit_BME280 bme; + +#include "setenv.h" + +const uint8_t i2c_SDA = 0; +const uint8_t i2c_SCL = 1; + +const uint8_t pinBMEminus = 3; // питание датчика - +const uint8_t pinBMEplus = 19; // питание датчика + +const uint8_t pinVcc = 4; // напряжение батареи + +WiFiClient espClient; +PubSubClient client(espClient); + +//------------------------------------------------ +const char *ssid = WiFi_SSID; +const char *pass = WiFi_PASS; + +const char *mqtt_client = MQTT_CLIENT_N; +const char *mqtt_client2 = MQTT_CLIENT_T; +const char *mqtt_user = MQTT_USER; +const char *mqtt_pass = MQTT_PASS; +const char *mqtt_server = MQTT_SERVER; +const char *mqtt_port = MQTT_PORT; + +const char *outTopicData = "/t;p;h;v;"; // для BME280 +// const char *outTopicData = "/t;"; // для DS18B20 +// const char *outTopicData_v = "/v;"; // для всех + +//------------------------------------------------ +uint8_t countConnect = 20; // кол-во попыток соединения +uint16_t countPause = 500; // пауза между попытками +uint32_t timeSleep = 60000000; // время сна (60s) +uint16_t TimeBeforeBedtime = 500; // время до засыпания +uint8_t countMaxSleep = 120; // не передавать данные не более + // countMaxSleep х timeSleep (60мин) + +RTC_DATA_ATTR struct +{ + float t = 0; + uint16_t p = 0; + uint16_t h = 0; + float v = 0; + uint8_t countSleep = 0; +} data; + +float diffTemp = 0.25; // разница температур +int8_t diffPres = 3; // разница давлений +int8_t diffHum = 5; // разница влажностей +float diffVcc = 0.1; // разница зарядки акб + +RTC_DATA_ATTR bool flagNotWork = false; + +//----------------------------------- +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(topic); + Serial.print(" = "); + Serial.println(value); + return client.publish(topic.c_str(), value.c_str()); +} + +//----------------------------------- +void mqttDataOut() +{ + String topic, topicValue; + + topic = "/"; + topic += mqtt_client2; + topic += outTopicData; + topicValue = ""; + topicValue += data.t; + topicValue += ";"; + topicValue += data.p; + topicValue += ";"; + topicValue += data.h; + topicValue += ";"; + topicValue += data.v; + topicValue += ";"; + + while (!mqtt_publish(client, topic, topicValue)) + { + mqtt_publish(client, topic, topicValue); + } + + // topic = "/"; + // topic += mqtt_client2; + // topic += outTopicData_v; + + // topicValue = ""; + // topicValue += data.v; + // topicValue += ";"; + + // while (!mqtt_publish(client, topic, topicValue)) + // { + // mqtt_publish(client, topic, topicValue); + // } +} + +//----------------------------------- +bool reconnect() +{ + client.setServer(mqtt_server, String(mqtt_port).toInt()); + + Serial.print("MQTT connect : "); + Serial.println(mqtt_server); + + while (!(client.connect(mqtt_client, mqtt_user, mqtt_pass)) && countConnect--) + { + Serial.print(countConnect); + Serial.print('>'); + delay(countPause); + } + + if (client.connected()) + { + Serial.println("MQTT connected - OK !"); + return true; + } + else + { + return false; + } +} + +//----------------------------------- +bool setupWiFi(const char *wifi_ssid, const char *wifi_pass) +{ + WiFi.begin(wifi_ssid, wifi_pass); + + Serial.print("Setup WiFi: "); + Serial.println(ssid); + + while ((WiFi.status() != WL_CONNECTED) && countConnect--) + { + Serial.print(countConnect); + Serial.print('>'); + delay(countPause); + } + + if (WiFi.status() == WL_CONNECTED) + { + // индикация IP + Serial.print("\nWiFi connected - OK !\n"); + Serial.println(WiFi.localIP()); + // индикация силы сигнала + int8_t dBm = WiFi.RSSI(); + Serial.print("RSSI dBm = "); + Serial.println(dBm); + uint8_t 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; + } +} + +//----------------------------------- +// медиана на 3 значения со своим буфером +uint16_t medianRoom(uint16_t newValRoom) +{ + RTC_DATA_ATTR static uint16_t bufRoom[3] = {0, 0, 0}; + RTC_DATA_ATTR static byte countRoom = 0; + + Serial.println(); + Serial.print(countRoom); + Serial.print(" - "); + Serial.print(bufRoom[0]); + Serial.print("..."); + Serial.print(bufRoom[1]); + Serial.print("..."); + Serial.print(bufRoom[2]); + Serial.println(); + + if (!(bufRoom[0] + bufRoom[1] + bufRoom[2])) + bufRoom[0] = bufRoom[1] = bufRoom[2] = newValRoom; + + bufRoom[countRoom] = newValRoom; + if (countRoom++ >= 2) + countRoom = 0; + uint16_t 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; +} + +//----------------------------------- +bool readData() +{ + //============================================================ + // BME280 + i2cBME280.begin(i2c_SDA, i2c_SCL, 100000); + + if (!bme.begin(0x76, &i2cBME280)) + { + Serial.println("Could not find a valid BME280 sensor !"); + flagNotWork = true; + return false; + } + + float temp = bme.readTemperature(); + int16_t pres = (bme.readPressure() * 0.7500637554192 / 100); + int16_t hum = bme.readHumidity(); + float vcc = 0; + Serial.println("\n================="); + + uint16_t dataVcc = 0; + for (uint8_t i = 0; i < 3; ++i) + { + uint16_t temp = analogRead(pinVcc); + Serial.print(temp); + if (i < 2) + Serial.print("..."); + dataVcc += temp; + } + + Serial.print(" = "); + Serial.print(dataVcc / 3); + vcc = 2.8 / 4095 * medianRoom(dataVcc / 3) * 3.6 / 2.8; + Serial.println(); + + Serial.print("Temperature = "); + Serial.print(temp); + Serial.println(" *C"); + + Serial.print("Pressure = "); + Serial.print(pres); + Serial.println(" mm"); + + Serial.print("Humidity = "); + Serial.print(hum); + Serial.println(" %"); + + Serial.print("Vcc = "); + Serial.print(vcc); + Serial.println(" v"); + + Serial.println("=================\n"); + + if (abs(data.t - temp) >= diffTemp || abs(data.p - pres) >= diffPres || + abs(data.h - hum) >= diffHum || abs(data.v - vcc) >= diffVcc || flagNotWork) + { + data.t = temp; + data.p = pres; + data.h = hum; + data.v = vcc; + + data.countSleep = countMaxSleep; + return true; + } + else + { + if (--data.countSleep) + { + return false; + } + else + { + return true; + } + Serial.print("\ncountSleep = "); + Serial.println(data.countSleep); + } + + //============================================================ + // DS18b20 +// DS18B20.begin(); // Инициализация DS18B20 +// DS18B20.requestTemperatures(); // Запрос на считывание температуры + +// float temp = DS18B20.getTempCByIndex(0); +// float vcc = 0; +// Serial.println("\n================="); + +// uint16_t dataVcc = 0; +// for (uint8_t i = 0; i < 3; ++i) +// { +// uint16_t temp = analogRead(pinVcc); +// Serial.print(temp); +// if (i < 2) +// Serial.print("..."); +// dataVcc += temp; +// } + +// Serial.print(" = "); +// Serial.print(dataVcc / 3); +// vcc = 2.8 / 4095 * medianRoom(dataVcc / 3) * 3.6 / 2.8; +// Serial.println(); + +// Serial.print("Temperature = "); +// Serial.print(temp); +// Serial.println(" *C"); + +// Serial.print("Vcc = "); +// Serial.print(vcc); +// Serial.println(" v"); + +// Serial.println("=================\n"); + +// if (abs(data.t - temp) >= diffTemp || abs(data.v - vcc) >= diffVcc || flagNotWork) +// { +// data.t = temp; +// data.v = vcc; + +// data.countSleep = countMaxSleep; +// return true; +// } +// else +// { +// if (--data.countSleep) +// { +// return false; +// } +// else +// { +// return true; +// } +// Serial.print("\ncountSleep = "); +// Serial.println(data.countSleep); +// } +} + +//============================================================ +void setup() +{ + Serial.begin(115200); + pinMode(pinBMEplus, OUTPUT); + digitalWrite(pinBMEplus, HIGH); + pinMode(pinBMEminus, OUTPUT); + digitalWrite(pinBMEminus, LOW); + delay(20); + + if (!readData()) + { + esp_deep_sleep(timeSleep); + } + + if (!setupWiFi(ssid, pass)) + { + flagNotWork = true; + esp_deep_sleep(timeSleep); + } + else + { + flagNotWork = false; + } + + if (!reconnect()) + { + flagNotWork = true; + esp_deep_sleep(timeSleep); + } + else + { + flagNotWork = false; + } + + mqttDataOut(); + + Serial.println("================="); + Serial.flush(); + + delay(TimeBeforeBedtime); + esp_deep_sleep(timeSleep); +} + +void loop() {} \ No newline at end of file -- cgit v1.2.3