diff --git a/firmware/GyverLamp_v1.4/GyverLamp_v1.4.ino b/firmware/GyverLamp_v1.4/GyverLamp_v1.4.ino index 956ab90..3719a9c 100644 --- a/firmware/GyverLamp_v1.4/GyverLamp_v1.4.ino +++ b/firmware/GyverLamp_v1.4/GyverLamp_v1.4.ino @@ -28,6 +28,8 @@ - Добавлено управление по воздуху: -- работает только в режиме WiFi клиента -- работает при подключенной кнопке (потому что режим прошивки активируется кнопкой) + --- 16.07.2019 + - Исправлено регулярное подвисание матрицы на 1-2 секунды при отсутствии подключения к интернету (но при успешном подключении к WiFi) */ // Ссылка для менеджера плат: @@ -39,6 +41,7 @@ #define USE_NTP // закомментировать или удалить эту строку, если нужно, чтобы устройство не лезло в интернет #define GMT (3) // часовой пояс (москва 3) #define NTP_ADDRESS ("europe.pool.ntp.org") // сервер времени +#define NTP_INTERVAL (30UL * 60UL * 1000UL) // интервал синхронизации времени (30 минут) // --- РАССВЕТ ------------------------- #define DAWN_BRIGHT (200U) // максимальная яркость рассвета (0-255) @@ -94,7 +97,6 @@ uint8_t AP_STATIC_IP[] = {192, 168, 4, 1}; // статичес #define FASTLED_INTERRUPT_RETRY_COUNT (0U) #define FASTLED_ALLOW_INTERRUPTS (0U) #define FASTLED_ESP8266_RAW_PIN_ORDER -#define NTP_INTERVAL (30UL * 60UL * 1000UL)// интервал синхронизации времени (30 минут) #include "timerMinim.h" #include @@ -119,11 +121,14 @@ CRGB leds[NUM_LEDS]; WiFiManager wifiManager; WiFiServer wifiServer(ESP_HTTP_PORT); WiFiUDP Udp; -WiFiUDP ntpUDP; + #ifdef USE_NTP +WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, NTP_ADDRESS, GMT * 3600, NTP_INTERVAL); #endif + timerMinim timeTimer(3000); + #ifdef ESP_USE_BUTTON GButton touch(BTN_PIN, LOW_PULL, NORM_OPEN); #endif @@ -206,8 +211,8 @@ void setup() wifiServer.begin(); } - else - { // режим WiFi клиента (подключаемся к роутеру, если есть сохранённые SSID и пароль, иначе создаём WiFi точку доступа и запрашиваем их) + else // режим WiFi клиента (подключаемся к роутеру, если есть сохранённые SSID и пароль, иначе создаём WiFi точку доступа и запрашиваем их) + { Serial.println("Режим WiFi клиента"); if (WiFi.SSID()) { diff --git a/firmware/GyverLamp_v1.4/time.ino b/firmware/GyverLamp_v1.4/time.ino index 1864ed1..61ec11d 100644 --- a/firmware/GyverLamp_v1.4/time.ino +++ b/firmware/GyverLamp_v1.4/time.ino @@ -1,11 +1,51 @@ #ifdef USE_NTP + +#define RESOLVE_INTERVAL (5UL * 60UL * 1000UL) // интервал проверки подключения к интеренету в миллисекундах (5 минут) + // при старте ESP пытается получить точное время от сервера времени в интрнете + // эта попытка длится RESOLVE_TIMEOUT + // если при этом отсутствует подключение к интернету (но есть WiFi подключение), + // модуль будет подвисать на RESOLVE_TIMEOUT каждое срабатывание таймера, т.е., 3 секунды + // чтобы избежать этого, будем пытаться узнать состояние подключения 1 раз в RESOLVE_INTERVAL (5 минут) + // попытки будут продолжаться до первой успешной синхронизации времени + // до этого момента функции будильника работать не будут + // интервал последующих синхронизаций времени определяён в NTP_INTERVAL (30 минут) + // при ошибках повторной синхронизации времени функции будильника отключаться не будут +#define RESOLVE_TIMEOUT (1500UL) // таймаут ожидания подключения к интернету в миллисекундах (1,5 секунды) +uint64_t lastResolveTryMoment = 0UL; +bool timeSynched = false; +bool ntpServerAddressResolved = false; +IPAddress ntpServerIp = {0, 0, 0, 0}; + void timeTick() { if (ESP_MODE == 1) { if (timeTimer.isReady()) { - timeClient.update(); + if (!timeSynched) + { + if (millis() - lastResolveTryMoment >= RESOLVE_INTERVAL || lastResolveTryMoment == 0) + { + resolveNtpServerAddress(ntpServerAddressResolved); // пытаемся получить IP адрес сервера времени (тест интернет подключения) до тех пор, пока время не будет успешно синхронизировано + lastResolveTryMoment = millis(); + if (!ntpServerAddressResolved) + { + #ifdef GENERAL_DEBUG + Serial.println("Функции будильника отключены до восстановления подключения к интернету"); + #endif + } + } + if (!ntpServerAddressResolved) + { + return; // если нет интернет подключения, отключаем будильник до тех пор, пока оно не будет восстановлено + } + } + + timeSynched = timeSynched || timeClient.update(); // если время хотя бы один раз было синхронизировано, продолжаем + if (!timeSynched) // если время не было синхронизиировано ни разу, отключаем будильник до тех пор, пока оно не будет синхронизировано + { + return; + } byte thisDay = timeClient.getDay(); if (thisDay == 0) thisDay = 7; // воскресенье это 0 thisDay--; @@ -46,4 +86,34 @@ void timeTick() } } } + +void resolveNtpServerAddress(bool &ntpServerAddressResolved) // функция проверки подключения к интернету +{ + if (ntpServerAddressResolved) + { + return; + } + WiFi.hostByName(NTP_ADDRESS, ntpServerIp, RESOLVE_TIMEOUT); + if (ntpServerIp[0] <= 0) + { + #ifdef GENERAL_DEBUG + if (ntpServerAddressResolved) + { + Serial.println("Подключение к интернету отсутствует"); + } + #endif + ntpServerAddressResolved = false; + } + else + { + #ifdef GENERAL_DEBUG + if (!ntpServerAddressResolved) + { + Serial.println("Подключение к интернету установлено"); + } + #endif + + ntpServerAddressResolved = true; + } +} #endif USE_NTP