Добавлен вывод времени по запросу и/или периодически; Добавлен перезапуск в режиме ESP_MODE = 0, если при первом запуске в режиме ESP_MODE = 1 не были введены имя и пароль WiFi сети

This commit is contained in:
gunner47
2019-10-14 16:18:45 +03:00
parent 8c90148534
commit a09da9b3ed
6 changed files with 124 additions and 17 deletions

View File

@@ -11,7 +11,7 @@ uint8_t espMode = ESP_MODE; // ESP_MODE може
#define ESP_RESET_ON_START (false) // true - если при старте нажата кнопка (или кнопки нет!), сохранённые настройки будут сброшены; false - не будут
#define ESP_HTTP_PORT (80U) // номер порта, который будет использоваться во время первой утановки имени WiFi сети (и пароля), к которой потом будет подключаться лампа в режиме WiFi клиента (лучше не менять)
#define ESP_UDP_PORT (8888U) // номер порта, который будет "слушать" UDP сервер во время работы лампы как в режиме WiFi точки доступа, так и в режиме WiFi клиента (лучше не менять)
#define ESP_CONN_TIMEOUT (6U) // время в секундах (ДОЛЖНО БЫТЬ МЕНЬШЕ 8, иначе сработает WDT), которое ESP будет пытаться подключиться к WiFi сети, после его истечения автоматически развернёт WiFi точку доступа
#define ESP_CONN_TIMEOUT (7U) // время в секундах (ДОЛЖНО БЫТЬ МЕНЬШЕ 8, иначе сработает WDT), которое ESP будет пытаться подключиться к WiFi сети, после его истечения автоматически развернёт WiFi точку доступа
#define ESP_CONF_TIMEOUT (300U) // время в секундах, которое ESP будет ждать ввода SSID и пароля WiFi сети роутера в конфигурационном режиме, после его истечения ESP перезагружается
#define GENERAL_DEBUG // если строка не закомментирована, будут выводиться отладочные сообщения
#define WIFIMAN_DEBUG (true) // вывод отладочных сообщений при подключении к WiFi сети: true - выводятся, false - не выводятся; настройка не зависит от GENERAL_DEBUG
@@ -36,6 +36,8 @@ const uint8_t AP_STATIC_IP[] = {192, 168, 4, 1}; // статичес
#define GMT (3) // часовой пояс (москва 3)
#define NTP_ADDRESS ("ntp2.colocall.net") // сервер времени
#define NTP_INTERVAL (30UL * 60UL * 1000UL) // интервал синхронизации времени (30 минут)
#define PRINT_TIME (0U) // 0U - не выводить время бегущей строкой; 1U - вывод времени каждый час; 2U - каждый час + каждые 30 минут; 3U - каждый час + каждые 15 минут
// 4U - каждый час + каждые 10 минут; 5U - каждый час + каждые 5 минут; 6U - каждый час + каждую минуту
// --- ВНЕШНЕЕ УПРАВЛЕНИЕ --------------
#define USE_MQTT (false) // true - используется mqtt клиент, false - нет

View File

@@ -87,6 +87,11 @@
- * при переключении рабочего режима лампы WiFi точка доступа/WiFi клиент семикратным кликом по кнопке (перед перезагрузкой) - 3 стандартных вспышки красным
- Уменьшен таймаут подключения к WiFi сети до 6 секунд; вызвано увеличившейся продолжительностью работы функции setup(), она в сумме должна быть меньше 8 секунд
- Оптимизирован код
--- 14.10.2019
- Если при первом старте в режиме WiFi клиента запрашиваемые имя и пароль WiFi сети не введены за отведённый таймаут (5 минут), лампа перезагрузится в режиме точки доступа
- Добавлен вывод времени бегущей строкой:
- * по запросу - шестикратному клику - текущее время белым цветом;
- * периодически - определяется константой PRINT_TIME в Constants.h - от раза в час (красным цветом) до раза в минуту (синим цветом) с яркостью текущего эффекта как при включенной, так и при выключенной матрице
*/
// Ссылка для менеджера плат:
@@ -133,6 +138,8 @@ NTPClient timeClient(ntpUDP, NTP_ADDRESS, GMT * 3600, NTP_INTERVAL);
#endif
timerMinim timeTimer(3000);
bool ntpServerAddressResolved = false;
uint32_t lastTimePrinted = 0U;
#ifdef ESP_USE_BUTTON
GButton touch(BTN_PIN, LOW_PULL, NORM_OPEN);
@@ -200,6 +207,7 @@ void setup()
{
Serial.begin(115200);
Serial.println();
ESP.wdtEnable(WDTO_8S);
// TELNET
@@ -209,12 +217,10 @@ void setup()
{
handleTelnetClient();
delay(100);
ESP.wdtFeed();
}
#endif
ESP.wdtDisable();
//ESP.wdtEnable(WDTO_8S);
// КНОПКА
#if defined(ESP_USE_BUTTON)
@@ -227,6 +233,7 @@ void setup()
wifiManager.resetSettings(); // сброс сохранённых SSID и пароля при старте с зажатой кнопкой, если разрешено
LOG.println(F("Настройки WiFiManager сброшены"));
}
ESP.wdtFeed();
#endif
#endif
@@ -304,7 +311,14 @@ void setup()
if (WiFi.status() != WL_CONNECTED)
{
LOG.println(F("Время ожидания ввода SSID и пароля от WiFi сети или подключения к WiFi сети превышено\nПерезагрузка модуля"));
LOG.println(F("Время ожидания ввода SSID и пароля от WiFi сети или подключения к WiFi сети превышено\nЛампа будет перезагружена в режиме WiFi точки доступа!\n"));
espMode = (espMode == 0U) ? 1U : 0U;
EepromManager::SaveEspMode(&espMode);
LOG.printf_P(PSTR("Рабочий режим лампы изменён и сохранён в энергонезависимую память\nНовый рабочий режим: ESP_MODE = %d, %s\nРестарт...\n"),
espMode, espMode == 0U ? F("WiFi точка доступа") : F("WiFi клиент (подключение к роутеру)"));
showWarning(CRGB::Red, 250U, 250U); // мигание красным цветом 0,25 секунды (1 раз) - ожидание ввода SSID'а и пароля WiFi сети прекращено, перезагрузка
ESP.restart();
}
@@ -312,6 +326,7 @@ void setup()
LOG.print(F("IP адрес: "));
LOG.println(WiFi.localIP());
}
ESP.wdtFeed();
LOG.printf_P(PSTR("Порт UDP сервера: %u\n"), localPort);
Udp.begin(localPort);
@@ -320,6 +335,7 @@ void setup()
// NTP
#ifdef USE_NTP
timeClient.begin();
ESP.wdtFeed();
#endif
@@ -330,6 +346,7 @@ void setup()
mqttClient = new AsyncMqttClient();
MqttManager::setupMqtt(mqttClient, inputBuffer, &sendCurrent); // создание экземпляров объектов для работы с MQTT, их инициализация и подключение к MQTT брокеру
}
ESP.wdtFeed();
#endif
@@ -401,5 +418,4 @@ void loop()
#endif
ESP.wdtFeed(); // пнуть собаку
yield(); // обработать все "служебные" задачи: wdt, WiFi подключение и т.д. (?)
}

View File

@@ -84,16 +84,21 @@ void buttonTick()
#endif
}
if (ONflag && clickCount == 5U) // вывод IP на лампу
if (clickCount == 5U) // вывод IP на лампу
{
if (espMode == 1U)
{
loadingFlag = true;
while(!fillString(WiFi.localIP().toString().c_str())) delay(1);
while(!fillString(WiFi.localIP().toString().c_str(), CRGB::White)) { delay(1); ESP.wdtFeed(); }
loadingFlag = true;
}
}
if (clickCount == 6U) // вывод текущего времени бегущей строкой
{
printTime(thisTime, true);
}
if (ONflag && clickCount == 7U) // смена рабочего режима лампы: с WiFi точки доступа на WiFi клиент или наоборот
{
espMode = (espMode == 0U) ? 1U : 0U;

View File

@@ -229,7 +229,7 @@ void rainbowDiagonalRoutine()
for (uint8_t j = 0U; j < HEIGHT; j++)
{
float twirlFactor = 3.0F * (modes[EFF_RAINBOW_DIAG].Scale / 100.0F); // на сколько оборотов будет закручена матрица, [0..3]
CRGB thisColor = CHSV(constrain((uint8_t)(hue + (float)(WIDTH / HEIGHT * i + j * twirlFactor) * (float)(255 / maxDim)), 0, 255), 255, 255);
CRGB thisColor = CHSV((uint8_t)(hue + (float)(WIDTH / HEIGHT * i + j * twirlFactor) * (float)(255 / maxDim)), 255, 255);
drawPixelXY(i, j, thisColor);
}
}

View File

@@ -9,14 +9,16 @@
#define LET_WIDTH (5U) // ширина буквы шрифта
#define LET_HEIGHT (8U) // высота буквы шрифта
#define SPACE (1U) // пробел
#define LETTER_COLOR (CRGB::White) // цвет букв
#define LETTER_COLOR (CRGB::White) // цвет букв по умолчанию
// --- ДЛЯ РАЗРАБОТЧИКОВ ---------------
int16_t offset = WIDTH;
uint32_t scrollTimer = 0LL;
bool fillString(const char* text)
bool fillString(const char* text, CRGB letterColor)
{
if (!text || !strlen(text))
{
@@ -36,13 +38,13 @@ bool fillString(const char* text)
uint8_t i = 0, j = 0;
while (text[i] != '\0')
{
if ((uint8_t)text[i] > 191) // работаем с русскими буквами!
if ((uint8_t)text[i] > 191) // работаем с русскими буквами
{
i++;
}
else
{
drawLetter(text[i], offset + j * (LET_WIDTH + SPACE));
drawLetter(text[i], offset + j * (LET_WIDTH + SPACE), letterColor);
i++;
j++;
}
@@ -60,7 +62,88 @@ bool fillString(const char* text)
return false;
}
void drawLetter(uint8_t letter, int8_t offset)
void printTime(uint32_t thisTime, bool onDemand) // периодический вывод времени бегущей строкой; onDemand - по требованию, вывод текущего времени; иначе - вывод времени по расписанию
{
#if defined(USE_NTP) && defined(PRINT_TIME) // вывод, только если используется синхронизация времени и если заказан его вывод бегущей строкой
if (espMode != 1U || !ntpServerAddressResolved) // вывод только в режиме WiFi клиента и только, если имя сервера времени разрезолвлено
{
return;
}
CRGB letterColor = CRGB::Black;
bool needToPrint = false;
#if (PRINT_TIME >= 1U) // вывод только каждый час (красным цветом)
if (thisTime % 60U == 0U)
{
needToPrint = true;
letterColor = CRGB::Red;
}
#endif
#if (PRINT_TIME == 2U) // вывод каждый час (красным цветом) + каждые 30 минут (синим цветом)
if (thisTime % 60U != 0U && thisTime % 30U == 0U)
{
needToPrint = true;
letterColor = CRGB::Blue;
}
#endif
#if (PRINT_TIME == 3U) // вывод каждый час (красным цветом) + каждые 15 минут (синим цветом)
if (thisTime % 60U != 0U && thisTime % 15U == 0U)
{
needToPrint = true;
letterColor = CRGB::Blue;
}
#endif
#if (PRINT_TIME == 4U) // вывод каждый час (красным цветом) + каждые 10 минут (синим цветом)
if (thisTime % 60U != 0U && thisTime % 10U == 0U)
{
needToPrint = true;
letterColor = CRGB::Blue;
}
#endif
#if (PRINT_TIME == 5U) // вывод каждый час (красным цветом) + каждые 5 минут (синим цветом)
if (thisTime % 60U != 0U && thisTime % 5U == 0U)
{
needToPrint = true;
letterColor = CRGB::Blue;
}
#endif
#if (PRINT_TIME == 6U) // вывод каждый час (красным цветом) + каждую минуту (синим цветом)
if (thisTime % 60U != 0U)
{
needToPrint = true;
letterColor = CRGB::Blue;
}
#endif
if (onDemand)
{
letterColor = CRGB::White;
}
if ((needToPrint && thisTime != lastTimePrinted) || onDemand)
{
lastTimePrinted = thisTime;
char stringTime[10U];
sprintf_P(stringTime, PSTR("-> %u:%02u"), (uint8_t)((thisTime - thisTime % 60U) / 60U), (uint8_t)(thisTime % 60U));
loadingFlag = true;
FastLED.setBrightness(modes[currentMode].Brightness);
delay(1);
while (!fillString(stringTime, letterColor)) { delay(1); ESP.wdtFeed(); }
loadingFlag = true;
}
#endif
}
void drawLetter(uint8_t letter, int8_t offset, CRGB letterColor)
{
uint8_t start_pos = 0, finish_pos = LET_WIDTH;
@@ -100,7 +183,7 @@ void drawLetter(uint8_t letter, int8_t offset)
{
if (thisBit)
{
leds[getPixelNumber(offset + i, TEXT_HEIGHT + j)] = LETTER_COLOR;
leds[getPixelNumber(offset + i, TEXT_HEIGHT + j)] = letterColor;
}
else
{
@@ -111,7 +194,7 @@ void drawLetter(uint8_t letter, int8_t offset)
{
if (thisBit)
{
leds[getPixelNumber(i, offset + TEXT_HEIGHT + j)] = LETTER_COLOR;
leds[getPixelNumber(i, offset + TEXT_HEIGHT + j)] = letterColor;
}
else
{

View File

@@ -13,7 +13,6 @@
#define RESOLVE_TIMEOUT (1500UL) // таймаут ожидания подключения к интернету в миллисекундах (1,5 секунды)
uint64_t lastResolveTryMoment = 0UL;
bool timeSynched = false;
bool ntpServerAddressResolved = false;
IPAddress ntpServerIp = {0, 0, 0, 0};
static CHSV dawnColor = CHSV(0, 0, 0); // цвет "рассвета"
static CHSV dawnColorMinus1 = CHSV(0, 0, 0); // для большей плавности назначаем каждый новый цвет только 1/10 всех диодов; каждая следующая 1/10 часть будет "оставать" на 1 шаг
@@ -61,6 +60,8 @@ void timeTick()
thisTime = timeClient.getHours() * 60 + timeClient.getMinutes();
uint32_t thisFullTime = timeClient.getHours() * 3600 + timeClient.getMinutes() * 60 + timeClient.getSeconds();
printTime(thisTime, false);
// проверка рассвета
if (alarms[thisDay].State && // день будильника
thisTime >= (uint16_t)constrain(alarms[thisDay].Time - pgm_read_byte(&dawnOffsets[dawnMode]), 0, (24 * 60)) && // позже начала