summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--README.mdbin0 -> 48 bytes
-rw-r--r--include/tablo_ws2812.h314
-rw-r--r--include/tablo_ws2812_22ledX5.h242
-rw-r--r--platformio.ini21
-rw-r--r--src/main.cpp453
6 files changed, 1032 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b9f3806
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.pio
+.vscode
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..08133ef
--- /dev/null
+++ b/README.md
Binary files differ
diff --git a/include/tablo_ws2812.h b/include/tablo_ws2812.h
new file mode 100644
index 0000000..03c43e2
--- /dev/null
+++ b/include/tablo_ws2812.h
@@ -0,0 +1,314 @@
+/*=========================================================
+ Tablo ws2812
+ = vlapa = v.509
+ 2021.02.01 - 2023.11.14
+=========================================================*/
+#pragma once
+
+#define PIXEL_PIN D2
+#define RAZR_PIXEL 42
+
+// #define BRIGHT_DAY 5
+// #define BRIGHT_NIGHT 1
+const uint8_t digit = 5; // кол-во разрядов табло
+#define PIXEL_COUNT RAZR_PIXEL * digit
+
+#include <Adafruit_NeoPixel.h>
+Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
+
+//********************************************************************
+// плата
+void visibleWork(String visData, uint32_t color, uint8_t bright)
+
+{ // данные, цвет
+ strip.setBrightness(bright);
+
+ for (uint8_t razr = 0; razr < digit; ++razr)
+ {
+ uint8_t x;
+ if (visData.charAt(razr) == 'A')
+ {
+ x = 10;
+ }
+ else if (visData.charAt(razr) == 'B')
+ {
+ x = 11;
+ }
+ else if (visData.charAt(razr) == 'C')
+ {
+ x = 12;
+ }
+ else if (visData.charAt(razr) == 'D')
+ {
+ x = 13;
+ }
+ else if (visData.charAt(razr) == 'E')
+ {
+ x = 14;
+ }
+ else if (visData.charAt(razr) == 'p')
+ {
+ x = 15;
+ }
+ else if (visData.charAt(razr) == 'h')
+ {
+ x = 16;
+ }
+ else
+ {
+ x = visData.substring(razr, razr + 1).toInt();
+ }
+
+ switch (x)
+ {
+ case 0:
+ for (int i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if (i >= 0 && i < 36)
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 1:
+ for (int i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if (i > 11 && i < 24)
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 2:
+ for (int i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if ((i > 5 && i < 18) || (i > 23 && i < 42))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 3:
+ for (int i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if ((i > 5 && i < 30) || (i > 36 && i < 42))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 4:
+ for (int i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if ((i >= 0 && i < 6) || (i > 11 && i < 24) || (i > 35 && i < 42))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 5:
+ for (int i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if ((i >= 0 && i < 12) || (i > 17 && i < 30) || (i > 35 && i < 42))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 6:
+ for (int i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if ((i >= 0 && i < 12) || (i > 17 && i < 42))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 7:
+ for (int i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if (i > 5 && i < 24)
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 8:
+ for (int i = 0; i < RAZR_PIXEL; ++i)
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ break;
+ case 9:
+ for (int i = 0; i < RAZR_PIXEL; i++)
+ {
+ if ((i >= 0 && i < 30) || (i > 35 && i < 42))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 10: // градус ( A )
+ for (int i = 0; i < RAZR_PIXEL; i++)
+ {
+ if ((i >= 0 && i < 18) || (i > 35 && i < 42))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 11: // минус ( B )
+ for (int i = 0; i < RAZR_PIXEL; i++)
+ {
+ if ((i > 35) && (i < 42))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 12: // двоеточие ( C )
+ for (int i = 0; i < RAZR_PIXEL; i++)
+ {
+ if ((i == 36) || (i == 37) || (i == 40) || (i == 41))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 13: // null (пусто) ( D )
+ for (int i = 0; i < RAZR_PIXEL; ++i)
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ break;
+ case 14: // точка ( E )
+ for (int i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if ((i == 26) || (i == 27))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 15: // давление ( p )
+ for (int i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if ((i < 18) || (i > 29))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 16: // влажность ( h )
+ for (int i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if ((i < 6) || (i > 17 && i < 24) || (i > 29))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ }
+ }
+ strip.show();
+}
+
+//********************************************************************
+// Эффекты табло:
+// void visible_effect()
+// {
+// uint8_t a, b, c;
+// for (uint8_t k = 0; k < 3; ++k)
+// {
+// (k == 0) ? a = 255 : b = c = 0;
+// (k == 1) ? b = 255 : a = c = 0;
+// (k == 2) ? c = 255 : b = a = 0;
+
+// for (uint8_t i = 0; i < PIXEL_COUNT; ++i)
+// {
+// // uint32_t col = 255;
+// for (uint8_t i = 0; i < PIXEL_COUNT; ++i)
+// {
+// // uint32_t col = random(200, 65535);
+// strip.setPixelColor(i, strip.Color(a, b, c));
+// strip.show();
+// delay(10);
+// }
+// }
+// }
+
+// // for (uint8_t i = 0; i < PIXEL_COUNT; ++i)
+// // {
+// // uint32_t col = random(200, 65535);
+// // strip.setPixelColor(i, col);
+// // strip.show();
+// // delay(10);
+// // }
+// delay(1000);
+
+// for (uint8_t i = 0; i < PIXEL_COUNT; ++i)
+// {
+// strip.setPixelColor(i, 0);
+// strip.show();
+// }
+// } \ No newline at end of file
diff --git a/include/tablo_ws2812_22ledX5.h b/include/tablo_ws2812_22ledX5.h
new file mode 100644
index 0000000..666716a
--- /dev/null
+++ b/include/tablo_ws2812_22ledX5.h
@@ -0,0 +1,242 @@
+/*=========================================================
+ Tablo ws2812_22ledX5
+ 2026.02.21 -
+
+ A - градус
+ В - минус
+ С - двоеточие
+ D - пусто
+ E - точка
+ F - p
+ G - h
+=========================================================*/
+#pragma once
+
+#define PIXEL_PIN D2
+#define RAZR_PIXEL 42
+#define PIXEL_COUNT 210
+#define DIGIT 5
+
+#include <Adafruit_NeoPixel.h>
+Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
+
+//********************************************************
+// "Перевод" данных в пиксели:
+void visibleWork(String visData, uint32_t color, uint8_t bright)
+{
+ // Serial.println(visData);
+ strip.setBrightness(bright);
+ for (uint8_t razr = 0; razr < DIGIT; ++razr)
+ {
+ uint8_t temp;
+ if (visData.charAt(razr) == 'A')
+ {
+ temp = 10;
+ }
+ else if (visData.charAt(razr) == 'B')
+ {
+ temp = 11;
+ }
+ else if (visData.charAt(razr) == 'C')
+ {
+ temp = 12;
+ }
+ else if (visData.charAt(razr) == 'D')
+ {
+ temp = 13;
+ }
+ else if (visData.charAt(razr) == 'E')
+ {
+ temp = 14;
+ }
+ else
+ {
+ temp = visData.substring(razr, razr + 1).toInt();
+ }
+ switch (temp)
+ {
+ case 0:
+ for (uint8_t i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if (i >= 0 && i < 20)
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 1:
+ for (uint8_t i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if (i > 4 && i < 13)
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 2:
+ for (uint8_t i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if ((i > 1 && i < 9) || (i > 11 && i < 22))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 3:
+ for (uint8_t i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if ((i > 1 && i < 16) || (i == 20 || i == 21))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 4:
+ for (uint8_t i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if ((i >= 0 && i < 3) || (i > 4 && i < 13) || (i > 18 && i < 22))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 5:
+ for (uint8_t i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if ((i >= 0 && i < 6) || (i > 7 && i < 16) || (i > 18 && i < 22))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 6:
+ for (uint8_t i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if ((i >= 0 && i < 6) || (i > 7 && i < 22))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 7:
+ for (uint8_t i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if (i > 1 && i < 13)
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 8:
+ for (uint8_t i = 0; i < RAZR_PIXEL; ++i)
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ break;
+ case 9:
+ for (uint8_t i = 0; i < RAZR_PIXEL; i++)
+ {
+ if ((i >= 0 && i < 16) || (i > 18 && i < 22))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 10: // градус ( A )
+ for (uint8_t i = 0; i < RAZR_PIXEL; i++)
+ {
+ if (i == 0 || i == 1 || i == 3 || i == 4 || i == 6 || i == 7 ||
+ i == 20 || i == 21)
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 11: // минус ( B )
+ for (uint8_t i = 0; i < RAZR_PIXEL; i++)
+ {
+ if (i == 8 || (i > 18 && i < 22))
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 12: // двоеточие ( C ) короткое тире
+ for (uint8_t i = 0; i < RAZR_PIXEL; i++)
+ {
+ if (i == 20 || i == 21)
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ case 13: // null (пусто) ( D )
+ for (uint8_t i = 0; i < RAZR_PIXEL; ++i)
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ break;
+ case 14: // точка ( E )
+ for (uint8_t i = 0; i < RAZR_PIXEL; ++i)
+ {
+ if (i == 13 || i == 14)
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, color);
+ }
+ else
+ {
+ strip.setPixelColor(i + razr * RAZR_PIXEL, strip.Color(0, 0, 0));
+ }
+ }
+ break;
+ }
+ }
+} \ No newline at end of file
diff --git a/platformio.ini b/platformio.ini
new file mode 100644
index 0000000..f0ae75b
--- /dev/null
+++ b/platformio.ini
@@ -0,0 +1,21 @@
+; 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:d1_mini]
+platform = espressif8266
+board = d1_mini
+framework = arduino
+
+upload_speed = 460800 ;921600
+monitor_speed = 115200
+
+lib_deps =
+ adafruit/Adafruit NeoPixel
+ arduino-libraries/NTPClient
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