diff options
| author | vlapa <vlapa@ya.ru> | 2026-06-13 16:13:07 +0300 |
|---|---|---|
| committer | vlapa <vlapa@ya.ru> | 2026-06-13 16:13:07 +0300 |
| commit | f983db075831645971bc265f76fdf99bae84b08d (patch) | |
| tree | f3690ef1d586b7663c1a9824bee783f4ef2155bf /src/main.cpp | |
Firstmain
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 453 |
1 files changed, 453 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..51cd991 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,453 @@ +///////////////////////////////////////////////// +// +// 2026-06-12 v.009 +// +///////////////////////////////////////////////// +#include <Arduino.h> +#include <ESP8266WiFi.h> +#include <ESP8266HTTPUpdateServer.h> +#include <NTPClient.h> +#include <WiFiUdp.h> +#include <ESP8266HTTPClient.h> +#include <Adafruit_NeoPixel.h> + +#include "tablo_ws2812.h" + +const uint8_t TIME_DAY = 8; +const uint8_t TIME_NIGHT = 18; +const uint8_t BRIGHT_DAY = 4; +const uint8_t BRIGHT_NIGHT = 1; + +const char *ssid = "link"; +const char *pass = "dkfgf#*12091997"; +const char *ntp_server = "ntp3.vniiftri.ru"; +const char *host = "89.110.92.137"; +const uint16_t port = 8000; +const char *address_page = "/"; + +const uint32_t utcOffsetInSeconds = 10800; +const uint32_t utcPeriodMseconds = 86400000; // 86400000-р/сут; 604800000-р/нед + +WiFiUDP ntpUDP; +NTPClient timeClient(ntpUDP, ntp_server, utcOffsetInSeconds, utcPeriodMseconds); + +const char *tablo_client = "Tablo_Home_mini"; +const char *sensor_1 = "Home_bme280_home_in"; +const char *sensor_2 = "Villa_bme280_base"; + +String sensorKeys; + +WiFiClient espClient; +HTTPClient http; + +uint32_t timeUpdateH = 02; // время обновления NTP +uint32_t timeUpdateM = 05; // время обновления NTP +String z = ""; // строка данных для отображения + +uint32_t colorTime = 16766720; // цвет часы (желтый) +uint32_t colorTemp = 16711935; // цвет температура (красный) +uint32_t colorTemp2 = 65280; // цвет внешняя температура (зеленый) +uint32_t colorTempOut = 9127187; // цвет температура2 (коричневый) +uint32_t colorPress = 9830400; // цвет давление (розовый) +uint32_t colorWiFi = 16728935; // цвет WiFi (томато) +uint32_t colorHum = 52945; // цвет влажность (бирюзовый) +uint32_t colorHumOut = 255; // цвет влажность2 (синий) + +bool flagVis = true; +bool flagSec = true; +uint8_t brightVis = 0; +uint32_t timeReadOld = 0; +uint8_t visData[] = {5, 2, 2, 2, 2}; +uint8_t displayMode = 0; +unsigned long lastModeSwitch = 0; + +unsigned long lastHTTPRequest = 0; +const unsigned long HTTP_UPDATE_INTERVAL = 60000; // Обновляем раз в минуту + +struct +{ + float temp_in = 0.0; + uint16_t pres = 0; + uint8_t hum = 0; + float temp_out = 0.0; +} dataSensors; + +const uint8_t NUMBER_OF_ATTEMPTS = 20; +// uint8_t count = 0; + +ESP8266WebServer server(80); +ESP8266HTTPUpdateServer httpUpdater; + +//=================================================== +// подключение к WiFi +bool setupWiFi() +{ + z = "ABABA"; + visibleWork(z, colorWiFi, BRIGHT_DAY); + strip.show(); + + digitalWrite(LED_BUILTIN, LOW); + Serial.println("\n\nSetup WiFi: "); + + WiFi.begin(ssid, pass); + uint8_t count = NUMBER_OF_ATTEMPTS; + while (WiFi.status() != WL_CONNECTED) + { + Serial.print(count); + Serial.print('>'); + if (!count--) + return false; + delay(500); + } + digitalWrite(LED_BUILTIN, HIGH); + + //----------------------------------- + // индикация IP + z = "DDDDD"; + visibleWork(z, colorWiFi, BRIGHT_DAY); + strip.show(); + String l = WiFi.localIP().toString(); + l = l.substring(l.lastIndexOf('.') + 1, l.length()); + (l.toInt() < 100) ? l = "DDE" + l : l = "DE" + l; + visibleWork(l, colorWiFi, BRIGHT_DAY); + strip.show(); + Serial.print("\nWiFi connected !\nIP: "); + Serial.println(WiFi.localIP()); + delay(2000); + visibleWork("DDDDD", colorWiFi, BRIGHT_DAY); + strip.show(); + + //----------------------------------- + // индикация силы сигнала + int8_t RSSI_MAX = -50; + int8_t RSSI_MIN = -100; + int8_t dBm = WiFi.RSSI(); + Serial.print("RSSI dBm = "); + Serial.println(dBm); + l = ""; + (dBm <= RSSI_MIN) ? l += 0 : (dBm >= RSSI_MAX) ? l += 100 + : l += 2 * (dBm + 100); + Serial.print("RSSI % = "); + Serial.println(l); + Serial.println(); + (l.toInt() < 100) ? l = "DDE" + l : l = "DE" + l; + + visibleWork(l, colorWiFi, BRIGHT_DAY); + strip.show(); + delay(2000); + visibleWork("DDDDD", colorWiFi, BRIGHT_DAY); + strip.show(); + + return true; +} + +//=================================================== +// синхронизация с NTP: +bool setupNTP() +{ + Serial.println("\nСинхронизируем время: "); + uint8_t count = NUMBER_OF_ATTEMPTS; + while (!timeClient.update()) + { + Serial.print(count); + Serial.print('.'); + if (!count--) + return false; + delay(500); + } + Serial.println(); + Serial.println(timeClient.getFormattedTime()); + Serial.println(); + + return true; +} + +//=================================================== +// Запрос POST на сервер: +String http_response() +{ + String payload; + + String url = "http://" + String(host) + ":" + String(port) + address_page; + Serial.println("Sending POST to: " + url); + Serial.println("Data: " + sensorKeys); + + http.begin(espClient, url); + http.addHeader("Content-Type", "text/plain"); + // http.setTimeout(10000); + + // Отправляем POST с нашими ключами + int httpCode = http.POST(sensorKeys); + + // Анализируем ответ + if (httpCode > 0) + { + Serial.printf("Response code: %d\n", httpCode); + + if (httpCode == HTTP_CODE_OK) + { + payload = http.getString(); + Serial.println("Server response: \n" + payload); + } + } + else + { + Serial.printf("POST failed, error: %s\n", http.errorToString(httpCode).c_str()); + } + + http.end(); + + return payload; +} +//=================================================== +// Парсим ответ сервера: +void parse_data_http(String data) +{ + // Serial.println(data); + dataSensors.temp_in = data.substring(1, data.indexOf(";")).toFloat(); + data = data.substring(data.indexOf(";") + 1, data.length()); + // Serial.println(data); + dataSensors.pres = data.substring(0, data.indexOf(";")).toInt(); + data = data.substring(data.indexOf(";") + 1, data.length()); + // Serial.println(data); + dataSensors.hum = data.substring(0, data.indexOf(";")).toInt(); + data = data.substring(data.indexOf(";") + 7, data.length()); + // Serial.println(data); + dataSensors.temp_out = data.substring(0, data.indexOf(";")).toFloat(); + + // Serial.print(dataSensors.temp_in); + // Serial.print(" - "); + // Serial.print(dataSensors.pres); + // Serial.print(" - "); + // Serial.print(dataSensors.hum); + // Serial.print(" - "); + // Serial.print(dataSensors.temp_out); + // Serial.println(); + // Serial.println(sizeof(dataSensors)); +} + +//=================================================== +// Форматируем время: +void TimeMillis() +{ + z = ""; + + if (timeClient.getHours() < 10) + z += "D"; + z += timeClient.getHours(); + + (flagSec) ? z += "B" : z += "D"; + + if (timeClient.getMinutes() < 10) + z += "0"; + + z += timeClient.getMinutes(); + + if ((timeClient.getHours() >= TIME_DAY) && (timeClient.getHours() < TIME_NIGHT)) + { + brightVis = BRIGHT_DAY; + } + else + { + brightVis = BRIGHT_NIGHT; + } +} + +//=================================================== +// Форматируем температуру: +void fTemp(float t) +{ + if (t < 0) + { + if (abs(t) < 10) + { + z = "B"; + z += abs((int)t); + z += "E"; + z += abs((int)((t - (int)t) * 10)); + z += "A"; + } + else + { + z = "DB"; + z += abs((int)t); + z += "A"; + } + } + else + { + if (t < 10) + { + z = "D"; + z += (int)t; + z += "E"; + z += (int)((t - (int)t) * 10); + z += "A"; + } + else + { + z = "DD"; + z += (int)t; + z += "A"; + } + } +} + +// Форматируем давление, влажность: +void fOther(int o) +{ + if (o < 10) + { + z = "DDDD"; + } + else if (o < 100) + { + z = "DDD"; + } + else + { + z = "DD"; + } + z += o; +} + +//=================================================== +// Обновляем данные отображения: +void updateDisplay() +{ + if (flagVis) + { + String response; + switch (displayMode) + { + case 0: + TimeMillis(); + visibleWork(z, colorTime, brightVis); + strip.show(); + flagVis = false; + break; + case 1: + fTemp(dataSensors.temp_in); + visibleWork(z, colorTemp, brightVis); + strip.show(); + flagVis = false; + + // Обновляем данные с сервера не чаще чем раз в минуту + if (millis() - lastHTTPRequest >= HTTP_UPDATE_INTERVAL) + { + String response = http_response(); + if (response.length() > 0) + { + parse_data_http(response); + lastHTTPRequest = millis(); + } + else + { + Serial.println("Warning: Using cached sensor data"); + } + } + break; + case 2: + fOther(dataSensors.pres); + visibleWork(z, colorPress, brightVis); + strip.show(); + flagVis = false; + break; + case 3: + fOther(dataSensors.hum); + visibleWork(z, colorHum, brightVis); + strip.show(); + flagVis = false; + break; + case 4: + fTemp(dataSensors.temp_out); + visibleWork(z, colorTempOut, brightVis); + strip.show(); + flagVis = false; + break; + default: + break; + } + } +} +//=================================================== +void setup() +{ + Serial.begin(115200); + ESP.wdtEnable(5000); // Сторожевой таймер на 5 секунд + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, HIGH); + + strip.begin(); + z = "DDDDD"; + visibleWork(z, colorWiFi, BRIGHT_DAY); + strip.show(); + + if (!setupWiFi()) + ESP.restart(); + + timeClient.begin(); + if (!setupNTP()) + ESP.restart(); + + sensorKeys = sensor_1; + sensorKeys += ","; + sensorKeys += sensor_2; + + parse_data_http(http_response()); + + server.begin(); + httpUpdater.setup(&server); + + lastModeSwitch = millis(); +} + +//=================================================== +void loop() +{ + if (WiFi.status() != WL_CONNECTED) + if (!setupWiFi()) + ESP.restart(); + + // Синхронизация NTP каждые 6 часов + static unsigned long lastNTPSync = 0; + if (millis() - lastNTPSync > 21600000) + { + if (timeClient.update()) + { + lastNTPSync = millis(); + } + } + + if (flagVis) + updateDisplay(); + + // Отображение секундного тире + if (!displayMode) + { + if (millis() - timeReadOld >= 500) + { + flagSec = !flagSec; + timeReadOld = millis(); + flagVis = true; + } + } + + // Логика переключения между разными показаниями + unsigned long current = millis(); + if (current < lastModeSwitch) + { // Переполнение произошло + lastModeSwitch = current; + } + + if (current - lastModeSwitch >= visData[displayMode] * 1000) + { + (displayMode < sizeof(visData) - 1) ? displayMode++ : displayMode = 0; + lastModeSwitch = current; + flagVis = true; + timeReadOld = current; + } + + server.handleClient(); + delay(10); +}
\ No newline at end of file |
