summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp305
-rw-r--r--src/setenv_source.h12
2 files changed, 317 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..05206c3
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,305 @@
+#include <Arduino.h>
+#include <WiFi.h>
+#include <Wire.h>
+#include <Adafruit_BME280.h>
+#include <PubSubClient.h>
+
+#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; // напряжение батареи
+
+TwoWire i2cBME280 = TwoWire(0);
+Adafruit_BME280 bme;
+
+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 *outTopicTemp = "/Temp"; // топик
+const char *outTopicPres = "/Pres"; // топик
+const char *outTopicHum = "/Hum"; // топик
+const char *outTopicVcc = "/Vcc"; // топик
+
+//------------------------------------------------
+uint8_t countConnect = 20; // кол-во попыток соединения
+uint16_t countPause = 500; // пауза между попытками
+uint32_t timeSleep = 60000000; // время сна
+uint16_t TimeBeforeBedtime = 500; // время до засыпания
+uint8_t countMaxSleep = 10; // не передавать данные не более
+ // countMaxSleep х timeSleep (10 мин)
+
+// Структура для хранения данных в RTC памяти:
+RTC_DATA_ATTR struct
+{
+ float t; // температура
+ float v; // напряжение
+ uint16_t p; // давление
+ uint8_t h; // влажность
+ uint8_t countSleep; // счетчик предельного кол-ва циклов сна
+
+ uint16_t bufRoom[3] = {0, 0, 0};
+ byte countRoom = 0;
+} data;
+
+// Разница при которой будут отправляться данные:
+float diffTemp = 0.25; // разница температур
+int diffPres = 5; // разница давлений
+int diffHum = 5; // разница влажностей
+float diffVcc = 0.1; // разница зарядки акб
+
+//-----------------------------------
+// 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());
+}
+
+//-----------------------------------
+// Отправка данных на MQTT сервер:
+void mqttDataOut(float temp, uint16_t pres, uint8_t hum, float vcc)
+{
+ String topic = "/";
+ topic += mqtt_client2;
+ topic += outTopicTemp;
+ while (!mqtt_publish(client, topic, (String)temp))
+ {
+ mqtt_publish(client, topic, (String)temp);
+ }
+
+ topic = "/";
+ topic += mqtt_client2;
+ topic += outTopicPres;
+ while (!mqtt_publish(client, topic, (String)pres))
+ {
+ mqtt_publish(client, topic, (String)pres);
+ }
+
+ topic = "/";
+ topic += mqtt_client2;
+ topic += outTopicHum;
+ while (!mqtt_publish(client, topic, (String)hum))
+ {
+ mqtt_publish(client, topic, (String)hum);
+ }
+
+ topic = "/";
+ topic += mqtt_client2;
+ topic += outTopicVcc;
+ while (!mqtt_publish(client, topic, (String)vcc))
+ {
+ mqtt_publish(client, topic, (String)vcc);
+ }
+}
+
+//-----------------------------------
+// Подключение к MQTT серверу:
+bool reconnect()
+{
+ client.setServer(mqtt_server, String(mqtt_port).toInt());
+
+ Serial.println(mqtt_server);
+
+ while (!(client.connect(mqtt_client, mqtt_user, mqtt_pass)) && countConnect--)
+ {
+ Serial.print(countConnect);
+ Serial.print('>');
+ delay(countPause);
+ }
+
+ if (client.connected())
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//-----------------------------------
+// Подключение к сети WiFi:
+bool setupWiFi(const char *wifi_ssid, const char *wifi_pass)
+{
+ WiFi.begin(wifi_ssid, wifi_pass);
+
+ Serial.println("\n=================");
+ 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.println();
+ 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 значения со своим буфером для усреднения ADC:
+uint16_t medianRoom(uint16_t newValRoom)
+{
+ if (!(data.bufRoom[0] + data.bufRoom[1] + data.bufRoom[2]))
+ data.bufRoom[0] = data.bufRoom[1] = data.bufRoom[2] = newValRoom;
+
+ data.bufRoom[data.countRoom] = newValRoom;
+ if (data.countRoom++ >= 2)
+ data.countRoom = 0;
+ uint16_t dataRoom = (max(data.bufRoom[0], data.bufRoom[1]) == max(data.bufRoom[1], data.bufRoom[2]))
+ ? max(data.bufRoom[0], data.bufRoom[2])
+ : max(data.bufRoom[1], min(data.bufRoom[0], data.bufRoom[2]));
+ return dataRoom;
+}
+
+//-----------------------------------
+// Читаем данные с датчика BME280:
+bool readData()
+{
+ pinMode(pinBMEplus, OUTPUT);
+ digitalWrite(pinBMEplus, HIGH);
+ pinMode(pinBMEminus, OUTPUT);
+ digitalWrite(pinBMEminus, LOW);
+ delay(1);
+
+ i2cBME280.begin(i2c_SDA, i2c_SCL, 100000);
+
+ // Инициализация BME280 по адресу = 0х76 !!!
+ if (!bme.begin(0x76, &i2cBME280))
+ {
+ Serial.println("Could not find a valid BME280 sensor !");
+
+ pinMode(pinBMEplus, INPUT);
+ digitalWrite(pinBMEplus, LOW);
+ pinMode(pinBMEminus, INPUT);
+ digitalWrite(pinBMEminus, LOW);
+ delay(1);
+
+ return false;
+ }
+
+ float temp = bme.readTemperature();
+ uint16_t pres = (bme.readPressure() * 0.7500637554192 / 100);
+ uint8_t hum = bme.readHumidity();
+
+ pinMode(pinBMEplus, INPUT);
+ digitalWrite(pinBMEplus, LOW);
+ pinMode(pinBMEminus, INPUT);
+ digitalWrite(pinBMEminus, LOW);
+ delay(1);
+
+ // Читаем ADC:
+ uint16_t dataVcc = 0;
+ for (uint8_t i = 0; i < 3; ++i)
+ {
+ dataVcc += analogRead(pinVcc);
+ }
+
+ // Пересчет ADC в напряжение АКБ:
+ // 2.8 - максимальное напряжение на считываемой ножке
+ // 4095 - количество отсчетов ADC
+ // 3.6 - максимальное напряжение АКБ LiFePo4
+ float vcc = 0;
+ vcc = 2.8 / 4095 * medianRoom(dataVcc / 3) * 3.6 / 2.8;
+
+ // Если данные с датчика и напряжение питания изменились больше чем разница,
+ // то заносим данные в память RTC и сбрасываем предельный счетчик циклов сна:
+ if (abs(data.t - temp) >= diffTemp || abs(data.p - pres) >= diffPres ||
+ abs(data.h - hum) >= diffHum || abs(data.v - vcc) >= diffVcc || data.countSleep <= 1)
+ {
+ data.t = temp;
+ data.p = pres;
+ data.h = hum;
+ data.v = vcc;
+ data.countSleep = countMaxSleep - 1;
+ return true;
+ }
+ else
+ {
+ if (--data.countSleep)
+ {
+ Serial.println("\nДанные изменились незначительно !\n");
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+}
+
+//-----------------------------------
+void setup()
+{
+ Serial.begin(115200);
+
+ if (!readData())
+ {
+ esp_deep_sleep(timeSleep);
+ }
+
+ if (!setupWiFi(ssid, pass))
+ {
+ esp_deep_sleep(timeSleep);
+ }
+
+ if (!reconnect())
+ {
+ esp_deep_sleep(timeSleep);
+ }
+
+ mqttDataOut(data.t, data.p, data.h, data.v);
+
+ Serial.println("=================");
+ Serial.flush();
+
+ delay(TimeBeforeBedtime);
+ esp_deep_sleep(timeSleep);
+}
+
+void loop() {} \ No newline at end of file
diff --git a/src/setenv_source.h b/src/setenv_source.h
new file mode 100644
index 0000000..032beb5
--- /dev/null
+++ b/src/setenv_source.h
@@ -0,0 +1,12 @@
+/* Установка переменных:
+
+const char *WiFi_SSID = "";
+const char *WiFi_PASS = "";
+const char *MQTT_CLIENT_N = "1234567890";
+const char *MQTT_CLIENT_T = "";
+const char *MQTT_USER = "";
+const char *MQTT_PASS = "";
+const char *MQTT_SERVER = "000.000.000.000";
+const char *MQTT_PORT = "1883";
+
+*/ \ No newline at end of file