mirror of
https://github.com/gunner47/GyverLamp.git
synced 2025-08-08 01:20:31 +03:00
Добавлен режим автоматического переключения избранных эффектов; Реорганизован код, исправлены ошибки
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -28,6 +28,11 @@ ScreenManager
|
|||||||
ShowScreen метод: принимает номер "экрана", устанавливает свойство видимости в true для этого экрана и в false для остальных экранов; вызывает перерисовку "экранов"
|
ShowScreen метод: принимает номер "экрана", устанавливает свойство видимости в true для этого экрана и в false для остальных экранов; вызывает перерисовку "экранов"
|
||||||
RebuildAllScreens метод: перерисовывает "экраны", делает их блоки видимыми или видимыми в зависимости от выставленных свойств видимости
|
RebuildAllScreens метод: перерисовывает "экраны", делает их блоки видимыми или видимыми в зависимости от выставленных свойств видимости
|
||||||
CloseApplication метод: закрывает приложение
|
CloseApplication метод: закрывает приложение
|
||||||
|
Color_DarkGrey свойство (константа): код цвета "тёмно-серый"
|
||||||
|
Color_LightGrey свойство (константа): код цвета "светло-серый"
|
||||||
|
Color_LightLightGrey свойство (константа): код цвета "светло-светло-серый"
|
||||||
|
Color_LightGreyBackground свойство (константа): код цвета "светло-серый" для фона
|
||||||
|
Color_Red свойство (константа): код цвета "красный"
|
||||||
|
|
||||||
MainScreen
|
MainScreen
|
||||||
Visible свойство: "Видимость главного экрана"
|
Visible свойство: "Видимость главного экрана"
|
||||||
@@ -60,7 +65,7 @@ ConnectivityScreen
|
|||||||
RemoveConnectionButtonClick метод (событие): действия при нажатии на кнопку "Удалить"
|
RemoveConnectionButtonClick метод (событие): действия при нажатии на кнопку "Удалить"
|
||||||
SaveAllConnectionButtonClick метод (событие): действия при нажатии на кнопку "Сканировать и добавить"
|
SaveAllConnectionButtonClick метод (событие): действия при нажатии на кнопку "Сканировать и добавить"
|
||||||
DeviceSocketListViewAfterPicking метод (событие): действия при выборе устройства из списка сохранённых и его подключение
|
DeviceSocketListViewAfterPicking метод (событие): действия при выборе устройства из списка сохранённых и его подключение
|
||||||
BaсkButtonClick метод (событие): действия при UI кнопки "Назад" на "экране" устройств
|
BaсkButtonClick метод (событие): действия при нажатии кнопки "Назад" на "экране" устройств
|
||||||
UpdateConnectivityStatus метод: обновить статус устройства "Подключен"/"Отключен" на "экране" устройств
|
UpdateConnectivityStatus метод: обновить статус устройства "Подключен"/"Отключен" на "экране" устройств
|
||||||
UpdateCurrentDeviceSocket метод: отобразить текущее устройство (DeviceManager.CurrentDeviceSocket) в полях ввода IP адреса и порта на "экране" устройств
|
UpdateCurrentDeviceSocket метод: отобразить текущее устройство (DeviceManager.CurrentDeviceSocket) в полях ввода IP адреса и порта на "экране" устройств
|
||||||
UpdateCurrentDevicesSockets метод: отобразить текущий список сохранённых устройств (DeviceManager.Devices) на "экране" устройств
|
UpdateCurrentDevicesSockets метод: отобразить текущий список сохранённых устройств (DeviceManager.Devices) на "экране" устройств
|
||||||
@@ -70,17 +75,31 @@ ConnectivityScreen
|
|||||||
ModesScreen
|
ModesScreen
|
||||||
Visible свойство: "Видимость экрана эффектов"
|
Visible свойство: "Видимость экрана эффектов"
|
||||||
ModesListViewAfterPicking метод (событие): действия при выборе эффекта из списка эффектов
|
ModesListViewAfterPicking метод (событие): действия при выборе эффекта из списка эффектов
|
||||||
BaсkButtonClick метод (событие): действия при UI кнопки "Назад" на "экране" эффектов
|
BaсkButtonClick метод (событие): действия при нажатии кнопки "Назад" на "экране" эффектов
|
||||||
|
|
||||||
FavoritesScreen
|
FavoritesScreen
|
||||||
Visible свойство: "Видимость экрана устройств"
|
Visible свойство: "Видимость экрана устройств"
|
||||||
BaсkButtonClick метод (событие): действия при UI кнопки "Назад" на "экране" избранных эффектов
|
Initialized свойство: "Экран автоматического переключения избранных эффектов инициализирован"
|
||||||
|
BlockControlEventsEmitting свойство: "Не генерировать события от элементов управления" (переключателей, лист пикеров и т.д.)
|
||||||
|
BaсkButtonClick метод (событие): действия при нажатии кнопки "Назад" на "экране" избранных эффектов
|
||||||
|
OnOffSwitchChanged метод (событие): действия при установке/снятии переключателя включения режима избранных эффектов
|
||||||
|
IntervalListPickerAfterPicking метод (событие): действия при выборе интервала времени (статической состявляющей) между автоматическими переключениями избранных эффектов
|
||||||
|
DispersionListPickerAfterPicking метод (событие): действия при выборе разброса времени (случайной состявляющей) между автоматическими переключениями избранных эффектов
|
||||||
|
ListViewIconClick метод (событие): действия при добавлении/удалении эффекта в/из список избранных
|
||||||
|
ListViewelementTouchUp метод (событие): служебный метод, необходимый для корректной отрисовки фона элемента в списке избранных эффектов
|
||||||
|
Initialize метод: настраивает и заполняющий специфический (кастомный) компонент ListViewer
|
||||||
|
MarkListItemAsFavorite метод: устанавливает признак включения/исключения эффекта в избранные в свойстве "состояние режима избранных эффектов"
|
||||||
|
UpdateScreen метод: обновить все элементы управления на "экране" избранных эффектов согласно модели данных
|
||||||
|
UpdateControls метод: обновить отображение элементов управления (статусы enabled/disabled) в зависимости от сохранённых свойств (модели данных)
|
||||||
|
SetFavoriteSettings метод: меняет состояние "экрана" избранных эффектов (устанавливает недоступность элементов управления и отображает анимацию) и вызывает DeviceManager.SetFavoriteSettings
|
||||||
|
SetIntervalListPicker метод: иниицализирует значение поля выбора интервала времени автоматической смены избранных эффектов согласно модели данных
|
||||||
|
SetDispersionListPicker метод: иниицализирует значение поля выбора разброса времени автоматической смены избранных эффектов согласно модели данных
|
||||||
|
|
||||||
AlarmScreen
|
AlarmScreen
|
||||||
Visible свойство: "Видимость экрана устройств"
|
Visible свойство: "Видимость экрана устройств"
|
||||||
Initialized свойство: "Экран управления будильниками инициализирован"
|
Initialized свойство: "Экран управления будильниками инициализирован"
|
||||||
BlockControlEventsEmitting свойство: "Не генерировать события от элементов управления" (переключателей, тайм пикеров и т.д.); нужно, например, чтобы предотвратить switch.changed при его enable/disable
|
BlockControlEventsEmitting свойство: "Не генерировать события от элементов управления" (переключателей, тайм пикеров и т.д.); нужно, например, чтобы предотвратить switch.changed при его enable/disable
|
||||||
BaсkButtonClick метод (событие): действия при UI кнопки "Назад" на "экране" будильника
|
BaсkButtonClick метод (событие): действия при нажатии кнопки "Назад" на "экране" будильника
|
||||||
MonSwitchChanged метод (событие): действия при установке/снятии переключателя включения будильника
|
MonSwitchChanged метод (событие): действия при установке/снятии переключателя включения будильника
|
||||||
TueSwitchChanged метод (событие): действия при установке/снятии переключателя включения будильника
|
TueSwitchChanged метод (событие): действия при установке/снятии переключателя включения будильника
|
||||||
WedSwitchChanged метод (событие): действия при установке/снятии переключателя включения будильника
|
WedSwitchChanged метод (событие): действия при установке/снятии переключателя включения будильника
|
||||||
@@ -106,6 +125,7 @@ TimerScreen
|
|||||||
AnimationTimerOn свойство: "таймер, управляющий анимацией функции таймера лампы, включен"
|
AnimationTimerOn свойство: "таймер, управляющий анимацией функции таймера лампы, включен"
|
||||||
RemainingSeconds свойство: "время до срабатывания таймера лампы" и одновремнно "время до окончания работы таймера, управляющего анимацией функции таймера лампы"
|
RemainingSeconds свойство: "время до срабатывания таймера лампы" и одновремнно "время до окончания работы таймера, управляющего анимацией функции таймера лампы"
|
||||||
TimerTickMs свойство: "шаг таймера, управляющего анимацией функции таймера лампы"
|
TimerTickMs свойство: "шаг таймера, управляющего анимацией функции таймера лампы"
|
||||||
|
BaсkButtonClick метод (событие): действия при нажатии кнопки "Назад" на "экране" таймера
|
||||||
TimeListPickerAfterPicking метод (событие): действия при выборе пользователем времени до срабатывания таймера лампы (отправка команды модулю)
|
TimeListPickerAfterPicking метод (событие): действия при выборе пользователем времени до срабатывания таймера лампы (отправка команды модулю)
|
||||||
UpdateControls метод: обновить отображение элементов управления (статусы enabled/disabled) в зависимости от сохранённых свойств (модели данных)
|
UpdateControls метод: обновить отображение элементов управления (статусы enabled/disabled) в зависимости от сохранённых свойств (модели данных)
|
||||||
UpdateScreen метод: обновить все элементы управления на "экране" управления таймером согласно модели данных
|
UpdateScreen метод: обновить все элементы управления на "экране" управления таймером согласно модели данных
|
||||||
@@ -114,13 +134,13 @@ TimerScreen
|
|||||||
HandleAnimation метод: обработать таймер, управляющий анимацией функции таймера лампы (запуск, если не запущен, принудительная остановка, если нужно)
|
HandleAnimation метод: обработать таймер, управляющий анимацией функции таймера лампы (запуск, если не запущен, принудительная остановка, если нужно)
|
||||||
AnimationTimerTimerNow метод: действия при срабатывании события таймера, управляющий анимацией функции таймера лампы (показать/скрыть иконку, обновить текст оставшегося времени)
|
AnimationTimerTimerNow метод: действия при срабатывании события таймера, управляющий анимацией функции таймера лампы (показать/скрыть иконку, обновить текст оставшегося времени)
|
||||||
StopAnimationTimer метод: остановить таймер, управляющий анимацией функции таймера лампы, сбросить его сохранённое состояние в исходное (модель данных)
|
StopAnimationTimer метод: остановить таймер, управляющий анимацией функции таймера лампы, сбросить его сохранённое состояние в исходное (модель данных)
|
||||||
BaсkButtonClick метод (событие): действия при UI кнопки "Назад" на "экране" таймера
|
|
||||||
|
|
||||||
DeviceManager
|
DeviceManager
|
||||||
Connected свойство: подключено ли устройство (лампа)? точнее, был ли получен ответ на последнюю высланную ему команду
|
Connected свойство: подключено ли устройство (лампа)? точнее, был ли получен ответ на последнюю высланную ему команду
|
||||||
State свойство: полученное командой GET состояние устройства (CURR...), список (не строка)
|
State свойство: полученное командой GET состояние устройства (CURR...), список (не строка)
|
||||||
Devices свойство: список устройств (хранимое свойство)
|
Devices свойство: список устройств (хранимое свойство)
|
||||||
CurrentDeviceSocket свойство: текущее устройство (хранимое свойство)
|
CurrentDeviceSocket свойство: текущее устройство (хранимое свойство)
|
||||||
|
FavoritesState свойство: текущее состояние избранных эффектов (вкл/выкл, интервал, разброс, список эффектов)
|
||||||
AlarmState свойство: текущее состояние будильников по дням (вкл/выкл, время каждого, время срабатывания перед "рассветом")
|
AlarmState свойство: текущее состояние будильников по дням (вкл/выкл, время каждого, время срабатывания перед "рассветом")
|
||||||
TimerState свойство: текущее состояние таймера (ответ команды TMR_GET)
|
TimerState свойство: текущее состояние таймера (ответ команды TMR_GET)
|
||||||
Modes свойство: список доступных режимов, захардкожен одновременно в лампе и в приложении, должен совпадать
|
Modes свойство: список доступных режимов, захардкожен одновременно в лампе и в приложении, должен совпадать
|
||||||
@@ -158,6 +178,14 @@ DeviceManager
|
|||||||
GetTimerTimeOption метод: получить выбранное пользователем значение предуст ановки времени таймера (из свойства TimerState)
|
GetTimerTimeOption метод: получить выбранное пользователем значение предуст ановки времени таймера (из свойства TimerState)
|
||||||
GetTimerRemainingSeconds метод: получить оставшееся до срабатывания таймера время (из свойства TimerState)
|
GetTimerRemainingSeconds метод: получить оставшееся до срабатывания таймера время (из свойства TimerState)
|
||||||
SetTimerSettings метод: отправить команду установки таймера TMR_SET
|
SetTimerSettings метод: отправить команду установки таймера TMR_SET
|
||||||
|
GetFavoriteSettings метод: отправить команду запроса состояния избранных эффектов FAV_GET на устройство
|
||||||
|
SetFavoriteSettings метод: отправить команду установки состояния избранных эффектов FAV_SET
|
||||||
|
GeFavoritesModeOnOff метод: получить состояние (включен/исключён в избранные) для заданного эффекта (из свойства FavoritesState)
|
||||||
|
SeFavoritesModeOnOff метод: установить состояние (включен/исключён в избранные) для заданного эффекта (из свойства FavoritesState)
|
||||||
|
GeFavoritesOnOff метод: получить состояние вкл/выкл режима избранных эффектов (из свойства FavoritesState)
|
||||||
|
GeFavoritesInterval метод: получить интервал времени смены избранных эффектов (из свойства FavoritesState)
|
||||||
|
GeFavoritesDispersion метод: получить разброс времени смены избранных эффектов (из свойства FavoritesState)
|
||||||
|
GeFavoritesModesList метод: получить список эффектов с указанным состояние (включен/исключён в избранные) для каждого из них
|
||||||
|
|
||||||
DiscoverManager
|
DiscoverManager
|
||||||
TimeoutMs свойство: время ожидания ответа от устройств на multicast команду DISCOVER
|
TimeoutMs свойство: время ожидания ответа от устройств на multicast команду DISCOVER
|
||||||
|
239
firmware/GyverLamp_v1.4/EepromManager.h
Normal file
239
firmware/GyverLamp_v1.4/EepromManager.h
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Схема использования EEPROM памяти:
|
||||||
|
* Используются адреса:
|
||||||
|
* Начало Длина Описание
|
||||||
|
* массив alarm
|
||||||
|
* 0 1 будильник пн вкл/выкл
|
||||||
|
* 1-2 2 будильник пн время в минутах от начала суток (0 - 1440), должно быть 2 байта
|
||||||
|
* 3 1 будильник вт вкл/выкл
|
||||||
|
* 4-5 2 будильник вт время в минутах от начала суток (0 - 1440), должно быть 2 байта
|
||||||
|
* 6 1 будильник ср вкл/выкл
|
||||||
|
* 7-8 2 будильник ср время в минутах от начала суток (0 - 1440), должно быть 2 байта
|
||||||
|
* 9 1 будильник чт вкл/выкл
|
||||||
|
* 10-11 2 будильник чт время в минутах от начала суток (0 - 1440), должно быть 2 байта
|
||||||
|
* 12 1 будильник пт вкл/выкл
|
||||||
|
* 13-14 2 будильник пт время в минутах от начала суток (0 - 1440), должно быть 2 байта
|
||||||
|
* 15 1 будильник сб вкл/выкл
|
||||||
|
* 16-17 2 будильник сб время в минутах от начала суток (0 - 1440), должно быть 2 байта
|
||||||
|
* 18 1 будильник вс вкл/выкл
|
||||||
|
* 19-20 2 будильник вс время в минутах от начала суток (0 - 1440), должно быть 2 байта
|
||||||
|
* массив modes
|
||||||
|
* 21-23 3 режим №1: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 24-26 3 режим №2: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 27-29 3 режим №3: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 30-32 3 режим №4: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 33-35 3 режим №5: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 36-38 3 режим №6: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 39-41 3 режим №7: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 42-44 3 режим №8: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 45-47 3 режим №9: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 48-50 3 режим №10: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 51-53 3 режим №11: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 54-56 3 режим №12: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 57-59 3 режим №13: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 60-62 3 режим №14: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 63-65 3 режим №15: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 66-68 3 режим №16: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 69-71 3 режим №17: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 72-74 3 режим №18: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 75-77 3 режим №19: яркость, скорость, масштаб (по одному байту)
|
||||||
|
* 78-80 3 режим №20: яркость, скорость, масштаб (по одному байту)
|
||||||
|
*
|
||||||
|
* 111-134 24 настройки режима избранных эффектов (интервал - 2 байта; разброс - 2 байта; вкл/выкл каждого эффекта - 20 (MODE_AMOUNT) байт; вкл/выкл не хранится в EEPROM)
|
||||||
|
*
|
||||||
|
* 198 1 признак первого запуска (определяет необходимость первоначальной записи всех хранимых настроек)
|
||||||
|
* 199 1 время до "рассвета" (dawnMode)
|
||||||
|
* 200 1 текущий режим (currentMode)
|
||||||
|
*
|
||||||
|
* Не используются адреса:
|
||||||
|
* 81-110 30 резерв, можно добавить ещё 10 эффектов
|
||||||
|
* 135-197 63 если добавить ещё 10 эффектов, начальный адрес неиспользуемой памяти сдвинется с 135 на 145
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <EEPROM.h>
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#define EEPROM_TOTAL_BYTES_USED (201U) // общий размер используемой EEPROM памяти (сумма всех хранимых настроек + 1 байт)
|
||||||
|
#define EEPROM_ALARM_START_ADDRESS (0U) // начальный адрес в EEPROM памяти для записи настроек будильников
|
||||||
|
#define EEPROM_MODES_START_ADDRESS (21U) // начальный адрес в EEPROM памяти для записи настроек эффектов (яркость, скорость, масштаб)
|
||||||
|
#define EEPROM_FAVORITES_START_ADDRESS (111U) // начальный адрес в EEPROM памяти для записи настроек режима избранных эффектов
|
||||||
|
#define EEPROM_FIRST_RUN_ADDRESS (198U) // адрес в EEPROM памяти для записи признака первого запуска (определяет необходимость первоначальной записи всех хранимых настроек)
|
||||||
|
#define EEPROM_DAWN_MODE_ADDRESS (199U) // адрес в EEPROM памяти для записи времени до "рассвета"
|
||||||
|
#define EEPROM_CURRENT_MODE_ADDRESS (200U) // адрес в EEPROM памяти для записи номера текущего эффекта лампы
|
||||||
|
|
||||||
|
#define EEPROM_ALARM_STRUCT_SIZE (3U) // 1 байт - вкл/выкл; 2 байта - время от начала суток в минутах (0 - 1440)
|
||||||
|
#define EEPROM_MODE_STRUCT_SIZE (3U) // 1 байт - яркость; 1 байт - скорость; 1 байт - масштаб
|
||||||
|
|
||||||
|
#define EEPROM_FIRST_RUN_MARK (22U) // счисло-метка, если ещё не записно в EEPROM_FIRST_RUN_ADDRESS, значит нужно проинициализировать EEPROM и записать все первоначальные настройки
|
||||||
|
#define EEPROM_WRITE_DELAY (30000UL) // отсрочка записи в EEPROM после последнего изменения хранимых настроек, позволяет уменьшить количество операций записи в EEPROM
|
||||||
|
|
||||||
|
|
||||||
|
class EepromManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void InitEepromSettings(ModeType modes[], AlarmType alarms[], uint8_t* dawnMode, int8_t* currentMode,
|
||||||
|
void (*readFavoritesSettings)(), void (*saveFavoritesSettings)())
|
||||||
|
{
|
||||||
|
// записываем в EEPROM начальное состояние настроек, если их там ещё нет
|
||||||
|
EEPROM.begin(EEPROM_TOTAL_BYTES_USED);
|
||||||
|
delay(50);
|
||||||
|
|
||||||
|
if (EEPROM.read(EEPROM_FIRST_RUN_ADDRESS) != EEPROM_FIRST_RUN_MARK)
|
||||||
|
{
|
||||||
|
EEPROM.write(EEPROM_FIRST_RUN_ADDRESS, EEPROM_FIRST_RUN_MARK);
|
||||||
|
EEPROM.commit();
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < MODE_AMOUNT; i++)
|
||||||
|
{
|
||||||
|
EEPROM.put(EEPROM_MODES_START_ADDRESS + EEPROM_ALARM_STRUCT_SIZE * i, modes[i]);
|
||||||
|
EEPROM.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
EEPROM.write(EEPROM_ALARM_START_ADDRESS + EEPROM_ALARM_STRUCT_SIZE * i, alarms[i].State);
|
||||||
|
WriteUint16(EEPROM_ALARM_START_ADDRESS + EEPROM_ALARM_STRUCT_SIZE * i + 1, alarms[i].Time);
|
||||||
|
EEPROM.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
EEPROM.write(EEPROM_DAWN_MODE_ADDRESS, 0);
|
||||||
|
EEPROM.write(EEPROM_CURRENT_MODE_ADDRESS, 0);
|
||||||
|
|
||||||
|
saveFavoritesSettings();
|
||||||
|
|
||||||
|
EEPROM.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// инициализируем настройки лампы значениями из EEPROM
|
||||||
|
for (uint8_t i = 0; i < MODE_AMOUNT; i++)
|
||||||
|
{
|
||||||
|
EEPROM.get(EEPROM_MODES_START_ADDRESS + EEPROM_MODE_STRUCT_SIZE * i, modes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
alarms[i].State = EEPROM.read(EEPROM_ALARM_START_ADDRESS + EEPROM_ALARM_STRUCT_SIZE * i);
|
||||||
|
alarms[i].Time = ReadInt16(EEPROM_ALARM_START_ADDRESS + EEPROM_ALARM_STRUCT_SIZE * i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
readFavoritesSettings();
|
||||||
|
|
||||||
|
*dawnMode = EEPROM.read(EEPROM_DAWN_MODE_ADDRESS);
|
||||||
|
*currentMode = EEPROM.read(EEPROM_CURRENT_MODE_ADDRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SaveModesSettings(int8_t* currentMode, ModeType modes[])
|
||||||
|
{
|
||||||
|
EEPROM.put(3 * (*currentMode) + EEPROM_MODES_START_ADDRESS, modes[*currentMode]);
|
||||||
|
EEPROM.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HandleEepromTick(bool* settChanged, uint32_t* eepromTimer, int8_t* currentMode, ModeType modes[], void (*saveFavoritesSettings)())
|
||||||
|
{
|
||||||
|
if (*settChanged && millis() - *eepromTimer > EEPROM_WRITE_DELAY)
|
||||||
|
{
|
||||||
|
*settChanged = false;
|
||||||
|
*eepromTimer = millis();
|
||||||
|
SaveModesSettings(currentMode, modes);
|
||||||
|
if (EEPROM.read(EEPROM_CURRENT_MODE_ADDRESS) != *currentMode)
|
||||||
|
{
|
||||||
|
EEPROM.write(EEPROM_CURRENT_MODE_ADDRESS, *currentMode);
|
||||||
|
}
|
||||||
|
saveFavoritesSettings();
|
||||||
|
EEPROM.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SaveAlarmsSettings(uint8_t* alarmNumber, AlarmType alarms[])
|
||||||
|
{
|
||||||
|
EEPROM.write(5 * (*alarmNumber), alarms[*alarmNumber].State);
|
||||||
|
WriteUint16((uint16_t)(5 * (*alarmNumber) + 1), alarms[*alarmNumber].Time);
|
||||||
|
EEPROM.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SaveDawnMode(uint8_t* dawnMode)
|
||||||
|
{
|
||||||
|
EEPROM.write(EEPROM_DAWN_MODE_ADDRESS, *dawnMode);
|
||||||
|
EEPROM.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t ReadUint16(uint16_t address)
|
||||||
|
{
|
||||||
|
uint16_t val;
|
||||||
|
uint8_t* p = (uint8_t*)&val;
|
||||||
|
*p = EEPROM.read(address);
|
||||||
|
*(p + 1) = EEPROM.read(address + 1);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteUint16(uint16_t address, uint16_t val)
|
||||||
|
{
|
||||||
|
uint8_t* p = (uint8_t*)&val;
|
||||||
|
EEPROM.write(address, *p);
|
||||||
|
EEPROM.write(address + 1, *(p + 1));
|
||||||
|
EEPROM.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int16_t ReadInt16(uint16_t address)
|
||||||
|
{
|
||||||
|
int16_t val;
|
||||||
|
uint8_t* p = (uint8_t*)&val;
|
||||||
|
*p = EEPROM.read(address);
|
||||||
|
*(p + 1) = EEPROM.read(address + 1);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteInt16(uint16_t address, int16_t val)
|
||||||
|
{
|
||||||
|
uint8_t* p = (uint8_t*)&val;
|
||||||
|
EEPROM.write(address, *p);
|
||||||
|
EEPROM.write(address + 1, *(p + 1));
|
||||||
|
EEPROM.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t ReadUint32(uint16_t address)
|
||||||
|
{
|
||||||
|
uint32_t val;
|
||||||
|
uint8_t* p = (uint8_t*)&val;
|
||||||
|
*p = EEPROM.read(address);
|
||||||
|
*(p + 1) = EEPROM.read(address + 1);
|
||||||
|
*(p + 2) = EEPROM.read(address + 2);
|
||||||
|
*(p + 3) = EEPROM.read(address + 3);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteUint32(uint16_t address, uint32_t val)
|
||||||
|
{
|
||||||
|
uint8_t* p = (uint8_t*)&val;
|
||||||
|
EEPROM.write(address, *p);
|
||||||
|
EEPROM.write(address + 1, *(p + 1));
|
||||||
|
EEPROM.write(address + 2, *(p + 2));
|
||||||
|
EEPROM.write(address + 3, *(p + 3));
|
||||||
|
EEPROM.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t ReadInt32(uint16_t address)
|
||||||
|
{
|
||||||
|
int32_t val;
|
||||||
|
uint8_t* p = (uint8_t*)&val;
|
||||||
|
*p = EEPROM.read(address);
|
||||||
|
*(p + 1) = EEPROM.read(address + 1);
|
||||||
|
*(p + 2) = EEPROM.read(address + 2);
|
||||||
|
*(p + 3) = EEPROM.read(address + 3);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteInt32(uint16_t address, int32_t val)
|
||||||
|
{
|
||||||
|
uint8_t* p = (uint8_t*)&val;
|
||||||
|
EEPROM.write(address, *p);
|
||||||
|
EEPROM.write(address + 1, *(p + 1));
|
||||||
|
EEPROM.write(address + 2, *(p + 2));
|
||||||
|
EEPROM.write(address + 3, *(p + 3));
|
||||||
|
EEPROM.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
245
firmware/GyverLamp_v1.4/FavoritesManager.h
Normal file
245
firmware/GyverLamp_v1.4/FavoritesManager.h
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <EEPROM.h>
|
||||||
|
#include "EepromManager.h"
|
||||||
|
|
||||||
|
#define DEFAULT_FAVORITES_INTERVAL (300U) // значение по умолчанию для интервала переключения избпранных эффектов в секундах
|
||||||
|
#define DEFAULT_FAVORITES_DISPERSION (0U) // значение по умолчанию для разброса интервала переключения избпранных эффектов в секундах
|
||||||
|
|
||||||
|
|
||||||
|
class FavoritesManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool FavoritesRunning; // флаг "работает режим автоматической смены избранных эффектов"
|
||||||
|
static uint16_t Interval; // статический интервал (время между сменами эффектов)
|
||||||
|
static uint16_t Dispersion; // дополнительный динамический (случайный) интервал (время между сменами эффектов)
|
||||||
|
static uint8_t FavoriteModes[MODE_AMOUNT]; // массив, каждый элемент которого соответствует флагу "эффект №... добавлен в избранные"
|
||||||
|
|
||||||
|
static void SetStatus(char* statusText) // помещает в statusText состояние режима работы избранных эффектов
|
||||||
|
{
|
||||||
|
char buff[6];
|
||||||
|
statusText = "FAV ";
|
||||||
|
|
||||||
|
statusText = strcat(statusText, FavoritesRunning ? "1" : "0");
|
||||||
|
statusText = strcat(statusText, " ");
|
||||||
|
|
||||||
|
itoa(Interval, buff, 10);
|
||||||
|
statusText = strcat(statusText, buff);
|
||||||
|
statusText = strcat(statusText, " ");
|
||||||
|
buff[0] = '\0';
|
||||||
|
|
||||||
|
itoa(Dispersion, buff, 10);
|
||||||
|
statusText = strcat(statusText, buff);
|
||||||
|
statusText = strcat(statusText, " ");
|
||||||
|
buff[0] = '\0';
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < MODE_AMOUNT; i++)
|
||||||
|
{
|
||||||
|
itoa((uint8_t)FavoriteModes[i], buff, 10);
|
||||||
|
statusText = strcat(statusText, buff);
|
||||||
|
if (i < MODE_AMOUNT - 1) statusText = strcat(statusText, " ");
|
||||||
|
buff[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
statusText = strcat(statusText, "\0");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ConfigureFavorites(const char* statusText) // принимает statusText, парсит его и инициализирует свойства класса значениями из statusText'а
|
||||||
|
{
|
||||||
|
FavoritesRunning = getFavoritesRunning(statusText);
|
||||||
|
Interval = getInterval(statusText);
|
||||||
|
Dispersion = getDispersion(statusText);
|
||||||
|
for (uint8_t i = 0; i < MODE_AMOUNT; i++)
|
||||||
|
{
|
||||||
|
FavoriteModes[i] = getModeOnOff(statusText, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool HandleFavorites( // функция, обрабатывающая циклическое переключение избранных эффектов; возвращает true, если эффект был переключен
|
||||||
|
bool* ONflag,
|
||||||
|
int8_t* currentMode,
|
||||||
|
bool* loadingFlag
|
||||||
|
#ifdef USE_NTP
|
||||||
|
, bool* dawnFlag
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!FavoritesRunning ||
|
||||||
|
!*ONflag // лампа не переключается на следующий эффект при выключенной матрице
|
||||||
|
#ifdef USE_NTP
|
||||||
|
|| *dawnFlag // лампа не переключается на следующий эффект при включенном будильнике
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextModeAt == 0) // лампа не переключается на следующий эффект сразу после включения режима избранных эффектов
|
||||||
|
{
|
||||||
|
nextModeAt = getNexTime();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (millis() >= nextModeAt)
|
||||||
|
{
|
||||||
|
*currentMode = getNextFavoriteMode(currentMode);
|
||||||
|
*loadingFlag = true;
|
||||||
|
nextModeAt = getNexTime();
|
||||||
|
|
||||||
|
#ifdef GENERAL_DEBUG
|
||||||
|
Serial.printf("Переключение на следующий избранный режим: %d\n\n", (*currentMode));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ReadFavoritesFromEeprom()
|
||||||
|
{
|
||||||
|
Interval = EepromManager::ReadUint16(EEPROM_FAVORITES_START_ADDRESS);
|
||||||
|
Dispersion = EepromManager::ReadUint16(EEPROM_FAVORITES_START_ADDRESS + 2);
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < MODE_AMOUNT; i++)
|
||||||
|
{
|
||||||
|
FavoriteModes[i] = EEPROM.read(EEPROM_FAVORITES_START_ADDRESS + i + 4);
|
||||||
|
FavoriteModes[i] = FavoriteModes[i] > 0 ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SaveFavoritesToEeprom()
|
||||||
|
{
|
||||||
|
// FavoritesRunning в EEPROM не сохраняем для экономии ресурса памяти
|
||||||
|
EepromManager::WriteUint16(EEPROM_FAVORITES_START_ADDRESS, Interval);
|
||||||
|
EepromManager::WriteUint16(EEPROM_FAVORITES_START_ADDRESS + 2, Dispersion);
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < MODE_AMOUNT; i++)
|
||||||
|
{
|
||||||
|
EEPROM.put(EEPROM_FAVORITES_START_ADDRESS + i + 4, FavoriteModes[i] > 0 ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
EEPROM.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static uint32_t nextModeAt; // ближайшее время переключения на следующий избранный эффект (millis())
|
||||||
|
|
||||||
|
static bool isStatusTextCorrect(const char* statusText) // валидирует statusText (проверяет, правильное ли коичество компонентов он содержит)
|
||||||
|
{
|
||||||
|
char buff[64];
|
||||||
|
strcpy(buff, statusText);
|
||||||
|
|
||||||
|
uint8_t lexCount = 0;
|
||||||
|
char* p = strtok(buff, " ");
|
||||||
|
while (p != NULL) // пока есть лексемы...
|
||||||
|
{
|
||||||
|
lexCount++;
|
||||||
|
p = strtok(NULL, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return lexCount == getStatusTextNormalComponentsCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t getStatusTextNormalComponentsCount() // возвращает правильное ли коичество компонентов для statusText в зависимости от определённого формата команды и количества эффектов
|
||||||
|
{
|
||||||
|
// "FAV 0/1 <цифра> <цифра> <массив цифр 0/1 для каждого режима>" (вкл/выкл, интервал в секундах, разброс в секундах, вкл/выкл каждого эффекта в избранные)
|
||||||
|
return
|
||||||
|
1 + // "FAV"
|
||||||
|
1 + // On/Off
|
||||||
|
1 + // интервал
|
||||||
|
1 + // разброс
|
||||||
|
MODE_AMOUNT; // 0/1 для каждого эффекта
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool getFavoritesRunning(const char* statusText) // возвращает признак вкл/выкл режима избранных эффектов из statusText
|
||||||
|
{
|
||||||
|
char lexem[2];
|
||||||
|
memset(lexem, 0, 2);
|
||||||
|
strcpy(lexem, getLexNo(statusText, 1));
|
||||||
|
return lexem != NULL
|
||||||
|
? !strcmp(lexem, "1")
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t getInterval(const char* statusText) // возвращает интервал (постоянную составляющую) переключения избранных эффектов из statusText
|
||||||
|
{
|
||||||
|
char lexem[6];
|
||||||
|
memset(lexem, 0, 6);
|
||||||
|
strcpy(lexem, getLexNo(statusText, 2));
|
||||||
|
return lexem != NULL
|
||||||
|
? atoi((const char*)lexem)
|
||||||
|
: DEFAULT_FAVORITES_INTERVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t getDispersion(const char* statusText) // возвращает разброс (случайную составляющую) интервала переключения избранных эффектов из statusText
|
||||||
|
{
|
||||||
|
char lexem[6];
|
||||||
|
memset(lexem, 0, 6);
|
||||||
|
strcpy(lexem, getLexNo(statusText, 3));
|
||||||
|
return lexem != NULL
|
||||||
|
? atoi((const char*)lexem)
|
||||||
|
: DEFAULT_FAVORITES_DISPERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool getModeOnOff(const char* statusText, uint8_t modeId) // возвращает признак включения указанного эффекта в избранные эффекты
|
||||||
|
{
|
||||||
|
char lexem[2];
|
||||||
|
memset(lexem, 0, 2);
|
||||||
|
strcpy(lexem, getLexNo(statusText, modeId + 4));
|
||||||
|
return lexem != NULL
|
||||||
|
? !strcmp(lexem, "1")
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* getLexNo(const char* statusText, uint8_t pos) // служебная функция, разбивает команду statusText на лексемы ("слова", разделённые пробелами) и возвращает указанную по счёту лексему
|
||||||
|
{
|
||||||
|
if (!isStatusTextCorrect(statusText))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t buffSize = 64;
|
||||||
|
char buff[buffSize];
|
||||||
|
memset(buff, 0, buffSize);
|
||||||
|
strcpy(buff, statusText);
|
||||||
|
|
||||||
|
uint8_t lexPos = 0;
|
||||||
|
char* p = strtok(buff, " ");
|
||||||
|
while (p != NULL) // пока есть лексемы...
|
||||||
|
{
|
||||||
|
if (lexPos == pos)
|
||||||
|
{
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = strtok(NULL, " ");
|
||||||
|
lexPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t getNextFavoriteMode(int8_t* currentMode) // возвращает следующий (случайный) включенный в избранные эффект
|
||||||
|
{
|
||||||
|
int8_t result = *currentMode;
|
||||||
|
|
||||||
|
for (int8_t tryNo = 0; tryNo <= random(0, MODE_AMOUNT); tryNo++)// случайное количество попыток определения следующего эффекта; без этого будет выбран следующий (избранный) по порядку после текущего
|
||||||
|
{
|
||||||
|
for (uint8_t i = (result + 1); i <= (result + MODE_AMOUNT); i++)
|
||||||
|
{
|
||||||
|
if (FavoriteModes[i < MODE_AMOUNT ? i : i - MODE_AMOUNT] > 0)
|
||||||
|
{
|
||||||
|
result = i < MODE_AMOUNT ? i : i - MODE_AMOUNT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t getNexTime() // определяет время следующего переключения на следующий избранный эффект
|
||||||
|
{
|
||||||
|
return millis() + Interval * 1000 + random(0, Dispersion + 1) * 1000;
|
||||||
|
}
|
||||||
|
};
|
@@ -44,6 +44,9 @@
|
|||||||
- Добавлено взаимодействие с android приложением по управлению будильниками
|
- Добавлено взаимодействие с android приложением по управлению будильниками
|
||||||
--- 14.08.2019
|
--- 14.08.2019
|
||||||
- Добавлена функция таймера отключения
|
- Добавлена функция таймера отключения
|
||||||
|
--- 26.08.2019
|
||||||
|
- Добавлен режим автоматического переключения избранных эффектов
|
||||||
|
- Реорганизован код, исправлены ошибки
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Ссылка для менеджера плат:
|
// Ссылка для менеджера плат:
|
||||||
@@ -112,6 +115,7 @@ uint8_t AP_STATIC_IP[] = {192, 168, 4, 1}; // статичес
|
|||||||
#define FASTLED_ALLOW_INTERRUPTS (0U)
|
#define FASTLED_ALLOW_INTERRUPTS (0U)
|
||||||
#define FASTLED_ESP8266_RAW_PIN_ORDER
|
#define FASTLED_ESP8266_RAW_PIN_ORDER
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
#include "timerMinim.h"
|
#include "timerMinim.h"
|
||||||
#include <FastLED.h>
|
#include <FastLED.h>
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
@@ -130,6 +134,8 @@ uint8_t AP_STATIC_IP[] = {192, 168, 4, 1}; // статичес
|
|||||||
#include "OtaManager.h"
|
#include "OtaManager.h"
|
||||||
#endif
|
#endif
|
||||||
#include "TimerManager.h"
|
#include "TimerManager.h"
|
||||||
|
#include "FavoritesManager.h"
|
||||||
|
#include "EepromManager.h"
|
||||||
|
|
||||||
// --- ИНИЦИАЛИЗАЦИЯ ОБЪЕКТОВ ----------
|
// --- ИНИЦИАЛИЗАЦИЯ ОБЪЕКТОВ ----------
|
||||||
CRGB leds[NUM_LEDS];
|
CRGB leds[NUM_LEDS];
|
||||||
@@ -158,34 +164,25 @@ char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; // buffer to hold in
|
|||||||
String inputBuffer;
|
String inputBuffer;
|
||||||
static const uint8_t maxDim = max(WIDTH, HEIGHT);
|
static const uint8_t maxDim = max(WIDTH, HEIGHT);
|
||||||
|
|
||||||
struct
|
ModeType modes[MODE_AMOUNT];
|
||||||
{
|
AlarmType alarms[7];
|
||||||
uint8_t brightness = 50;
|
|
||||||
uint8_t speed = 30;
|
|
||||||
uint8_t scale = 40;
|
|
||||||
} modes[MODE_AMOUNT];
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
boolean state = false;
|
|
||||||
int16_t time = 0;
|
|
||||||
} alarm[7];
|
|
||||||
|
|
||||||
uint8_t dawnOffsets[] = {5, 10, 15, 20, 25, 30, 40, 50, 60};// опции для выпадающего списка параметра "время перед 'рассветом'" (будильник)
|
uint8_t dawnOffsets[] = {5, 10, 15, 20, 25, 30, 40, 50, 60};// опции для выпадающего списка параметра "время перед 'рассветом'" (будильник)
|
||||||
uint8_t dawnMode;
|
uint8_t dawnMode;
|
||||||
boolean dawnFlag = false;
|
bool dawnFlag = false;
|
||||||
long thisTime;
|
long thisTime;
|
||||||
boolean manualOff = false;
|
bool manualOff = false;
|
||||||
|
|
||||||
int8_t currentMode = 0;
|
int8_t currentMode = 0;
|
||||||
boolean loadingFlag = true;
|
bool loadingFlag = true;
|
||||||
boolean ONflag = true;
|
bool ONflag = true;
|
||||||
uint32_t eepromTimer;
|
uint32_t eepromTimer;
|
||||||
boolean settChanged = false;
|
bool settChanged = false;
|
||||||
|
|
||||||
// Конфетти, Огонь, Радуга верт., Радуга гориз., Смена цвета,
|
// Конфетти, Огонь, Радуга вертикальная, Радуга горизонтальная, Смена цвета,
|
||||||
// Безумие 3D, Облака 3D, Лава 3D, Плазма 3D, Радуга 3D,
|
// Безумие 3D, Облака 3D, Лава 3D, Плазма 3D, Радуга 3D,
|
||||||
// Павлин 3D, Зебра 3D, Лес 3D, Океан 3D,
|
// Павлин 3D, Зебра 3D, Лес 3D, Океан 3D,
|
||||||
|
// Цвет, Снег, Матрица, Светлячки, Светлячки со шлейфом, Белый свет
|
||||||
|
|
||||||
unsigned char matrixValue[8][16];
|
unsigned char matrixValue[8][16];
|
||||||
|
|
||||||
@@ -194,6 +191,12 @@ bool TimerManager::TimerHasFired = false;
|
|||||||
uint8_t TimerManager::TimerOption = 1U;
|
uint8_t TimerManager::TimerOption = 1U;
|
||||||
uint64_t TimerManager::TimeToFire = 0ULL;
|
uint64_t TimerManager::TimeToFire = 0ULL;
|
||||||
|
|
||||||
|
bool FavoritesManager::FavoritesRunning = false;
|
||||||
|
uint16_t FavoritesManager::Interval = DEFAULT_FAVORITES_INTERVAL;
|
||||||
|
uint16_t FavoritesManager::Dispersion = DEFAULT_FAVORITES_DISPERSION;
|
||||||
|
uint8_t FavoritesManager::FavoriteModes[MODE_AMOUNT] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
uint32_t FavoritesManager::nextModeAt = 0UL;
|
||||||
|
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
@@ -286,47 +289,12 @@ void setup()
|
|||||||
Serial.printf("Порт UDP сервера: %u\n", localPort);
|
Serial.printf("Порт UDP сервера: %u\n", localPort);
|
||||||
Udp.begin(localPort);
|
Udp.begin(localPort);
|
||||||
|
|
||||||
// EEPROM
|
EepromManager::InitEepromSettings( // инициализация EEPROM; запись начального состояния настроек, если их там ещё нет; инициализация настроек лампы значениями из EEPROM
|
||||||
EEPROM.begin(202);
|
modes, alarms, &dawnMode, ¤tMode,
|
||||||
delay(50);
|
&(FavoritesManager::ReadFavoritesFromEeprom),
|
||||||
if (EEPROM.read(198) != 20) // первый запуск
|
&(FavoritesManager::SaveFavoritesToEeprom));
|
||||||
{
|
|
||||||
EEPROM.write(198, 20);
|
|
||||||
EEPROM.commit();
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < MODE_AMOUNT; i++)
|
sendCurrent(); // отправляем настройки (куда?)
|
||||||
{
|
|
||||||
EEPROM.put(3 * i + 40, modes[i]);
|
|
||||||
EEPROM.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 7; i++)
|
|
||||||
{
|
|
||||||
EEPROM.write(5 * i, alarm[i].state); // рассвет
|
|
||||||
eeWriteInt(5 * i + 1, alarm[i].time);
|
|
||||||
EEPROM.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
EEPROM.write(199, 0); // рассвет
|
|
||||||
EEPROM.write(200, 0); // режим
|
|
||||||
EEPROM.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < MODE_AMOUNT; i++)
|
|
||||||
{
|
|
||||||
EEPROM.get(3 * i + 40, modes[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 7; i++)
|
|
||||||
{
|
|
||||||
alarm[i].state = EEPROM.read(5 * i);
|
|
||||||
alarm[i].time = eeGetInt(5 * i + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
dawnMode = EEPROM.read(199);
|
|
||||||
currentMode = (int8_t)EEPROM.read(200);
|
|
||||||
|
|
||||||
sendCurrent(); // отправляем настройки
|
|
||||||
char reply[inputBuffer.length() + 1];
|
char reply[inputBuffer.length() + 1];
|
||||||
inputBuffer.toCharArray(reply, inputBuffer.length() + 1);
|
inputBuffer.toCharArray(reply, inputBuffer.length() + 1);
|
||||||
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
|
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
|
||||||
@@ -347,7 +315,7 @@ void loop()
|
|||||||
{
|
{
|
||||||
parseUDP();
|
parseUDP();
|
||||||
effectsTick();
|
effectsTick();
|
||||||
eepromTick();
|
EepromManager::HandleEepromTick(&settChanged, &eepromTimer, ¤tMode, modes, &(FavoritesManager::SaveFavoritesToEeprom));
|
||||||
#ifdef USE_NTP
|
#ifdef USE_NTP
|
||||||
timeTick();
|
timeTick();
|
||||||
#endif
|
#endif
|
||||||
@@ -358,29 +326,19 @@ void loop()
|
|||||||
otaManager.HandleOtaUpdate(); // ожидание и обработка команды на обновление прошивки по воздуху
|
otaManager.HandleOtaUpdate(); // ожидание и обработка команды на обновление прошивки по воздуху
|
||||||
#endif
|
#endif
|
||||||
TimerManager::HandleTimer(&ONflag, &changePower); // обработка событий таймера отключения лампы
|
TimerManager::HandleTimer(&ONflag, &changePower); // обработка событий таймера отключения лампы
|
||||||
|
if (FavoritesManager::HandleFavorites( // обработка режима избранных эффектов
|
||||||
|
&ONflag,
|
||||||
|
¤tMode,
|
||||||
|
&loadingFlag
|
||||||
|
#ifdef USE_NTP
|
||||||
|
, &dawnFlag
|
||||||
|
#endif
|
||||||
|
))
|
||||||
|
{
|
||||||
|
FastLED.setBrightness(modes[currentMode].Brightness);
|
||||||
|
FastLED.clear();
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
ESP.wdtFeed(); // пнуть собаку
|
ESP.wdtFeed(); // пнуть собаку
|
||||||
yield(); // обработать все "служебные" задачи: WiFi подключение и т.д.
|
yield(); // обработать все "служебные" задачи: wdt, WiFi подключение и т.д. (?)
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void eeWriteInt(int16_t pos, int16_t val)
|
|
||||||
{
|
|
||||||
uint8_t* p = (uint8_t*) &val;
|
|
||||||
EEPROM.write(pos, *p);
|
|
||||||
EEPROM.write(pos + 1, *(p + 1));
|
|
||||||
EEPROM.write(pos + 2, *(p + 2));
|
|
||||||
EEPROM.write(pos + 3, *(p + 3));
|
|
||||||
EEPROM.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int16_t eeGetInt(int16_t pos)
|
|
||||||
{
|
|
||||||
int16_t val;
|
|
||||||
uint8_t* p = (uint8_t*) &val;
|
|
||||||
*p = EEPROM.read(pos);
|
|
||||||
*(p + 1) = EEPROM.read(pos + 1);
|
|
||||||
*(p + 2) = EEPROM.read(pos + 2);
|
|
||||||
*(p + 3) = EEPROM.read(pos + 3);
|
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
/*
|
/*
|
||||||
* 11.07.2019
|
* 11.07.2019
|
||||||
* Класс, который отслеживает действия пользователя по запросу обновления прошивки по воздуху и выполняет эту прошивку.
|
* Класс, который отслеживает действия пользователя по запросу обновления прошивки по воздуху и выполняет эту прошивку.
|
||||||
|
@@ -1,3 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
class TimerManager
|
class TimerManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
15
firmware/GyverLamp_v1.4/Types.h
Normal file
15
firmware/GyverLamp_v1.4/Types.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
struct AlarmType
|
||||||
|
{
|
||||||
|
bool State = false;
|
||||||
|
uint16_t Time = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ModeType
|
||||||
|
{
|
||||||
|
uint8_t Brightness = 50;
|
||||||
|
uint8_t Speed = 30;
|
||||||
|
uint8_t Scale = 40;
|
||||||
|
};
|
@@ -1,5 +1,5 @@
|
|||||||
#ifdef ESP_USE_BUTTON
|
#ifdef ESP_USE_BUTTON
|
||||||
boolean brightDirection;
|
bool brightDirection;
|
||||||
|
|
||||||
void buttonTick()
|
void buttonTick()
|
||||||
{
|
{
|
||||||
@@ -11,7 +11,7 @@ void buttonTick()
|
|||||||
manualOff = true;
|
manualOff = true;
|
||||||
dawnFlag = false;
|
dawnFlag = false;
|
||||||
loadingFlag = true;
|
loadingFlag = true;
|
||||||
FastLED.setBrightness(modes[currentMode].brightness);
|
FastLED.setBrightness(modes[currentMode].Brightness);
|
||||||
changePower();
|
changePower();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -24,7 +24,7 @@ void buttonTick()
|
|||||||
if (ONflag && touch.isDouble())
|
if (ONflag && touch.isDouble())
|
||||||
{
|
{
|
||||||
if (++currentMode >= MODE_AMOUNT) currentMode = 0;
|
if (++currentMode >= MODE_AMOUNT) currentMode = 0;
|
||||||
FastLED.setBrightness(modes[currentMode].brightness);
|
FastLED.setBrightness(modes[currentMode].Brightness);
|
||||||
loadingFlag = true;
|
loadingFlag = true;
|
||||||
settChanged = true;
|
settChanged = true;
|
||||||
eepromTimer = millis();
|
eepromTimer = millis();
|
||||||
@@ -35,7 +35,7 @@ void buttonTick()
|
|||||||
if (ONflag && touch.isTriple())
|
if (ONflag && touch.isTriple())
|
||||||
{
|
{
|
||||||
if (--currentMode < 0) currentMode = MODE_AMOUNT - 1;
|
if (--currentMode < 0) currentMode = MODE_AMOUNT - 1;
|
||||||
FastLED.setBrightness(modes[currentMode].brightness);
|
FastLED.setBrightness(modes[currentMode].Brightness);
|
||||||
loadingFlag = true;
|
loadingFlag = true;
|
||||||
settChanged = true;
|
settChanged = true;
|
||||||
eepromTimer = millis();
|
eepromTimer = millis();
|
||||||
@@ -64,22 +64,22 @@ void buttonTick()
|
|||||||
{
|
{
|
||||||
if (brightDirection)
|
if (brightDirection)
|
||||||
{
|
{
|
||||||
if (modes[currentMode].brightness < 10) modes[currentMode].brightness += 1;
|
if (modes[currentMode].Brightness < 10) modes[currentMode].Brightness += 1;
|
||||||
else if (modes[currentMode].brightness < 250) modes[currentMode].brightness += 5;
|
else if (modes[currentMode].Brightness < 250) modes[currentMode].Brightness += 5;
|
||||||
else modes[currentMode].brightness = 255;
|
else modes[currentMode].Brightness = 255;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (modes[currentMode].brightness > 15) modes[currentMode].brightness -= 5;
|
if (modes[currentMode].Brightness > 15) modes[currentMode].Brightness -= 5;
|
||||||
else if (modes[currentMode].brightness > 1) modes[currentMode].brightness -= 1;
|
else if (modes[currentMode].Brightness > 1) modes[currentMode].Brightness -= 1;
|
||||||
else modes[currentMode].brightness = 0;
|
else modes[currentMode].Brightness = 0;
|
||||||
}
|
}
|
||||||
FastLED.setBrightness(modes[currentMode].brightness);
|
FastLED.setBrightness(modes[currentMode].Brightness);
|
||||||
settChanged = true;
|
settChanged = true;
|
||||||
eepromTimer = millis();
|
eepromTimer = millis();
|
||||||
|
|
||||||
#ifdef GENERAL_DEBUG
|
#ifdef GENERAL_DEBUG
|
||||||
Serial.printf("New brightness value: %d\n", modes[currentMode].brightness);
|
Serial.printf("New brightness value: %d\n", modes[currentMode].Brightness);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,30 +0,0 @@
|
|||||||
void saveEEPROM()
|
|
||||||
{
|
|
||||||
EEPROM.put(3 * currentMode + 40, modes[currentMode]);
|
|
||||||
EEPROM.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void eepromTick()
|
|
||||||
{
|
|
||||||
if (settChanged && millis() - eepromTimer > 30000)
|
|
||||||
{
|
|
||||||
settChanged = false;
|
|
||||||
eepromTimer = millis();
|
|
||||||
saveEEPROM();
|
|
||||||
if (EEPROM.read(200) != currentMode) EEPROM.write(200, currentMode);
|
|
||||||
EEPROM.commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveAlarm(byte almNumber)
|
|
||||||
{
|
|
||||||
EEPROM.write(5 * almNumber, alarm[almNumber].state); // рассвет
|
|
||||||
eeWriteInt(5 * almNumber + 1, alarm[almNumber].time);
|
|
||||||
EEPROM.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveDawnMmode()
|
|
||||||
{
|
|
||||||
EEPROM.write(199, dawnMode); // рассвет
|
|
||||||
EEPROM.commit();
|
|
||||||
}
|
|
@@ -4,51 +4,32 @@ void effectsTick()
|
|||||||
{
|
{
|
||||||
if (!dawnFlag)
|
if (!dawnFlag)
|
||||||
{
|
{
|
||||||
if (ONflag && (millis() - effTimer >= ((currentMode < 5 || currentMode > 13) ? modes[currentMode].speed : 50)))
|
if (ONflag && (millis() - effTimer >= ((currentMode < 5 || currentMode > 13) ? modes[currentMode].Speed : 50)))
|
||||||
{
|
{
|
||||||
effTimer = millis();
|
effTimer = millis();
|
||||||
switch (currentMode)
|
switch (currentMode)
|
||||||
{
|
{
|
||||||
case 0: sparklesRoutine();
|
case 0: sparklesRoutine(); break;
|
||||||
break;
|
case 1: fireRoutine(); break;
|
||||||
case 1: fireRoutine();
|
case 2: rainbowVertical(); break;
|
||||||
break;
|
case 3: rainbowHorizontal(); break;
|
||||||
case 2: rainbowVertical();
|
case 4: colorsRoutine(); break;
|
||||||
break;
|
case 5: madnessNoise(); break;
|
||||||
case 3: rainbowHorizontal();
|
case 6: cloudNoise(); break;
|
||||||
break;
|
case 7: lavaNoise(); break;
|
||||||
case 4: colorsRoutine();
|
case 8: plasmaNoise(); break;
|
||||||
break;
|
case 9: rainbowNoise(); break;
|
||||||
case 5: madnessNoise();
|
case 10: rainbowStripeNoise(); break;
|
||||||
break;
|
case 11: zebraNoise(); break;
|
||||||
case 6: cloudNoise();
|
case 12: forestNoise(); break;
|
||||||
break;
|
case 13: oceanNoise(); break;
|
||||||
case 7: lavaNoise();
|
case 14: colorRoutine(); break;
|
||||||
break;
|
case 15: snowRoutine(); break;
|
||||||
case 8: plasmaNoise();
|
case 16: matrixRoutine(); break;
|
||||||
break;
|
case 17: lightersRoutine(); break;
|
||||||
case 9: rainbowNoise();
|
case 18: lightBalls(); break;
|
||||||
break;
|
case 19: whiteColor(); break;
|
||||||
case 10: rainbowStripeNoise();
|
default: break;
|
||||||
break;
|
|
||||||
case 11: zebraNoise();
|
|
||||||
break;
|
|
||||||
case 12: forestNoise();
|
|
||||||
break;
|
|
||||||
case 13: oceanNoise();
|
|
||||||
break;
|
|
||||||
case 14: colorRoutine();
|
|
||||||
break;
|
|
||||||
case 15: snowRoutine();
|
|
||||||
break;
|
|
||||||
case 16: matrixRoutine();
|
|
||||||
break;
|
|
||||||
case 17: lightersRoutine();
|
|
||||||
break;
|
|
||||||
case 18: lightBalls();
|
|
||||||
break;
|
|
||||||
case 19: whiteColor();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
}
|
}
|
||||||
@@ -60,20 +41,20 @@ void changePower()
|
|||||||
if (ONflag)
|
if (ONflag)
|
||||||
{
|
{
|
||||||
effectsTick();
|
effectsTick();
|
||||||
for (uint8_t i = 0; i < modes[currentMode].brightness; i = constrain(i + 8, 0, modes[currentMode].brightness))
|
for (uint8_t i = 0; i < modes[currentMode].Brightness; i = constrain(i + 8, 0, modes[currentMode].Brightness))
|
||||||
{
|
{
|
||||||
FastLED.setBrightness(i);
|
FastLED.setBrightness(i);
|
||||||
delay(1);
|
delay(1);
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
}
|
}
|
||||||
FastLED.setBrightness(modes[currentMode].brightness);
|
FastLED.setBrightness(modes[currentMode].Brightness);
|
||||||
delay(2);
|
delay(2);
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
effectsTick();
|
effectsTick();
|
||||||
for (uint8_t i = modes[currentMode].brightness; i > 0; i = constrain(i - 8, 0, modes[currentMode].brightness))
|
for (uint8_t i = modes[currentMode].Brightness; i > 0; i = constrain(i - 8, 0, modes[currentMode].Brightness))
|
||||||
{
|
{
|
||||||
FastLED.setBrightness(i);
|
FastLED.setBrightness(i);
|
||||||
delay(1);
|
delay(1);
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
// ------------- конфетти --------------
|
// ------------- конфетти --------------
|
||||||
void sparklesRoutine()
|
void sparklesRoutine()
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; i < modes[0].scale; i++)
|
for (uint8_t i = 0; i < modes[0].Scale; i++)
|
||||||
{
|
{
|
||||||
uint8_t x = random(0, WIDTH);
|
uint8_t x = random(0, WIDTH);
|
||||||
uint8_t y = random(0, HEIGHT);
|
uint8_t y = random(0, HEIGHT);
|
||||||
@@ -144,7 +144,7 @@ void drawFrame(int32_t pcnt)
|
|||||||
- pgm_read_byte(&(valueMask[y][newX]));
|
- pgm_read_byte(&(valueMask[y][newX]));
|
||||||
|
|
||||||
CRGB color = CHSV(
|
CRGB color = CHSV(
|
||||||
modes[1].scale * 2.5 + pgm_read_byte(&(hueMask[y][newX])), // H
|
modes[1].Scale * 2.5 + pgm_read_byte(&(hueMask[y][newX])), // H
|
||||||
255, // S
|
255, // S
|
||||||
(uint8_t)max(0, nextv) // V
|
(uint8_t)max(0, nextv) // V
|
||||||
);
|
);
|
||||||
@@ -172,7 +172,7 @@ void drawFrame(int32_t pcnt)
|
|||||||
uint8_t newX = x;
|
uint8_t newX = x;
|
||||||
if (x > 15) newX = x - 15;
|
if (x > 15) newX = x - 15;
|
||||||
CRGB color = CHSV(
|
CRGB color = CHSV(
|
||||||
modes[1].scale * 2.5 + pgm_read_byte(&(hueMask[0][newX])), // H
|
modes[1].Scale * 2.5 + pgm_read_byte(&(hueMask[0][newX])), // H
|
||||||
255, // S
|
255, // S
|
||||||
(uint8_t)(((100.0 - pcnt) * matrixValue[0][newX] + pcnt * line[newX]) / 100.0) // V
|
(uint8_t)(((100.0 - pcnt) * matrixValue[0][newX] + pcnt * line[newX]) / 100.0) // V
|
||||||
);
|
);
|
||||||
@@ -187,7 +187,7 @@ void rainbowVertical()
|
|||||||
hue += 2;
|
hue += 2;
|
||||||
for (uint8_t j = 0; j < HEIGHT; j++)
|
for (uint8_t j = 0; j < HEIGHT; j++)
|
||||||
{
|
{
|
||||||
CHSV thisColor = CHSV((uint8_t)(hue + j * modes[2].scale), 255, 255);
|
CHSV thisColor = CHSV((uint8_t)(hue + j * modes[2].Scale), 255, 255);
|
||||||
for (uint8_t i = 0; i < WIDTH; i++)
|
for (uint8_t i = 0; i < WIDTH; i++)
|
||||||
drawPixelXY(i, j, thisColor);
|
drawPixelXY(i, j, thisColor);
|
||||||
}
|
}
|
||||||
@@ -198,7 +198,7 @@ void rainbowHorizontal()
|
|||||||
hue += 2;
|
hue += 2;
|
||||||
for (uint8_t i = 0; i < WIDTH; i++)
|
for (uint8_t i = 0; i < WIDTH; i++)
|
||||||
{
|
{
|
||||||
CHSV thisColor = CHSV((uint8_t)(hue + i * modes[3].scale), 255, 255);
|
CHSV thisColor = CHSV((uint8_t)(hue + i * modes[3].Scale), 255, 255);
|
||||||
for (uint8_t j = 0; j < HEIGHT; j++)
|
for (uint8_t j = 0; j < HEIGHT; j++)
|
||||||
drawPixelXY(i, j, thisColor); //leds[getPixelNumber(i, j)] = thisColor;
|
drawPixelXY(i, j, thisColor); //leds[getPixelNumber(i, j)] = thisColor;
|
||||||
}
|
}
|
||||||
@@ -207,7 +207,7 @@ void rainbowHorizontal()
|
|||||||
// ------------- цвета -----------------
|
// ------------- цвета -----------------
|
||||||
void colorsRoutine()
|
void colorsRoutine()
|
||||||
{
|
{
|
||||||
hue += modes[4].scale;
|
hue += modes[4].Scale;
|
||||||
for (int32_t i = 0; i < NUM_LEDS; i++)
|
for (int32_t i = 0; i < NUM_LEDS; i++)
|
||||||
{
|
{
|
||||||
leds[i] = CHSV(hue, 255, 255);
|
leds[i] = CHSV(hue, 255, 255);
|
||||||
@@ -219,7 +219,7 @@ void colorRoutine()
|
|||||||
{
|
{
|
||||||
for (int32_t i = 0; i < NUM_LEDS; i++)
|
for (int32_t i = 0; i < NUM_LEDS; i++)
|
||||||
{
|
{
|
||||||
leds[i] = CHSV(modes[14].scale * 2.5, 255, 255);
|
leds[i] = CHSV(modes[14].Scale * 2.5, 255, 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +239,7 @@ void snowRoutine()
|
|||||||
{
|
{
|
||||||
// заполняем случайно верхнюю строку
|
// заполняем случайно верхнюю строку
|
||||||
// а также не даём двум блокам по вертикали вместе быть
|
// а также не даём двум блокам по вертикали вместе быть
|
||||||
if (getPixColorXY(x, HEIGHT - 2) == 0 && (random(0, 100 - modes[15].scale) == 0))
|
if (getPixColorXY(x, HEIGHT - 2) == 0 && (random(0, 100 - modes[15].Scale) == 0))
|
||||||
drawPixelXY(x, HEIGHT - 1, 0xE0FFFF - 0x101010 * random(0, 4));
|
drawPixelXY(x, HEIGHT - 1, 0xE0FFFF - 0x101010 * random(0, 4));
|
||||||
else
|
else
|
||||||
drawPixelXY(x, HEIGHT - 1, 0x000000);
|
drawPixelXY(x, HEIGHT - 1, 0x000000);
|
||||||
@@ -254,7 +254,7 @@ void matrixRoutine()
|
|||||||
// заполняем случайно верхнюю строку
|
// заполняем случайно верхнюю строку
|
||||||
uint32_t thisColor = getPixColorXY(x, HEIGHT - 1);
|
uint32_t thisColor = getPixColorXY(x, HEIGHT - 1);
|
||||||
if (thisColor == 0)
|
if (thisColor == 0)
|
||||||
drawPixelXY(x, HEIGHT - 1, 0x00FF00 * (random(0, 100 - modes[16].scale) == 0));
|
drawPixelXY(x, HEIGHT - 1, 0x00FF00 * (random(0, 100 - modes[16].Scale) == 0));
|
||||||
else if (thisColor < 0x002000)
|
else if (thisColor < 0x002000)
|
||||||
drawPixelXY(x, HEIGHT - 1, 0);
|
drawPixelXY(x, HEIGHT - 1, 0);
|
||||||
else
|
else
|
||||||
@@ -299,7 +299,7 @@ void lightersRoutine()
|
|||||||
}
|
}
|
||||||
FastLED.clear();
|
FastLED.clear();
|
||||||
if (++loopCounter > 20) loopCounter = 0;
|
if (++loopCounter > 20) loopCounter = 0;
|
||||||
for (uint8_t i = 0; i < modes[17].scale; i++)
|
for (uint8_t i = 0; i < modes[17].Scale; i++)
|
||||||
{
|
{
|
||||||
if (loopCounter == 0) // меняем скорость каждые 255 отрисовок
|
if (loopCounter == 0) // меняем скорость каждые 255 отрисовок
|
||||||
{
|
{
|
||||||
|
@@ -37,8 +37,8 @@ void madnessNoise()
|
|||||||
if (loadingFlag)
|
if (loadingFlag)
|
||||||
{
|
{
|
||||||
loadingFlag = false;
|
loadingFlag = false;
|
||||||
scale = modes[5].scale;
|
scale = modes[5].Scale;
|
||||||
speed = modes[5].speed;
|
speed = modes[5].Speed;
|
||||||
}
|
}
|
||||||
fillnoise8();
|
fillnoise8();
|
||||||
for (uint8_t i = 0; i < WIDTH; i++)
|
for (uint8_t i = 0; i < WIDTH; i++)
|
||||||
@@ -58,8 +58,8 @@ void rainbowNoise()
|
|||||||
{
|
{
|
||||||
loadingFlag = false;
|
loadingFlag = false;
|
||||||
currentPalette = RainbowColors_p;
|
currentPalette = RainbowColors_p;
|
||||||
scale = modes[9].scale;
|
scale = modes[9].Scale;
|
||||||
speed = modes[9].speed;
|
speed = modes[9].Speed;
|
||||||
colorLoop = 1;
|
colorLoop = 1;
|
||||||
}
|
}
|
||||||
fillNoiseLED();
|
fillNoiseLED();
|
||||||
@@ -71,8 +71,8 @@ void rainbowStripeNoise()
|
|||||||
{
|
{
|
||||||
loadingFlag = false;
|
loadingFlag = false;
|
||||||
currentPalette = RainbowStripeColors_p;
|
currentPalette = RainbowStripeColors_p;
|
||||||
scale = modes[10].scale;
|
scale = modes[10].Scale;
|
||||||
speed = modes[10].speed;
|
speed = modes[10].Speed;
|
||||||
colorLoop = 1;
|
colorLoop = 1;
|
||||||
}
|
}
|
||||||
fillNoiseLED();
|
fillNoiseLED();
|
||||||
@@ -90,8 +90,8 @@ void zebraNoise()
|
|||||||
currentPalette[4] = CRGB::White;
|
currentPalette[4] = CRGB::White;
|
||||||
currentPalette[8] = CRGB::White;
|
currentPalette[8] = CRGB::White;
|
||||||
currentPalette[12] = CRGB::White;
|
currentPalette[12] = CRGB::White;
|
||||||
scale = modes[11].scale;
|
scale = modes[11].Scale;
|
||||||
speed = modes[11].speed;
|
speed = modes[11].Speed;
|
||||||
colorLoop = 1;
|
colorLoop = 1;
|
||||||
}
|
}
|
||||||
fillNoiseLED();
|
fillNoiseLED();
|
||||||
@@ -103,8 +103,8 @@ void forestNoise()
|
|||||||
{
|
{
|
||||||
loadingFlag = false;
|
loadingFlag = false;
|
||||||
currentPalette = ForestColors_p;
|
currentPalette = ForestColors_p;
|
||||||
scale = modes[12].scale;
|
scale = modes[12].Scale;
|
||||||
speed = modes[12].speed;
|
speed = modes[12].Speed;
|
||||||
colorLoop = 0;
|
colorLoop = 0;
|
||||||
}
|
}
|
||||||
fillNoiseLED();
|
fillNoiseLED();
|
||||||
@@ -116,8 +116,8 @@ void oceanNoise()
|
|||||||
{
|
{
|
||||||
loadingFlag = false;
|
loadingFlag = false;
|
||||||
currentPalette = OceanColors_p;
|
currentPalette = OceanColors_p;
|
||||||
scale = modes[13].scale;
|
scale = modes[13].Scale;
|
||||||
speed = modes[13].speed;
|
speed = modes[13].Speed;
|
||||||
colorLoop = 0;
|
colorLoop = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,8 +130,8 @@ void plasmaNoise()
|
|||||||
{
|
{
|
||||||
loadingFlag = false;
|
loadingFlag = false;
|
||||||
currentPalette = PartyColors_p;
|
currentPalette = PartyColors_p;
|
||||||
scale = modes[8].scale;
|
scale = modes[8].Scale;
|
||||||
speed = modes[8].speed;
|
speed = modes[8].Speed;
|
||||||
colorLoop = 1;
|
colorLoop = 1;
|
||||||
}
|
}
|
||||||
fillNoiseLED();
|
fillNoiseLED();
|
||||||
@@ -143,8 +143,8 @@ void cloudNoise()
|
|||||||
{
|
{
|
||||||
loadingFlag = false;
|
loadingFlag = false;
|
||||||
currentPalette = CloudColors_p;
|
currentPalette = CloudColors_p;
|
||||||
scale = modes[6].scale;
|
scale = modes[6].Scale;
|
||||||
speed = modes[6].speed;
|
speed = modes[6].Speed;
|
||||||
colorLoop = 0;
|
colorLoop = 0;
|
||||||
}
|
}
|
||||||
fillNoiseLED();
|
fillNoiseLED();
|
||||||
@@ -156,8 +156,8 @@ void lavaNoise()
|
|||||||
{
|
{
|
||||||
loadingFlag = false;
|
loadingFlag = false;
|
||||||
currentPalette = LavaColors_p;
|
currentPalette = LavaColors_p;
|
||||||
scale = modes[7].scale;
|
scale = modes[7].Scale;
|
||||||
speed = modes[7].speed;
|
speed = modes[7].Speed;
|
||||||
colorLoop = 0;
|
colorLoop = 0;
|
||||||
}
|
}
|
||||||
fillNoiseLED();
|
fillNoiseLED();
|
||||||
|
@@ -30,19 +30,19 @@ void parseUDP()
|
|||||||
|
|
||||||
else if (inputBuffer.startsWith("EFF"))
|
else if (inputBuffer.startsWith("EFF"))
|
||||||
{
|
{
|
||||||
saveEEPROM();
|
EepromManager::SaveModesSettings(¤tMode, modes);
|
||||||
currentMode = (byte)inputBuffer.substring(3).toInt();
|
currentMode = (byte)inputBuffer.substring(3).toInt();
|
||||||
loadingFlag = true;
|
loadingFlag = true;
|
||||||
FastLED.clear();
|
FastLED.clear();
|
||||||
delay(1);
|
delay(1);
|
||||||
sendCurrent();
|
sendCurrent();
|
||||||
FastLED.setBrightness(modes[currentMode].brightness);
|
FastLED.setBrightness(modes[currentMode].Brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (inputBuffer.startsWith("BRI"))
|
else if (inputBuffer.startsWith("BRI"))
|
||||||
{
|
{
|
||||||
modes[currentMode].brightness = constrain(inputBuffer.substring(3).toInt(), 1, 255);
|
modes[currentMode].Brightness = constrain(inputBuffer.substring(3).toInt(), 1, 255);
|
||||||
FastLED.setBrightness(modes[currentMode].brightness);
|
FastLED.setBrightness(modes[currentMode].Brightness);
|
||||||
settChanged = true;
|
settChanged = true;
|
||||||
eepromTimer = millis();
|
eepromTimer = millis();
|
||||||
sendCurrent();
|
sendCurrent();
|
||||||
@@ -50,7 +50,7 @@ void parseUDP()
|
|||||||
|
|
||||||
else if (inputBuffer.startsWith("SPD"))
|
else if (inputBuffer.startsWith("SPD"))
|
||||||
{
|
{
|
||||||
modes[currentMode].speed = inputBuffer.substring(3).toInt();
|
modes[currentMode].Speed = inputBuffer.substring(3).toInt();
|
||||||
loadingFlag = true;
|
loadingFlag = true;
|
||||||
settChanged = true;
|
settChanged = true;
|
||||||
eepromTimer = millis();
|
eepromTimer = millis();
|
||||||
@@ -59,7 +59,7 @@ void parseUDP()
|
|||||||
|
|
||||||
else if (inputBuffer.startsWith("SCA"))
|
else if (inputBuffer.startsWith("SCA"))
|
||||||
{
|
{
|
||||||
modes[currentMode].scale = inputBuffer.substring(3).toInt();
|
modes[currentMode].Scale = inputBuffer.substring(3).toInt();
|
||||||
loadingFlag = true;
|
loadingFlag = true;
|
||||||
settChanged = true;
|
settChanged = true;
|
||||||
eepromTimer = millis();
|
eepromTimer = millis();
|
||||||
@@ -82,27 +82,27 @@ void parseUDP()
|
|||||||
|
|
||||||
else if (inputBuffer.startsWith("ALM_SET"))
|
else if (inputBuffer.startsWith("ALM_SET"))
|
||||||
{
|
{
|
||||||
byte alarmNum = (char)inputBuffer[7] - '0';
|
uint8_t alarmNum = (char)inputBuffer[7] - '0';
|
||||||
alarmNum -= 1;
|
alarmNum -= 1;
|
||||||
if (inputBuffer.indexOf("ON") != -1)
|
if (inputBuffer.indexOf("ON") != -1)
|
||||||
{
|
{
|
||||||
alarm[alarmNum].state = true;
|
alarms[alarmNum].State = true;
|
||||||
sendAlarms();
|
sendAlarms();
|
||||||
}
|
}
|
||||||
else if (inputBuffer.indexOf("OFF") != -1)
|
else if (inputBuffer.indexOf("OFF") != -1)
|
||||||
{
|
{
|
||||||
alarm[alarmNum].state = false;
|
alarms[alarmNum].State = false;
|
||||||
sendAlarms();
|
sendAlarms();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int32_t almTime = inputBuffer.substring(8).toInt();
|
int32_t alarmTime = inputBuffer.substring(8).toInt();
|
||||||
alarm[alarmNum].time = almTime;
|
alarms[alarmNum].Time = alarmTime;
|
||||||
byte hour = floor(almTime / 60);
|
uint8_t hour = floor(alarmTime / 60);
|
||||||
byte minute = almTime - hour * 60;
|
uint8_t minute = alarmTime - hour * 60;
|
||||||
sendAlarms();
|
sendAlarms();
|
||||||
}
|
}
|
||||||
saveAlarm(alarmNum);
|
EepromManager::SaveAlarmsSettings(&alarmNum, alarms);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (inputBuffer.startsWith("ALM_GET"))
|
else if (inputBuffer.startsWith("ALM_GET"))
|
||||||
@@ -113,7 +113,7 @@ void parseUDP()
|
|||||||
else if (inputBuffer.startsWith("DAWN"))
|
else if (inputBuffer.startsWith("DAWN"))
|
||||||
{
|
{
|
||||||
dawnMode = inputBuffer.substring(4).toInt() - 1;
|
dawnMode = inputBuffer.substring(4).toInt() - 1;
|
||||||
saveDawnMmode();
|
EepromManager::SaveDawnMode(&dawnMode);
|
||||||
sendAlarms();
|
sendAlarms();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +146,20 @@ void parseUDP()
|
|||||||
sendTimer();
|
sendTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (inputBuffer.startsWith("FAV_GET"))
|
||||||
|
{
|
||||||
|
sendFavorites();
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (inputBuffer.startsWith("FAV_SET"))
|
||||||
|
{
|
||||||
|
FavoritesManager::ConfigureFavorites(inputBuffer.c_str());
|
||||||
|
//FavoritesManager::SetStatus(inputBuffer);
|
||||||
|
sendFavorites();
|
||||||
|
settChanged = true;
|
||||||
|
eepromTimer = millis();
|
||||||
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
inputBuffer = "";
|
inputBuffer = "";
|
||||||
@@ -182,11 +196,11 @@ void sendCurrent()
|
|||||||
inputBuffer += " ";
|
inputBuffer += " ";
|
||||||
inputBuffer += String(currentMode);
|
inputBuffer += String(currentMode);
|
||||||
inputBuffer += " ";
|
inputBuffer += " ";
|
||||||
inputBuffer += String(modes[currentMode].brightness);
|
inputBuffer += String(modes[currentMode].Brightness);
|
||||||
inputBuffer += " ";
|
inputBuffer += " ";
|
||||||
inputBuffer += String(modes[currentMode].speed);
|
inputBuffer += String(modes[currentMode].Speed);
|
||||||
inputBuffer += " ";
|
inputBuffer += " ";
|
||||||
inputBuffer += String(modes[currentMode].scale);
|
inputBuffer += String(modes[currentMode].Scale);
|
||||||
inputBuffer += " ";
|
inputBuffer += " ";
|
||||||
inputBuffer += String(ONflag);
|
inputBuffer += String(ONflag);
|
||||||
inputBuffer += " ";
|
inputBuffer += " ";
|
||||||
@@ -205,21 +219,19 @@ void sendCurrent()
|
|||||||
#else
|
#else
|
||||||
inputBuffer += String(millis());
|
inputBuffer += String(millis());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GENERAL_DEBUG
|
|
||||||
Serial.println(inputBuffer);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendAlarms()
|
void sendAlarms()
|
||||||
{
|
{
|
||||||
inputBuffer = "ALMS ";
|
inputBuffer = "ALMS ";
|
||||||
for (byte i = 0; i < 7; i++) {
|
for (byte i = 0; i < 7; i++)
|
||||||
inputBuffer += String(alarm[i].state);
|
{
|
||||||
|
inputBuffer += String(alarms[i].State);
|
||||||
inputBuffer += " ";
|
inputBuffer += " ";
|
||||||
}
|
}
|
||||||
for (byte i = 0; i < 7; i++) {
|
for (byte i = 0; i < 7; i++)
|
||||||
inputBuffer += String(alarm[i].time);
|
{
|
||||||
|
inputBuffer += String(alarms[i].Time);
|
||||||
inputBuffer += " ";
|
inputBuffer += " ";
|
||||||
}
|
}
|
||||||
inputBuffer += (dawnMode + 1);
|
inputBuffer += (dawnMode + 1);
|
||||||
@@ -235,3 +247,19 @@ void sendTimer()
|
|||||||
inputBuffer += " ";
|
inputBuffer += " ";
|
||||||
inputBuffer += String(TimerManager::TimerRunning ? (uint16_t)floor((TimerManager::TimeToFire - millis()) / 1000) : 0);
|
inputBuffer += String(TimerManager::TimerRunning ? (uint16_t)floor((TimerManager::TimeToFire - millis()) / 1000) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sendFavorites()
|
||||||
|
{
|
||||||
|
inputBuffer = "FAV";
|
||||||
|
inputBuffer += " ";
|
||||||
|
inputBuffer += String((uint8_t)FavoritesManager::FavoritesRunning);
|
||||||
|
inputBuffer += " ";
|
||||||
|
inputBuffer += String((uint16_t)FavoritesManager::Interval);
|
||||||
|
inputBuffer += " ";
|
||||||
|
inputBuffer += String((uint16_t)FavoritesManager::Dispersion);
|
||||||
|
for (uint8_t i = 0; i < MODE_AMOUNT; i++)
|
||||||
|
{
|
||||||
|
inputBuffer += " ";
|
||||||
|
inputBuffer += String((uint8_t)FavoritesManager::FavoriteModes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -52,14 +52,14 @@ void timeTick()
|
|||||||
thisTime = timeClient.getHours() * 60 + timeClient.getMinutes();
|
thisTime = timeClient.getHours() * 60 + timeClient.getMinutes();
|
||||||
|
|
||||||
// проверка рассвета
|
// проверка рассвета
|
||||||
if (alarm[thisDay].state && // день будильника
|
if (alarms[thisDay].State && // день будильника
|
||||||
thisTime >= (alarm[thisDay].time - dawnOffsets[dawnMode]) && // позже начала
|
thisTime >= (alarms[thisDay].Time - dawnOffsets[dawnMode]) && // позже начала
|
||||||
thisTime < (alarm[thisDay].time + DAWN_TIMEOUT)) // раньше конца + минута
|
thisTime < (alarms[thisDay].Time + DAWN_TIMEOUT)) // раньше конца + минута
|
||||||
{
|
{
|
||||||
if (!manualOff) // будильник не был выключен вручную (из приложения или кнопкой)
|
if (!manualOff) // будильник не был выключен вручную (из приложения или кнопкой)
|
||||||
{
|
{
|
||||||
// величина рассвета 0-255
|
// величина рассвета 0-255
|
||||||
int32_t dawnPosition = 255 * ((float)(thisTime - (alarm[thisDay].time - dawnOffsets[dawnMode])) / dawnOffsets[dawnMode]);
|
int32_t dawnPosition = 255 * ((float)(thisTime - (alarms[thisDay].Time - dawnOffsets[dawnMode])) / dawnOffsets[dawnMode]);
|
||||||
dawnPosition = constrain(dawnPosition, 0, 255);
|
dawnPosition = constrain(dawnPosition, 0, 255);
|
||||||
CHSV dawnColor = CHSV(map(dawnPosition, 0, 255, 10, 35),
|
CHSV dawnColor = CHSV(map(dawnPosition, 0, 255, 10, 35),
|
||||||
map(dawnPosition, 0, 255, 255, 170),
|
map(dawnPosition, 0, 255, 255, 170),
|
||||||
@@ -118,4 +118,4 @@ void resolveNtpServerAddress(bool &ntpServerAddressResolved) // ф
|
|||||||
ntpServerAddressResolved = true;
|
ntpServerAddressResolved = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif USE_NTP
|
#endif
|
||||||
|
@@ -5,7 +5,7 @@ class timerMinim
|
|||||||
public:
|
public:
|
||||||
timerMinim(uint32_t interval); // объявление таймера с указанием интервала
|
timerMinim(uint32_t interval); // объявление таймера с указанием интервала
|
||||||
void setInterval(uint32_t interval); // установка интервала работы таймера
|
void setInterval(uint32_t interval); // установка интервала работы таймера
|
||||||
boolean isReady(); // возвращает true, когда пришло время. Сбрасывается в false сам (AUTO) или вручную (MANUAL)
|
bool isReady(); // возвращает true, когда пришло время. Сбрасывается в false сам (AUTO) или вручную (MANUAL)
|
||||||
void reset(); // ручной сброс таймера на установленный интервал
|
void reset(); // ручной сброс таймера на установленный интервал
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -24,7 +24,7 @@ void timerMinim::setInterval(uint32_t interval)
|
|||||||
_interval = interval;
|
_interval = interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean timerMinim::isReady()
|
bool timerMinim::isReady()
|
||||||
{
|
{
|
||||||
if ((long)millis() - _timer >= _interval)
|
if ((long)millis() - _timer >= _interval)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user