mirror of
https://github.com/AlexGyver/GyverLamp2.git
synced 2025-08-07 08:40:35 +03:00
0.11b
This commit is contained in:
Binary file not shown.
@@ -1,20 +1,36 @@
|
|||||||
// 0.10
|
/*
|
||||||
// исправлена обработка ключа
|
Версия 0.11b
|
||||||
// добавлена совместимость с nodemcu
|
Добавлен редактор палитр
|
||||||
// поворот матрицы
|
Исправлены мелкие баги в эффектах
|
||||||
// обновление прошивок для разных схем
|
Переподключение к роутеру после сброса сети
|
||||||
// исправлен цвет огня
|
Настройка ориентации матрицы из приложения
|
||||||
// индикация обновления при запуске
|
Переработан эффект "Частицы"
|
||||||
|
Добавлена скорость огня
|
||||||
|
Переключение на новый/выбранный режим при редактировании
|
||||||
|
Отправка времени из сервиса (для АР)
|
||||||
|
Выключение по таймеру теперь плавное
|
||||||
|
Добавлен рассвет
|
||||||
|
|
||||||
// мигает 8:
|
TODO:
|
||||||
// красным - не смог подключиться к АР
|
плавная смена режимов
|
||||||
// зелёным - смог подключиться к АР
|
Аккуратнее со светомузыкой!
|
||||||
// жёлтым - создал свою АП
|
4 клика вкл выкл смену?
|
||||||
// бирюзовым - успешно обновился на новую версию
|
Mqtt?
|
||||||
// синим - обновился на ту же версию
|
Базовый пак
|
||||||
// розовым - сброс всех настроек (первый запуск)
|
Предложения Серёги крутского
|
||||||
|
Убрать аплод?
|
||||||
|
Огонь 2018/2020?
|
||||||
|
Взять огонь отсюда https://community.alexgyver.ru/threads/wifi-lampa-budilnik-obsuzhdenie-proshivki-ot-gunner47.2418/page-72#post-33652
|
||||||
|
Вернуть искры
|
||||||
|
Эффект погода https://it4it.club/topic/40-esp8266-i-parsing-pogodyi-s-openweathermap/
|
||||||
|
Эффект часы
|
||||||
|
*/
|
||||||
|
|
||||||
// Generic ESP8266, 4MB (FS:2MB OTA)
|
// ВНИМАНИЕ! ВНИМАНИЕ! ВНИМАНИЕ! ВНИМАНИЕ! ВНИМАНИЕ! ВНИМАНИЕ! ВНИМАНИЕ!
|
||||||
|
// ДЛЯ КОМПИЛЯЦИИ ПРОШИВКИ ПОД NODEMCU/WEMOS/ESP01/ESP12 ВЫБИРАТЬ
|
||||||
|
// Инструменты/Плата Generic ESP8266
|
||||||
|
// Инструменты/Flash Size 4MB (FS:2MB OTA)
|
||||||
|
// При прошивке с других прошивок лампы поставить: Инструменты/Erase Flash/All Flash Contents
|
||||||
// ESP core 2.7.4+ http://arduino.esp8266.com/stable/package_esp8266com_index.json
|
// ESP core 2.7.4+ http://arduino.esp8266.com/stable/package_esp8266com_index.json
|
||||||
// FastLED 3.4.0+ https://github.com/FastLED/FastLED/releases
|
// FastLED 3.4.0+ https://github.com/FastLED/FastLED/releases
|
||||||
|
|
||||||
@@ -49,11 +65,12 @@ const char AP_NameChar[] = "GyverLamp2";
|
|||||||
const char WiFiPassword[] = "12345678";
|
const char WiFiPassword[] = "12345678";
|
||||||
|
|
||||||
// ------------ Прочее -------------
|
// ------------ Прочее -------------
|
||||||
#define GL_VERSION 010
|
#define GL_VERSION 011 // код версии прошивки
|
||||||
#define EE_TOUT 30000 // таймаут сохранения епром после изменения, мс
|
#define EE_TOUT 30000 // таймаут сохранения епром после изменения, мс
|
||||||
#define DEBUG_SERIAL // закомментируй чтобы выключить отладку (скорость 115200)
|
//#define DEBUG_SERIAL // закомментируй чтобы выключить отладку (скорость 115200)
|
||||||
#define EE_KEY 44 // ключ сброса WiFi (измени для сброса всех настроек)
|
#define EE_KEY 50 // ключ сброса WiFi (измени для сброса всех настроек)
|
||||||
#define NTP_UPD_PRD 5 // период обновления времени с NTP сервера, минут
|
#define NTP_UPD_PRD 5 // период обновления времени с NTP сервера, минут
|
||||||
|
//#define SKIP_WIFI // пропустить подключение к вафле (для отладки)
|
||||||
|
|
||||||
// ------------ БИЛДЕР -------------
|
// ------------ БИЛДЕР -------------
|
||||||
//#define MAX_LEDS 1200
|
//#define MAX_LEDS 1200
|
||||||
@@ -82,11 +99,13 @@ const char WiFiPassword[] = "12345678";
|
|||||||
#include <WiFiUdp.h> // общение по UDP
|
#include <WiFiUdp.h> // общение по UDP
|
||||||
#include <EEPROM.h> // епром
|
#include <EEPROM.h> // епром
|
||||||
#include "ESP8266httpUpdate.h" // OTA
|
#include "ESP8266httpUpdate.h" // OTA
|
||||||
|
#include "mString.h" // стринг билдер
|
||||||
|
|
||||||
// ------------------- ДАТА --------------------
|
// ------------------- ДАТА --------------------
|
||||||
Config cfg;
|
Config cfg;
|
||||||
Preset preset[MAX_PRESETS];
|
Preset preset[MAX_PRESETS];
|
||||||
Dawn dawn;
|
Dawn dawn;
|
||||||
|
Palette pal;
|
||||||
WiFiServer server(80);
|
WiFiServer server(80);
|
||||||
WiFiUDP Udp;
|
WiFiUDP Udp;
|
||||||
WiFiUDP ntpUDP;
|
WiFiUDP ntpUDP;
|
||||||
@@ -94,43 +113,48 @@ NTPClient ntp(ntpUDP);
|
|||||||
CRGB leds[MAX_LEDS];
|
CRGB leds[MAX_LEDS];
|
||||||
Time now;
|
Time now;
|
||||||
Button btn(BTN_PIN);
|
Button btn(BTN_PIN);
|
||||||
timerMillis EEtmr(EE_TOUT), turnoffTmr;
|
timerMillis EEtmr(EE_TOUT), turnoffTmr, connTmr(120000), dawnTmr;
|
||||||
TimeRandom trnd;
|
TimeRandom trnd;
|
||||||
VolAnalyzer vol(A0), low, high;
|
VolAnalyzer vol(A0), low, high;
|
||||||
FastFilter phot;
|
FastFilter phot;
|
||||||
|
|
||||||
byte btnClicks = 0, brTicks = 0;
|
byte btnClicks = 0, brTicks = 0;
|
||||||
unsigned char matrixValue[11][16];
|
unsigned char matrixValue[11][16];
|
||||||
bool gotNTP = false;
|
bool gotNTP = false, gotTime = false;
|
||||||
void blink8(CRGB color);
|
void blink8(CRGB color);
|
||||||
|
|
||||||
// ------------------- SETUP --------------------
|
// ------------------- SETUP --------------------
|
||||||
void setup() {
|
void setup() {
|
||||||
delay(800);
|
delay(2000); // ждём старта есп
|
||||||
memset(matrixValue, 0, sizeof(matrixValue));
|
memset(matrixValue, 0, sizeof(matrixValue));
|
||||||
#ifdef DEBUG_SERIAL
|
#ifdef DEBUG_SERIAL
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
DEBUGLN();
|
DEBUGLN();
|
||||||
#endif
|
#endif
|
||||||
EEPROM.begin(512); // старт епром
|
EEPROM.begin(512); // старт епром
|
||||||
startStrip(); // старт ленты
|
startStrip(); // старт ленты
|
||||||
btn.setLevel(digitalRead(BTN_PIN)); // смотрим что за кнопка
|
btn.setLevel(digitalRead(BTN_PIN)); // смотрим что за кнопка
|
||||||
EE_startup(); // читаем епром
|
EE_startup(); // читаем епром
|
||||||
|
#ifndef SKIP_WIFI
|
||||||
checkUpdate(); // индикация было ли обновление
|
checkUpdate(); // индикация было ли обновление
|
||||||
showRGB(); // показываем ргб
|
showRGB(); // показываем ргб
|
||||||
checkGroup(); // показываем или меняем адрес
|
checkGroup(); // показываем или меняем адрес
|
||||||
checkButton(); // проверяем кнопку на удержание
|
checkButton(); // проверяем кнопку на удержание
|
||||||
startWiFi(); // старт вайфай
|
startWiFi(); // старт вайфай
|
||||||
setupTime(); // выставляем время
|
setupTime(); // выставляем время
|
||||||
|
#endif
|
||||||
setupADC(); // настраиваем анализ
|
setupADC(); // настраиваем анализ
|
||||||
presetRotation(true); // форсировать смену режима
|
presetRotation(true); // форсировать смену режима
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
timeTicker(); // обновляем время
|
timeTicker(); // обновляем время
|
||||||
|
#ifndef SKIP_WIFI
|
||||||
|
tryReconnect(); // пробуем переподключиться если WiFi упал
|
||||||
yield();
|
yield();
|
||||||
parsing(); // ловим данные
|
parsing(); // ловим данные
|
||||||
yield();
|
yield();
|
||||||
|
#endif
|
||||||
checkEEupdate(); // сохраняем епром
|
checkEEupdate(); // сохраняем епром
|
||||||
presetRotation(0); // смена режимов по расписанию
|
presetRotation(0); // смена режимов по расписанию
|
||||||
effectsRoutine(); // мигаем
|
effectsRoutine(); // мигаем
|
||||||
|
@@ -3,7 +3,7 @@ class Time {
|
|||||||
byte sec = 0;
|
byte sec = 0;
|
||||||
byte min = 0;
|
byte min = 0;
|
||||||
byte hour = 0;
|
byte hour = 0;
|
||||||
byte day = 0; // пн 0, вт 2.. вс 6
|
byte day = 0;
|
||||||
int ms = 0;
|
int ms = 0;
|
||||||
uint32_t weekMs = 0;
|
uint32_t weekMs = 0;
|
||||||
uint32_t weekS = 0;
|
uint32_t weekS = 0;
|
||||||
|
@@ -17,8 +17,7 @@ void button() {
|
|||||||
DEBUGLN(btnClicks);
|
DEBUGLN(btnClicks);
|
||||||
switch (btnClicks) {
|
switch (btnClicks) {
|
||||||
case 1:
|
case 1:
|
||||||
setPower(!cfg.state);
|
controlHandler(!cfg.state);
|
||||||
sendToSlaves(0, cfg.state);
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
changePreset(1);
|
changePreset(1);
|
||||||
|
@@ -48,18 +48,21 @@ const char *OTAfile[] = {
|
|||||||
"module_1200.bin",
|
"module_1200.bin",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *NTPservers[] = {
|
const char NTPserver[] = "pool.ntp.org";
|
||||||
"pool.ntp.org",
|
//"pool.ntp.org"
|
||||||
"europe.pool.ntp.org",
|
//"europe.pool.ntp.org"
|
||||||
"ntp1.stratum2.ru",
|
//"ntp1.stratum2.ru"
|
||||||
"ntp2.stratum2.ru",
|
//"ntp2.stratum2.ru"
|
||||||
"ntp.msk-ix.ru",
|
//"ntp.msk-ix.ru"
|
||||||
|
|
||||||
|
struct Palette {
|
||||||
|
byte size = 1;
|
||||||
|
byte strip[16 * 3];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CFG_SIZE 13
|
#define CFG_SIZE 13
|
||||||
struct Config {
|
struct Config {
|
||||||
byte GMT = 3; // часовой пояс +13
|
byte GMT = 3; // часовой пояс +13
|
||||||
byte NTP = 1; // 1..5 ВЫЧЕСТЬ 1
|
|
||||||
byte bright = 100; // яркость
|
byte bright = 100; // яркость
|
||||||
byte adcMode = 1; // режим ацп (1 выкл, 2 ярк, 3 муз)
|
byte adcMode = 1; // режим ацп (1 выкл, 2 ярк, 3 муз)
|
||||||
byte minBright = 0; // мин яркость
|
byte minBright = 0; // мин яркость
|
||||||
@@ -71,9 +74,11 @@ struct Config {
|
|||||||
byte maxCur = 5; // макс ток (мА/100)
|
byte maxCur = 5; // макс ток (мА/100)
|
||||||
byte workFrom = 0; // часы работы (0,1.. 23)
|
byte workFrom = 0; // часы работы (0,1.. 23)
|
||||||
byte workTo = 0; // часы работы (0,1.. 23)
|
byte workTo = 0; // часы работы (0,1.. 23)
|
||||||
int16_t length = 100; // длина ленты
|
byte matrix = 1; // тип матрицы 1.. 8
|
||||||
int16_t width = 1; // ширина матрицы
|
|
||||||
byte mTurn = 0;
|
int16_t length = 100; // длина ленты
|
||||||
|
int16_t width = 1; // ширина матрицы
|
||||||
|
uint32_t cityID = 1; // city ID
|
||||||
|
|
||||||
byte state = 1; // состояние 0 выкл, 1 вкл
|
byte state = 1; // состояние 0 выкл, 1 вкл
|
||||||
byte group = 1; // группа девайса (1-10)
|
byte group = 1; // группа девайса (1-10)
|
||||||
@@ -82,8 +87,8 @@ struct Config {
|
|||||||
byte presetAmount = 1; // количество режимов
|
byte presetAmount = 1; // количество режимов
|
||||||
byte manualOff = 0; // выключали вручную?
|
byte manualOff = 0; // выключали вручную?
|
||||||
int8_t curPreset = 0; // текущий режим
|
int8_t curPreset = 0; // текущий режим
|
||||||
int16_t minLight = 0; // мин освещённость
|
int16_t minLight = 0; // мин освещённость
|
||||||
int16_t maxLight = 1023; // макс освещённость
|
int16_t maxLight = 1023;// макс освещённость
|
||||||
char ssid[32]; // логин wifi
|
char ssid[32]; // логин wifi
|
||||||
char pass[32]; // пароль wifi
|
char pass[32]; // пароль wifi
|
||||||
byte version = GL_VERSION;
|
byte version = GL_VERSION;
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
bool EEcfgFlag = false;
|
bool EEcfgFlag = false;
|
||||||
bool EEdawnFlag = false;
|
bool EEdawnFlag = false;
|
||||||
bool EEpresetFlag = false;
|
bool EEpresetFlag = false;
|
||||||
|
bool EEpalFlag = false;
|
||||||
|
|
||||||
void EE_startup() {
|
void EE_startup() {
|
||||||
// старт епром
|
// старт епром
|
||||||
@@ -8,18 +9,23 @@ void EE_startup() {
|
|||||||
EEPROM.write(511, EE_KEY);
|
EEPROM.write(511, EE_KEY);
|
||||||
EEPROM.put(0, cfg);
|
EEPROM.put(0, cfg);
|
||||||
EEPROM.put(sizeof(cfg), dawn);
|
EEPROM.put(sizeof(cfg), dawn);
|
||||||
EEPROM.put(sizeof(cfg) + sizeof(dawn), preset);
|
EEPROM.put(sizeof(cfg) + sizeof(dawn), pal);
|
||||||
|
EEPROM.put(sizeof(cfg) + sizeof(dawn) + sizeof(pal), preset);
|
||||||
EEPROM.commit();
|
EEPROM.commit();
|
||||||
blink8(CRGB::Pink);
|
blink8(CRGB::Pink);
|
||||||
DEBUGLN("First start");
|
DEBUGLN("First start");
|
||||||
}
|
}
|
||||||
EEPROM.get(0, cfg);
|
EEPROM.get(0, cfg);
|
||||||
EEPROM.get(sizeof(cfg), dawn);
|
EEPROM.get(sizeof(cfg), dawn);
|
||||||
EEPROM.get(sizeof(cfg) + sizeof(dawn), preset);
|
EEPROM.get(sizeof(cfg) + sizeof(dawn), pal);
|
||||||
|
EEPROM.get(sizeof(cfg) + sizeof(dawn) + sizeof(pal), preset);
|
||||||
|
|
||||||
|
DEBUG("EEPR size: ");
|
||||||
|
DEBUGLN(sizeof(cfg) + sizeof(dawn) + sizeof(pal) + sizeof(preset));
|
||||||
|
|
||||||
// запускаем всё
|
// запускаем всё
|
||||||
//trnd.setChannel(cfg.group);
|
|
||||||
FastLED.setMaxPowerInVoltsAndMilliamps(STRIP_VOLT, cfg.maxCur * 100);
|
FastLED.setMaxPowerInVoltsAndMilliamps(STRIP_VOLT, cfg.maxCur * 100);
|
||||||
|
updPal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EE_updateCfg() {
|
void EE_updateCfg() {
|
||||||
@@ -34,6 +40,10 @@ void EE_updatePreset() {
|
|||||||
EEpresetFlag = true;
|
EEpresetFlag = true;
|
||||||
EEtmr.restart();
|
EEtmr.restart();
|
||||||
}
|
}
|
||||||
|
void EE_updatePal() {
|
||||||
|
EEpalFlag = true;
|
||||||
|
EEtmr.restart();
|
||||||
|
}
|
||||||
void checkEEupdate() {
|
void checkEEupdate() {
|
||||||
if (EEtmr.isReady()) {
|
if (EEtmr.isReady()) {
|
||||||
if (EEcfgFlag || EEdawnFlag || EEpresetFlag) {
|
if (EEcfgFlag || EEdawnFlag || EEpresetFlag) {
|
||||||
@@ -47,11 +57,16 @@ void checkEEupdate() {
|
|||||||
EEPROM.put(sizeof(cfg), dawn);
|
EEPROM.put(sizeof(cfg), dawn);
|
||||||
DEBUGLN("save dawn");
|
DEBUGLN("save dawn");
|
||||||
}
|
}
|
||||||
|
if (EEpalFlag) {
|
||||||
|
EEpalFlag = false;
|
||||||
|
EEPROM.put(sizeof(cfg) + sizeof(dawn), pal);
|
||||||
|
DEBUGLN("save pal");
|
||||||
|
}
|
||||||
if (EEpresetFlag) {
|
if (EEpresetFlag) {
|
||||||
EEpresetFlag = false;
|
EEpresetFlag = false;
|
||||||
EEPROM.put(sizeof(cfg) + sizeof(dawn), preset);
|
EEPROM.put(sizeof(cfg) + sizeof(dawn) + sizeof(pal), preset);
|
||||||
DEBUGLN("save preset");
|
DEBUGLN("save preset");
|
||||||
}
|
}
|
||||||
EEPROM.commit();
|
EEPROM.commit();
|
||||||
}
|
}
|
||||||
EEtmr.stop();
|
EEtmr.stop();
|
||||||
|
@@ -1,12 +1,30 @@
|
|||||||
void effectsRoutine() {
|
void effectsRoutine() {
|
||||||
static timerMillis effTmr(30, true);
|
static timerMillis effTmr(30, true);
|
||||||
static byte prevEff = 255;
|
static byte prevEff = 255;
|
||||||
|
|
||||||
|
if (dawnTmr.running()) {
|
||||||
|
if (effTmr.isReady()) {
|
||||||
|
fill_solid(leds, MAX_LEDS, ColorFromPalette(HeatColors_p, dawnTmr.getLength8(), scaleFF(dawnTmr.getLength8(), dawn.bright), LINEARBLEND));
|
||||||
|
FastLED.show();
|
||||||
|
}
|
||||||
|
if (dawnTmr.isReady()) dawnTmr.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (cfg.state && effTmr.isReady()) {
|
if (cfg.state && effTmr.isReady()) {
|
||||||
int thisLength = getLength();
|
int thisLength = getLength();
|
||||||
byte thisScale = getScale();
|
byte thisScale = getScale();
|
||||||
int thisWidth = (cfg.deviceType > 1) ? cfg.width : 1;
|
int thisWidth = (cfg.deviceType > 1) ? cfg.width : 1;
|
||||||
|
byte thisBright = getBright();
|
||||||
|
|
||||||
|
if (turnoffTmr.running()) thisBright = scaleFF(thisBright, 255 - turnoffTmr.getLength8());
|
||||||
|
if (turnoffTmr.isReady()) {
|
||||||
|
turnoffTmr.stop();
|
||||||
|
setPower(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FastLED.setBrightness(thisBright);
|
||||||
|
|
||||||
FastLED.setBrightness(getBright());
|
|
||||||
if (prevEff != CUR_PRES.effect) {
|
if (prevEff != CUR_PRES.effect) {
|
||||||
FastLED.clear();
|
FastLED.clear();
|
||||||
prevEff = CUR_PRES.effect;
|
prevEff = CUR_PRES.effect;
|
||||||
@@ -18,10 +36,10 @@ void effectsRoutine() {
|
|||||||
FOR_j(0, cfg.length) {
|
FOR_j(0, cfg.length) {
|
||||||
FOR_i(0, cfg.width) {
|
FOR_i(0, cfg.width) {
|
||||||
leds[getPix(i, j)] = ColorFromPalette(paletteArr[CUR_PRES.palette - 1],
|
leds[getPix(i, j)] = ColorFromPalette(paletteArr[CUR_PRES.palette - 1],
|
||||||
inoise8(
|
scalePal(inoise8(
|
||||||
i * (thisScale / 5) - cfg.width * (thisScale / 5) / 2,
|
i * (thisScale / 5) - cfg.width * (thisScale / 5) / 2,
|
||||||
j * (thisScale / 5) - cfg.length * (thisScale / 5) / 2,
|
j * (thisScale / 5) - cfg.length * (thisScale / 5) / 2,
|
||||||
(now.weekMs >> 1) * CUR_PRES.speed / 255),
|
(now.weekMs >> 1) * CUR_PRES.speed / 255)),
|
||||||
255, LINEARBLEND);
|
255, LINEARBLEND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,12 +47,13 @@ void effectsRoutine() {
|
|||||||
} else {
|
} else {
|
||||||
FOR_i(0, cfg.length) {
|
FOR_i(0, cfg.length) {
|
||||||
leds[i] = ColorFromPalette(paletteArr[CUR_PRES.palette - 1],
|
leds[i] = ColorFromPalette(paletteArr[CUR_PRES.palette - 1],
|
||||||
inoise8(i * (thisScale / 5) - cfg.length * (thisScale / 5) / 2,
|
scalePal(inoise8(i * (thisScale / 5) - cfg.length * (thisScale / 5) / 2,
|
||||||
(now.weekMs >> 1) * CUR_PRES.speed / 255),
|
(now.weekMs >> 1) * CUR_PRES.speed / 255)),
|
||||||
255, LINEARBLEND);
|
255, LINEARBLEND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // ==================================== ЦВЕТ ====================================
|
case 2: // ==================================== ЦВЕТ ====================================
|
||||||
{
|
{
|
||||||
fill_solid(leds, cfg.length * thisWidth, CHSV(CUR_PRES.color, thisScale, CUR_PRES.min));
|
fill_solid(leds, cfg.length * thisWidth, CHSV(CUR_PRES.color, thisScale, CUR_PRES.min));
|
||||||
@@ -47,11 +66,12 @@ void effectsRoutine() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // ================================= СМЕНА ЦВЕТА =================================
|
case 3: // ================================= СМЕНА ЦВЕТА =================================
|
||||||
{
|
{
|
||||||
CRGB thisColor = ColorFromPalette(paletteArr[CUR_PRES.palette - 1], (now.weekMs >> 5) * CUR_PRES.speed / 255, CUR_PRES.min, LINEARBLEND);
|
CRGB thisColor = ColorFromPalette(paletteArr[CUR_PRES.palette - 1], scalePal((now.weekMs >> 5) * CUR_PRES.speed / 255), CUR_PRES.min, LINEARBLEND);
|
||||||
fill_solid(leds, cfg.length * thisWidth, thisColor);
|
fill_solid(leds, cfg.length * thisWidth, thisColor);
|
||||||
thisColor = ColorFromPalette(paletteArr[CUR_PRES.palette - 1], (now.weekMs >> 5) * CUR_PRES.speed / 255, CUR_PRES.max, LINEARBLEND);
|
thisColor = ColorFromPalette(paletteArr[CUR_PRES.palette - 1], scalePal((now.weekMs >> 5) * CUR_PRES.speed / 255), CUR_PRES.max, LINEARBLEND);
|
||||||
if (CUR_PRES.fromCenter) {
|
if (CUR_PRES.fromCenter) {
|
||||||
fillStrip(cfg.length / 2, cfg.length / 2 + thisLength / 2, thisColor);
|
fillStrip(cfg.length / 2, cfg.length / 2 + thisLength / 2, thisColor);
|
||||||
fillStrip(cfg.length / 2 - thisLength / 2, cfg.length / 2, thisColor);
|
fillStrip(cfg.length / 2 - thisLength / 2, cfg.length / 2, thisColor);
|
||||||
@@ -60,6 +80,7 @@ void effectsRoutine() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: // ================================== ГРАДИЕНТ ==================================
|
case 4: // ================================== ГРАДИЕНТ ==================================
|
||||||
if (CUR_PRES.fromCenter) {
|
if (CUR_PRES.fromCenter) {
|
||||||
FOR_i(cfg.length / 2, cfg.length) {
|
FOR_i(cfg.length / 2, cfg.length) {
|
||||||
@@ -67,7 +88,7 @@ void effectsRoutine() {
|
|||||||
if (CUR_PRES.soundReact == GL_REACT_LEN) bright = (i < cfg.length / 2 + thisLength / 2) ? (CUR_PRES.max) : (CUR_PRES.min);
|
if (CUR_PRES.soundReact == GL_REACT_LEN) bright = (i < cfg.length / 2 + thisLength / 2) ? (CUR_PRES.max) : (CUR_PRES.min);
|
||||||
CRGB thisColor = ColorFromPalette(
|
CRGB thisColor = ColorFromPalette(
|
||||||
paletteArr[CUR_PRES.palette - 1], // (x*1.9 + 25) / 255 - быстрый мап 0..255 в 0.1..2
|
paletteArr[CUR_PRES.palette - 1], // (x*1.9 + 25) / 255 - быстрый мап 0..255 в 0.1..2
|
||||||
(i * (thisScale * 1.9 + 25) / cfg.length) + ((now.weekMs >> 3) * (CUR_PRES.speed - 128) / 128),
|
scalePal((i * (thisScale * 1.9 + 25) / cfg.length) + ((now.weekMs >> 3) * (CUR_PRES.speed - 128) / 128)),
|
||||||
bright, LINEARBLEND);
|
bright, LINEARBLEND);
|
||||||
if (cfg.deviceType > 1) fillRow(i, thisColor);
|
if (cfg.deviceType > 1) fillRow(i, thisColor);
|
||||||
else leds[i] = thisColor;
|
else leds[i] = thisColor;
|
||||||
@@ -81,16 +102,41 @@ void effectsRoutine() {
|
|||||||
if (CUR_PRES.soundReact == GL_REACT_LEN) bright = (i < thisLength) ? (CUR_PRES.max) : (CUR_PRES.min);
|
if (CUR_PRES.soundReact == GL_REACT_LEN) bright = (i < thisLength) ? (CUR_PRES.max) : (CUR_PRES.min);
|
||||||
CRGB thisColor = ColorFromPalette(
|
CRGB thisColor = ColorFromPalette(
|
||||||
paletteArr[CUR_PRES.palette - 1], // (x*1.9 + 25) / 255 - быстрый мап 0..255 в 0.1..2
|
paletteArr[CUR_PRES.palette - 1], // (x*1.9 + 25) / 255 - быстрый мап 0..255 в 0.1..2
|
||||||
(i * (thisScale * 1.9 + 25) / cfg.length) + ((now.weekMs >> 3) * (CUR_PRES.speed - 128) / 128),
|
scalePal((i * (thisScale * 1.9 + 25) / cfg.length) + ((now.weekMs >> 3) * (CUR_PRES.speed - 128) / 128)),
|
||||||
bright, LINEARBLEND);
|
bright, LINEARBLEND);
|
||||||
if (cfg.deviceType > 1) fillRow(i, thisColor);
|
if (cfg.deviceType > 1) fillRow(i, thisColor);
|
||||||
else leds[i] = thisColor;
|
else leds[i] = thisColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5: // =================================== ЧАСТИЦЫ ===================================
|
case 5: // =================================== ЧАСТИЦЫ ===================================
|
||||||
FOR_i(0, cfg.length * cfg.width) leds[i].fadeToBlackBy(70);
|
FOR_i(0, cfg.length * cfg.width) leds[i].fadeToBlackBy(70);
|
||||||
if (cfg.deviceType > 1) {
|
{
|
||||||
|
uint16_t rndVal = 0;
|
||||||
|
FOR_i(0, thisScale / 8 + 1) {
|
||||||
|
rndVal = rndVal * 2053 + 13849; // random2053 алгоритм
|
||||||
|
int homeX = inoise16(i * 100000000ul + (now.weekMs << 3) * CUR_PRES.speed / 255);
|
||||||
|
homeX = map(homeX, 10000, 55000, 0, cfg.length);
|
||||||
|
int offsX = inoise8(i * 2500 + (now.weekMs >> 1) * CUR_PRES.speed / 255) - 128;
|
||||||
|
offsX = cfg.length / 2 * offsX / 128;
|
||||||
|
int thisX = homeX + offsX;
|
||||||
|
|
||||||
|
if (cfg.deviceType > 1) {
|
||||||
|
int homeY = inoise16(i * 100000000ul + 2000000000ul + (now.weekMs << 3) * CUR_PRES.speed / 255);
|
||||||
|
homeY = map(homeY, 10000, 55000, 0, cfg.width);
|
||||||
|
int offsY = inoise8(i * 2500 + 30000 + (now.weekMs >> 1) * CUR_PRES.speed / 255) - 128;
|
||||||
|
offsY = cfg.length / 2 * offsY / 128;
|
||||||
|
int thisY = homeY + offsY;
|
||||||
|
setPix(thisX, thisY, CHSV(CUR_PRES.rnd ? rndVal : CUR_PRES.color, 255, 255));
|
||||||
|
} else {
|
||||||
|
setLED(thisX, CHSV(CUR_PRES.rnd ? rndVal : CUR_PRES.color, 255, 255));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
FOR_i(0, cfg.length * cfg.width) leds[i].fadeToBlackBy(70);
|
||||||
|
if (cfg.deviceType > 1) {
|
||||||
uint16_t rndVal = 0;
|
uint16_t rndVal = 0;
|
||||||
FOR_i(0, thisScale / 8) {
|
FOR_i(0, thisScale / 8) {
|
||||||
int thisY = inoise16(i * 100000000ul + (now.weekMs << 6) * CUR_PRES.speed / 255);
|
int thisY = inoise16(i * 100000000ul + (now.weekMs << 6) * CUR_PRES.speed / 255);
|
||||||
@@ -102,7 +148,7 @@ void effectsRoutine() {
|
|||||||
if (thisY >= 0 && thisY < cfg.length && thisX >= 0 && thisX < cfg.width)
|
if (thisY >= 0 && thisY < cfg.length && thisX >= 0 && thisX < cfg.width)
|
||||||
leds[getPix(thisX, thisY)] = CHSV(CUR_PRES.rnd ? rndVal : CUR_PRES.color, 255, 255);
|
leds[getPix(thisX, thisY)] = CHSV(CUR_PRES.rnd ? rndVal : CUR_PRES.color, 255, 255);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint16_t rndVal = 0;
|
uint16_t rndVal = 0;
|
||||||
FOR_i(0, thisScale / 8) {
|
FOR_i(0, thisScale / 8) {
|
||||||
int thisPos = inoise16(i * 100000000ul + (now.weekMs << 6) * CUR_PRES.speed / 255);
|
int thisPos = inoise16(i * 100000000ul + (now.weekMs << 6) * CUR_PRES.speed / 255);
|
||||||
@@ -110,12 +156,13 @@ void effectsRoutine() {
|
|||||||
rndVal = rndVal * 2053 + 13849; // random2053 алгоритм
|
rndVal = rndVal * 2053 + 13849; // random2053 алгоритм
|
||||||
if (thisPos >= 0 && thisPos < cfg.length) leds[thisPos] = CHSV(CUR_PRES.rnd ? rndVal : CUR_PRES.color, 255, 255);
|
if (thisPos >= 0 && thisPos < cfg.length) leds[thisPos] = CHSV(CUR_PRES.rnd ? rndVal : CUR_PRES.color, 255, 255);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6: // ==================================== ОГОНЬ ====================================
|
case 6: // ==================================== ОГОНЬ ====================================
|
||||||
{
|
{
|
||||||
if (cfg.deviceType > 1) { // 2D огонь
|
if (cfg.deviceType > 1) { // 2D огонь
|
||||||
fireRoutine();
|
fireRoutine(CUR_PRES.speed / 2);
|
||||||
} else { // 1D огонь
|
} else { // 1D огонь
|
||||||
static byte heat[MAX_LEDS];
|
static byte heat[MAX_LEDS];
|
||||||
CRGBPalette16 gPal;
|
CRGBPalette16 gPal;
|
||||||
@@ -138,16 +185,21 @@ void effectsRoutine() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7: // ================================== КОНФЕТТИ ==================================
|
case 7: // ================================== КОНФЕТТИ ==================================
|
||||||
FOR_i(0, (thisScale >> 3) + 1) {
|
FOR_i(0, (thisScale >> 3) + 1) {
|
||||||
byte x = random(0, cfg.length * cfg.width);
|
int x = random(0, cfg.length * cfg.width);
|
||||||
if (leds[x] == CRGB(0, 0, 0)) leds[x] = CHSV(CUR_PRES.rnd ? random(0, 255) : CUR_PRES.color, 255, 255);
|
if (leds[x] == CRGB(0, 0, 0)) leds[x] = CHSV(CUR_PRES.rnd ? random(0, 255) : CUR_PRES.color, 255, 255);
|
||||||
}
|
}
|
||||||
FOR_i(0, cfg.length * cfg.width) {
|
FOR_i(0, cfg.length * cfg.width) {
|
||||||
if (leds[i].r >= 10 || leds[i].g >= 10 || leds[i].b >= 10) leds[i].fadeToBlackBy(CUR_PRES.speed / 2);
|
if (leds[i].r >= 10 || leds[i].g >= 10 || leds[i].b >= 10) leds[i].fadeToBlackBy(CUR_PRES.speed / 2 + 1);
|
||||||
else leds[i] = 0;
|
else leds[i] = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 8: // ================================== ПОГОДА ==================================
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// выводим нажатия кнопки
|
// выводим нажатия кнопки
|
||||||
@@ -203,6 +255,13 @@ void fillRow(int row, CRGB color) {
|
|||||||
FOR_i(cfg.width * row, cfg.width * (row + 1)) leds[i] = color;
|
FOR_i(cfg.width * row, cfg.width * (row + 1)) leds[i] = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updPal() {
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
paletteArr[0][i] = CRGB(pal.strip[i * 3], pal.strip[i * 3 + 1], pal.strip[i * 3 + 2]);
|
||||||
|
}
|
||||||
|
if (pal.size < 16) paletteArr[0][pal.size] = paletteArr[0][0];
|
||||||
|
}
|
||||||
|
|
||||||
void blink8(CRGB color) {
|
void blink8(CRGB color) {
|
||||||
FOR_i(0, 3) {
|
FOR_i(0, 3) {
|
||||||
fill_solid(leds, 8, color);
|
fill_solid(leds, 8, color);
|
||||||
@@ -214,15 +273,37 @@ void blink8(CRGB color) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte scalePal(byte val) {
|
||||||
|
if (CUR_PRES.palette == 1) val = val * pal.size / 16;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPix(int x, int y, CRGB color) {
|
||||||
|
if (y >= 0 && y < cfg.length && x >= 0 && x < cfg.width) leds[getPix(x, y)] = color;
|
||||||
|
}
|
||||||
|
void setLED(int x, CRGB color) {
|
||||||
|
if (x >= 0 && x < cfg.length) leds[x] = color;
|
||||||
|
}
|
||||||
|
|
||||||
// получить номер пикселя в ленте по координатам
|
// получить номер пикселя в ленте по координатам
|
||||||
uint16_t getPix(int x, int y) {
|
uint16_t getPix(int x, int y) {
|
||||||
if (cfg.mTurn) {
|
int matrixW;
|
||||||
byte b = x;
|
if (cfg.matrix == 2 || cfg.matrix == 4 || cfg.matrix == 6 || cfg.matrix == 8) matrixW = cfg.length;
|
||||||
x = y;
|
else matrixW = cfg.width;
|
||||||
y = b;
|
int thisX, thisY;
|
||||||
|
switch (cfg.matrix) {
|
||||||
|
case 1: thisX = x; thisY = y; break;
|
||||||
|
case 2: thisX = y; thisY = x; break;
|
||||||
|
case 3: thisX = x; thisY = (cfg.length - y - 1); break;
|
||||||
|
case 4: thisX = (cfg.length - y - 1); thisY = x; break;
|
||||||
|
case 5: thisX = (cfg.width - x - 1); thisY = (cfg.length - y - 1); break;
|
||||||
|
case 6: thisX = (cfg.length - y - 1); thisY = (cfg.width - x - 1); break;
|
||||||
|
case 7: thisX = (cfg.width - x - 1); thisY = y; break;
|
||||||
|
case 8: thisX = y; thisY = (cfg.width - x - 1); break;
|
||||||
}
|
}
|
||||||
if ( !(y & 1) || (cfg.deviceType - 2) ) return (y * cfg.width + x); // если чётная строка
|
|
||||||
else return (y * cfg.width + cfg.width - x - 1); // если нечётная строка
|
if ( !(thisY & 1) || (cfg.deviceType - 2) ) return (thisY * matrixW + thisX); // чётная строка
|
||||||
|
else return (thisY * matrixW + matrixW - thisX - 1); // нечётная строка
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
целочисленный мап
|
целочисленный мап
|
||||||
|
@@ -27,10 +27,15 @@ const unsigned char hueMask[11][16] PROGMEM = {
|
|||||||
|
|
||||||
byte fireLine[100];
|
byte fireLine[100];
|
||||||
|
|
||||||
void fireRoutine() {
|
void fireRoutine(byte speed) {
|
||||||
shiftUp();
|
static byte count = 0;
|
||||||
FOR_i(0, cfg.width) fireLine[i] = random(64, 255);
|
if (count >= 100) {
|
||||||
drawFrame(30);
|
shiftUp();
|
||||||
|
FOR_i(0, cfg.width) fireLine[i] = random(64, 255);
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
drawFrame(count);
|
||||||
|
count += speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void shiftUp() {
|
void shiftUp() {
|
||||||
|
315
firmware/GyverLamp2/mString.h
Normal file
315
firmware/GyverLamp2/mString.h
Normal file
@@ -0,0 +1,315 @@
|
|||||||
|
// TODO
|
||||||
|
// защита от переполнения
|
||||||
|
|
||||||
|
char* mUtoa(uint32_t value, char *buffer, bool clear = 1);
|
||||||
|
char* mLtoa(int32_t value, char *buffer, bool clear = 1);
|
||||||
|
char* mFtoa(double value, int8_t decimals, char *buffer);
|
||||||
|
|
||||||
|
char* mUtoa(uint32_t value, char *buffer, bool clear) {
|
||||||
|
buffer += 11;
|
||||||
|
if (clear) *--buffer = 0;
|
||||||
|
do {
|
||||||
|
*--buffer = value % 10 + '0';
|
||||||
|
value /= 10;
|
||||||
|
} while (value != 0);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* mLtoa(int32_t value, char *buffer, bool clear) {
|
||||||
|
bool minus = value < 0;
|
||||||
|
if (minus) value = -value;
|
||||||
|
buffer = mUtoa(value, buffer, clear);
|
||||||
|
if (minus) *--buffer = '-';
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* mFtoa(double value, int8_t decimals, char *buffer) {
|
||||||
|
int32_t mant = (int32_t)value;
|
||||||
|
value -= mant;
|
||||||
|
uint32_t exp = 1;
|
||||||
|
while (decimals--) exp *= 10;
|
||||||
|
exp *= (float)value;
|
||||||
|
/*buffer += 9;
|
||||||
|
buffer = mUtoa(exp, buffer);
|
||||||
|
--buffer = '.';
|
||||||
|
buffer -= 11;
|
||||||
|
buffer = mLtoa(mant, buffer, 0);*/
|
||||||
|
buffer = ltoa(mant, buffer, DEC);
|
||||||
|
byte len = strlen(buffer);
|
||||||
|
*(buffer + len++) = '.';
|
||||||
|
ltoa(exp, buffer + len++, DEC);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
class mString {
|
||||||
|
public:
|
||||||
|
int size = 0;
|
||||||
|
char* buf;
|
||||||
|
// system*this = buf;
|
||||||
|
uint16_t length() {
|
||||||
|
return strlen(buf);
|
||||||
|
}
|
||||||
|
void clear() {
|
||||||
|
buf[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
mString(char* buffer, int newSize) {
|
||||||
|
//*this = buf;
|
||||||
|
buf = buffer;
|
||||||
|
size = newSize;
|
||||||
|
}
|
||||||
|
/*mString (const char c) {
|
||||||
|
init();
|
||||||
|
add(c);
|
||||||
|
}
|
||||||
|
mString (const char* data) {
|
||||||
|
init();
|
||||||
|
add(data);
|
||||||
|
}
|
||||||
|
mString (const __FlashStringHelper *data) {
|
||||||
|
init();
|
||||||
|
add(data);
|
||||||
|
}
|
||||||
|
mString (uint32_t value) {
|
||||||
|
init();
|
||||||
|
add(value);
|
||||||
|
}
|
||||||
|
mString (int32_t value) {
|
||||||
|
init();
|
||||||
|
add(value);
|
||||||
|
}
|
||||||
|
mString (uint16_t value) {
|
||||||
|
init();
|
||||||
|
add(value);
|
||||||
|
}
|
||||||
|
mString (int16_t value) {
|
||||||
|
init();
|
||||||
|
add(value);
|
||||||
|
}
|
||||||
|
mString (uint8_t value) {
|
||||||
|
init();
|
||||||
|
add(value);
|
||||||
|
}
|
||||||
|
mString (int8_t value) {
|
||||||
|
init();
|
||||||
|
add(value);
|
||||||
|
}
|
||||||
|
mString (double value, byte dec = 2) {
|
||||||
|
init();
|
||||||
|
add(value, dec);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// add
|
||||||
|
mString& add(const char c) {
|
||||||
|
byte len = length();
|
||||||
|
buf[len++] = c;
|
||||||
|
buf[len++] = 0;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
mString& add(const char* data) {
|
||||||
|
/*byte len = length();
|
||||||
|
do {
|
||||||
|
buf[len] = *(data++);
|
||||||
|
} while (buf[len++] != 0);*/
|
||||||
|
strcpy(buf + length(), data);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
mString& add(const __FlashStringHelper *data) {
|
||||||
|
PGM_P p = reinterpret_cast<PGM_P>(data);
|
||||||
|
strcpy_P(buf + length(), p);
|
||||||
|
return *this;
|
||||||
|
/*do {
|
||||||
|
buf[len] = (char)pgm_read_byte_near(p++);
|
||||||
|
} while (buf[len++] != 0);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
mString& add(uint32_t value) {
|
||||||
|
//char buf[11];
|
||||||
|
//return add(mUtoa(value, buf));
|
||||||
|
utoa(value, buf + length(), DEC);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
mString& add(uint16_t value) {
|
||||||
|
return add((uint32_t)value);
|
||||||
|
}
|
||||||
|
mString& add(uint8_t value) {
|
||||||
|
return add((uint32_t)value);
|
||||||
|
}
|
||||||
|
mString& add(int32_t value) {
|
||||||
|
//char buf[11];
|
||||||
|
//return add(mLtoa(value, buf));
|
||||||
|
ltoa(value, buf + length(), DEC);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
mString& add(int16_t value) {
|
||||||
|
return add((int32_t)value);
|
||||||
|
}
|
||||||
|
mString& add(int8_t value) {
|
||||||
|
return add((int32_t)value);
|
||||||
|
}
|
||||||
|
mString& add(double value, int8_t dec = 2) {
|
||||||
|
char buf[20];
|
||||||
|
return add(mFtoa(value, dec, buf));
|
||||||
|
//dtostrf(value, dec, DEC, buf+length());
|
||||||
|
//return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add +=
|
||||||
|
mString& operator += (const char c) {
|
||||||
|
return add(c);
|
||||||
|
}
|
||||||
|
mString& operator += (const char* data) {
|
||||||
|
return add(data);
|
||||||
|
}
|
||||||
|
mString& operator += (const __FlashStringHelper *data) {
|
||||||
|
return add(data);
|
||||||
|
}
|
||||||
|
mString& operator += (uint32_t value) {
|
||||||
|
return add(value);
|
||||||
|
}
|
||||||
|
mString& operator += (int32_t value) {
|
||||||
|
return add(value);
|
||||||
|
}
|
||||||
|
mString& operator += (uint16_t value) {
|
||||||
|
return add(value);
|
||||||
|
}
|
||||||
|
mString& operator += (int16_t value) {
|
||||||
|
return add(value);
|
||||||
|
}
|
||||||
|
mString& operator += (uint8_t value) {
|
||||||
|
return add(value);
|
||||||
|
}
|
||||||
|
mString& operator += (int8_t value) {
|
||||||
|
return add(value);
|
||||||
|
}
|
||||||
|
mString& operator += (double value) {
|
||||||
|
return add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// assign
|
||||||
|
mString& operator = (const char c) {
|
||||||
|
clear();
|
||||||
|
return add(c);
|
||||||
|
}
|
||||||
|
mString& operator = (const char* data) {
|
||||||
|
clear();
|
||||||
|
return add(data);
|
||||||
|
}
|
||||||
|
mString& operator = (const __FlashStringHelper *data) {
|
||||||
|
clear();
|
||||||
|
return add(data);
|
||||||
|
}
|
||||||
|
mString& operator = (uint32_t value) {
|
||||||
|
clear();
|
||||||
|
return add(value);
|
||||||
|
}
|
||||||
|
mString& operator = (int32_t value) {
|
||||||
|
clear();
|
||||||
|
return add(value);
|
||||||
|
}
|
||||||
|
mString& operator = (uint16_t value) {
|
||||||
|
clear();
|
||||||
|
return add(value);
|
||||||
|
}
|
||||||
|
mString& operator = (int16_t value) {
|
||||||
|
clear();
|
||||||
|
return add(value);
|
||||||
|
}
|
||||||
|
mString& operator = (uint8_t value) {
|
||||||
|
clear();
|
||||||
|
return add(value);
|
||||||
|
}
|
||||||
|
mString& operator = (int8_t value) {
|
||||||
|
clear();
|
||||||
|
return add(value);
|
||||||
|
}
|
||||||
|
mString& operator = (double value) {
|
||||||
|
clear();
|
||||||
|
return add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// compare
|
||||||
|
bool operator == (const char c) {
|
||||||
|
return (buf[0] == c && buf[1] == 0);
|
||||||
|
}
|
||||||
|
bool operator == (const char* data) {
|
||||||
|
return !strcmp(buf, data);
|
||||||
|
}
|
||||||
|
bool operator == (uint32_t value) {
|
||||||
|
char valBuf[11];
|
||||||
|
return !strcmp(buf, utoa(value, valBuf, DEC));
|
||||||
|
}
|
||||||
|
bool operator == (int32_t value) {
|
||||||
|
char valBuf[11];
|
||||||
|
return !strcmp(buf, ltoa(value, valBuf, DEC));
|
||||||
|
}
|
||||||
|
bool operator == (float value) {
|
||||||
|
char valBuf[20];
|
||||||
|
return !strcmp(buf, mFtoa(value, 2, valBuf));
|
||||||
|
}
|
||||||
|
char operator [] (uint16_t index) const {
|
||||||
|
return (index < size ? buf[index] : 0);
|
||||||
|
}
|
||||||
|
char& operator [] (uint16_t index) {
|
||||||
|
return buf[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// convert & parse
|
||||||
|
uint32_t toInt() {
|
||||||
|
return atoi(buf);
|
||||||
|
}
|
||||||
|
float toFloat() {
|
||||||
|
return atof(buf);
|
||||||
|
}
|
||||||
|
const char* c_str() {
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
bool startsWith(const char *data) {
|
||||||
|
return strlen(data) == strspn(buf, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int indexOf(char ch, uint16_t fromIndex = 0) {
|
||||||
|
if (fromIndex >= length()) return -1;
|
||||||
|
const char* temp = strchr(buf + fromIndex, ch);
|
||||||
|
if (temp == NULL) return -1;
|
||||||
|
return temp - buf;
|
||||||
|
}
|
||||||
|
int parseBytes(byte* data, int len, char div = ',', char ter = NULL) {
|
||||||
|
int b = 0, c = 0;
|
||||||
|
data[b] = 0;
|
||||||
|
while (true) {
|
||||||
|
if (buf[c] == div) {
|
||||||
|
b++;
|
||||||
|
c++;
|
||||||
|
if (b == len) return b;
|
||||||
|
data[b] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (buf[c] == ter || b == len) return b + 1;
|
||||||
|
data[b] *= 10;
|
||||||
|
data[b] += buf[c] - '0';
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int parseInts(int* data, int len, char div = ',', char ter = NULL) {
|
||||||
|
int b = 0, c = 0;
|
||||||
|
data[b] = 0;
|
||||||
|
while (true) {
|
||||||
|
if (buf[c] == div) {
|
||||||
|
b++;
|
||||||
|
c++;
|
||||||
|
if (b == len) return b;
|
||||||
|
data[b] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (buf[c] == ter || b == len) return b + 1;
|
||||||
|
data[b] *= 10;
|
||||||
|
data[b] += buf[c] - '0';
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
@@ -1,6 +1,8 @@
|
|||||||
#include <FastLED.h> // лента
|
#include <FastLED.h> // лента
|
||||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/
|
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/
|
||||||
|
|
||||||
|
CRGBPalette16 customPal;
|
||||||
|
|
||||||
DEFINE_GRADIENT_PALETTE( Fire_gp ) {
|
DEFINE_GRADIENT_PALETTE( Fire_gp ) {
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
128, 255, 0, 0,
|
128, 255, 0, 0,
|
||||||
@@ -221,6 +223,7 @@ DEFINE_GRADIENT_PALETTE ( aurora_gp ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
CRGBPalette16 paletteArr[] = {
|
CRGBPalette16 paletteArr[] = {
|
||||||
|
customPal,
|
||||||
HeatColors_p,
|
HeatColors_p,
|
||||||
Fire_gp,
|
Fire_gp,
|
||||||
LavaColors_p,
|
LavaColors_p,
|
||||||
|
@@ -9,35 +9,47 @@ void parsing() {
|
|||||||
|
|
||||||
buf[n] = NULL;
|
buf[n] = NULL;
|
||||||
DEBUGLN(buf); // пакет вида <ключ>,<канал>,<тип>,<дата1>,<дата2>...
|
DEBUGLN(buf); // пакет вида <ключ>,<канал>,<тип>,<дата1>,<дата2>...
|
||||||
|
mString pars(buf, sizeof(buf));
|
||||||
|
if (!pars.startsWith(GL_KEY)) return; // не наш ключ
|
||||||
|
byte keyLen = strlen(GL_KEY);
|
||||||
|
|
||||||
byte keyLen = strchr(buf, ',') - buf; // indexof
|
byte data[MAX_PRESETS * PRES_SIZE + 5];
|
||||||
if (strncmp(buf, GL_KEY, keyLen)) return; // не наш ключ
|
|
||||||
|
|
||||||
byte data[MAX_PRESETS * PRES_SIZE + keyLen];
|
|
||||||
memset(data, 0, MAX_PRESETS * PRES_SIZE + keyLen);
|
memset(data, 0, MAX_PRESETS * PRES_SIZE + keyLen);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
char *str, *p = buf + keyLen; // сдвиг до даты
|
char *str, *p = buf + keyLen; // сдвиг до даты
|
||||||
char *ssid, *pass;
|
char *ssid, *pass;
|
||||||
|
uint32_t city = 0;
|
||||||
|
uint16_t stripL, stripW;
|
||||||
while ((str = strtok_r(p, ",", &p)) != NULL) {
|
while ((str = strtok_r(p, ",", &p)) != NULL) {
|
||||||
data[count++] = atoi(str);
|
uint32_t thisInt = atoi(str);
|
||||||
if (count == 4) ssid = str;
|
data[count++] = (byte)thisInt;
|
||||||
if (count == 5) pass = str;
|
if (data[1] == 0) {
|
||||||
|
if (count == 4) ssid = str;
|
||||||
|
if (count == 5) pass = str;
|
||||||
|
}
|
||||||
|
if (data[1] == 1) {
|
||||||
|
if (count == 16) stripL = thisInt;
|
||||||
|
if (count == 17) stripW = thisInt;
|
||||||
|
if (count == 18) city = thisInt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// широковещательный запрос времени для local устройств в сети AP лампы
|
// широковещательный запрос времени для local устройств в сети AP лампы
|
||||||
if (data[0] == 0 && cfg.WiFimode && !gotNTP) {
|
if (data[0] == 0 && cfg.WiFimode && !gotNTP) {
|
||||||
now.hour = data[1];
|
now.day = data[1];
|
||||||
now.min = data[2];
|
now.hour = data[2];
|
||||||
|
now.min = data[3];
|
||||||
|
now.sec = data[4];
|
||||||
now.setMs(0);
|
now.setMs(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[0] != cfg.group) return; // не наш адрес, выходим
|
if (data[0] != cfg.group) return; // не наш адрес, выходим
|
||||||
|
|
||||||
switch (data[1]) { // тип 0 - control, 1 - config, 2 - effects, 3 - dawn
|
switch (data[1]) { // тип 0 - control, 1 - config, 2 - effects, 3 - dawn, 4 - from master, 5 - palette
|
||||||
case 0: DEBUGLN("Control");
|
case 0: DEBUGLN("Control");
|
||||||
switch (data[2]) {
|
switch (data[2]) {
|
||||||
case 0: setPower(0); break; // выкл
|
case 0: controlHandler(0); break; // выкл
|
||||||
case 1: setPower(1); break; // вкл
|
case 1: controlHandler(1); break; // вкл
|
||||||
case 2: cfg.minLight = phot.getRaw(); break; // мин яркость
|
case 2: cfg.minLight = phot.getRaw(); break; // мин яркость
|
||||||
case 3: cfg.maxLight = phot.getRaw(); break; // макс яркость
|
case 3: cfg.maxLight = phot.getRaw(); break; // макс яркость
|
||||||
case 4: changePreset(-1); break; // пред пресет
|
case 4: changePreset(-1); break; // пред пресет
|
||||||
@@ -54,12 +66,16 @@ void parsing() {
|
|||||||
case 12: if (gotNTP) { // OTA обновление, если есть интернет
|
case 12: if (gotNTP) { // OTA обновление, если есть интернет
|
||||||
cfg.update = 1;
|
cfg.update = 1;
|
||||||
EE_updCfg();
|
EE_updCfg();
|
||||||
delay(100);
|
|
||||||
FastLED.clear();
|
FastLED.clear();
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
char OTA[60];
|
char OTA[60];
|
||||||
strcpy(OTA, OTAhost);
|
mString ota(OTA, 60);
|
||||||
strcpy(OTA + strlen(OTAhost), OTAfile[data[3]]);
|
ota.clear();
|
||||||
|
ota += OTAhost;
|
||||||
|
ota += OTAfile[data[3]];
|
||||||
|
DEBUG("Update to ");
|
||||||
|
DEBUGLN(OTA);
|
||||||
|
delay(100);
|
||||||
ESPhttpUpdate.update(OTA);
|
ESPhttpUpdate.update(OTA);
|
||||||
} break;
|
} break;
|
||||||
case 13: // выключить через
|
case 13: // выключить через
|
||||||
@@ -77,15 +93,14 @@ void parsing() {
|
|||||||
FOR_i(0, CFG_SIZE) {
|
FOR_i(0, CFG_SIZE) {
|
||||||
*((byte*)&cfg + i) = data[i + 2]; // загоняем в структуру
|
*((byte*)&cfg + i) = data[i + 2]; // загоняем в структуру
|
||||||
}
|
}
|
||||||
cfg.mTurn = data[21];
|
cfg.length = stripL;
|
||||||
cfg.length = data[17] | (data[16] << 8); // склеиваем
|
cfg.width = stripW;
|
||||||
cfg.width = data[20] | (data[19] << 8); // склеиваем
|
cfg.cityID = city;
|
||||||
|
|
||||||
if (cfg.length > MAX_LEDS) cfg.length = MAX_LEDS;
|
if (cfg.length > MAX_LEDS) cfg.length = MAX_LEDS;
|
||||||
if (cfg.deviceType == GL_TYPE_STRIP) cfg.width = 1;
|
if (cfg.deviceType == GL_TYPE_STRIP) cfg.width = 1;
|
||||||
if (cfg.length * cfg.width > MAX_LEDS) cfg.width = MAX_LEDS / cfg.length;
|
if (cfg.length * cfg.width > MAX_LEDS) cfg.width = MAX_LEDS / cfg.length;
|
||||||
ntp.setTimeOffset((cfg.GMT - 13) * 3600);
|
ntp.setTimeOffset((cfg.GMT - 13) * 3600);
|
||||||
ntp.setPoolServerName(NTPservers[cfg.NTP - 1]);
|
|
||||||
FastLED.setMaxPowerInVoltsAndMilliamps(STRIP_VOLT, cfg.maxCur * 100);
|
FastLED.setMaxPowerInVoltsAndMilliamps(STRIP_VOLT, cfg.maxCur * 100);
|
||||||
if (cfg.adcMode == GL_ADC_BRI) switchToPhot();
|
if (cfg.adcMode == GL_ADC_BRI) switchToPhot();
|
||||||
else if (cfg.adcMode == GL_ADC_MIC) switchToMic();
|
else if (cfg.adcMode == GL_ADC_MIC) switchToMic();
|
||||||
@@ -100,6 +115,7 @@ void parsing() {
|
|||||||
*((byte*)&preset + j * PRES_SIZE + i) = data[j * PRES_SIZE + i + 3]; // загоняем в структуру
|
*((byte*)&preset + j * PRES_SIZE + i) = data[j * PRES_SIZE + i + 3]; // загоняем в структуру
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!cfg.rotation) setPreset(data[cfg.presetAmount * PRES_SIZE + 3] - 1);
|
||||||
EE_updatePreset();
|
EE_updatePreset();
|
||||||
presetRotation(true); // форсировать смену режима
|
presetRotation(true); // форсировать смену режима
|
||||||
break;
|
break;
|
||||||
@@ -121,9 +137,25 @@ void parsing() {
|
|||||||
EE_updateCfg();
|
EE_updateCfg();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 5: DEBUGLN("Palette");
|
||||||
|
FOR_i(0, 1 + 16 * 3) {
|
||||||
|
*((byte*)&pal + i) = data[i + 2]; // загоняем в структуру
|
||||||
|
}
|
||||||
|
updPal();
|
||||||
|
EE_updatePal();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6: DEBUGLN("Time");
|
||||||
|
if (!cfg.WiFimode) { // если мы AP
|
||||||
|
now.day = data[2];
|
||||||
|
now.hour = data[3];
|
||||||
|
now.min = data[4];
|
||||||
|
}
|
||||||
|
gotTime = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
FastLED.clear(); // на всякий случай
|
FastLED.clear(); // на всякий случай
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,18 +163,19 @@ void sendToSlaves(byte data1, byte data2) {
|
|||||||
if (cfg.role == GL_MASTER) {
|
if (cfg.role == GL_MASTER) {
|
||||||
IPAddress ip = WiFi.localIP();
|
IPAddress ip = WiFi.localIP();
|
||||||
ip[3] = 255;
|
ip[3] = 255;
|
||||||
char reply[20] = GL_KEY;
|
|
||||||
byte keylen = strlen(GL_KEY);
|
|
||||||
reply[keylen++] = ',';
|
|
||||||
reply[keylen++] = cfg.group + '0';
|
|
||||||
reply[keylen++] = ',';
|
|
||||||
reply[keylen++] = '4';
|
|
||||||
reply[keylen++] = ',';
|
|
||||||
reply[keylen++] = data1 + '0';
|
|
||||||
reply[keylen++] = ',';
|
|
||||||
itoa(data2, reply + (keylen++), DEC);
|
|
||||||
|
|
||||||
DEBUG("Sending: ");
|
char reply[20];
|
||||||
|
mString packet(reply, sizeof(reply));
|
||||||
|
packet.clear();
|
||||||
|
packet += GL_KEY;
|
||||||
|
packet += ',';
|
||||||
|
packet += cfg.group;
|
||||||
|
packet += ",4,";
|
||||||
|
packet += data1;
|
||||||
|
packet += ',';
|
||||||
|
packet += data2;
|
||||||
|
|
||||||
|
DEBUG("Sending to Slaves: ");
|
||||||
DEBUGLN(reply);
|
DEBUGLN(reply);
|
||||||
|
|
||||||
FOR_i(0, 3) {
|
FOR_i(0, 3) {
|
||||||
|
@@ -30,14 +30,29 @@ void setPreset(byte pres) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPower(bool state) {
|
void controlHandler(bool state) {
|
||||||
|
if (turnoffTmr.running()) {
|
||||||
|
turnoffTmr.stop();
|
||||||
|
DEBUGLN("stop off timer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (dawnTmr.running()) {
|
||||||
|
dawnTmr.stop();
|
||||||
|
DEBUGLN("stop dawn timer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (state) cfg.manualOff = 0;
|
if (state) cfg.manualOff = 0;
|
||||||
if (cfg.state && !state) cfg.manualOff = 1;
|
if (cfg.state && !state) cfg.manualOff = 1;
|
||||||
|
setPower(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPower(bool state) {
|
||||||
cfg.state = state;
|
cfg.state = state;
|
||||||
if (!state) {
|
if (!state) {
|
||||||
delay(100); // чтобы пролететь мин. частоту обновления
|
delay(100); // чтобы пролететь мин. частоту обновления
|
||||||
FastLED.clear();
|
FastLED.clear();
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
}
|
}
|
||||||
|
sendToSlaves(0, cfg.state);
|
||||||
DEBUGLN(state ? "Power on" : "Power off");
|
DEBUGLN(state ? "Power on" : "Power off");
|
||||||
}
|
}
|
||||||
|
@@ -135,6 +135,7 @@ void setupLocal() {
|
|||||||
delay(50);
|
delay(50);
|
||||||
}
|
}
|
||||||
if (connect) {
|
if (connect) {
|
||||||
|
connTmr.stop();
|
||||||
blink8(CRGB::Green);
|
blink8(CRGB::Green);
|
||||||
server.begin();
|
server.begin();
|
||||||
DEBUG("Connected! Local IP: ");
|
DEBUG("Connected! Local IP: ");
|
||||||
@@ -147,6 +148,7 @@ void setupLocal() {
|
|||||||
failCount++;
|
failCount++;
|
||||||
tmr = millis();
|
tmr = millis();
|
||||||
if (failCount >= 3) {
|
if (failCount >= 3) {
|
||||||
|
connTmr.restart(); // попробуем позже
|
||||||
setupAP();
|
setupAP();
|
||||||
return;
|
return;
|
||||||
/*DEBUGLN("Reboot to AP!");
|
/*DEBUGLN("Reboot to AP!");
|
||||||
@@ -172,5 +174,13 @@ void checkUpdate() {
|
|||||||
DEBUG("Update to current");
|
DEBUG("Update to current");
|
||||||
}
|
}
|
||||||
cfg.update = 0;
|
cfg.update = 0;
|
||||||
|
EE_updCfg();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tryReconnect() {
|
||||||
|
if (connTmr.isReady()) {
|
||||||
|
DEBUGLN("Reconnect");
|
||||||
|
setupLocal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
void setupTime() {
|
void setupTime() {
|
||||||
ntp.setUpdateInterval(NTP_UPD_PRD / 2 * 60000ul); // меньше в два раза, ибо апдейт вручную
|
ntp.setUpdateInterval(NTP_UPD_PRD / 2 * 60000ul); // меньше в два раза, ибо апдейт вручную
|
||||||
ntp.setTimeOffset((cfg.GMT - 13) * 3600);
|
ntp.setTimeOffset((cfg.GMT - 13) * 3600);
|
||||||
ntp.setPoolServerName(NTPservers[cfg.NTP - 1]);
|
ntp.setPoolServerName(NTPserver);
|
||||||
if (cfg.WiFimode) {
|
if (cfg.WiFimode) {
|
||||||
// если подключены - запрашиваем время с сервера
|
// если подключены - запрашиваем время с сервера
|
||||||
ntp.begin();
|
ntp.begin();
|
||||||
@@ -16,8 +16,7 @@ void timeTicker() {
|
|||||||
updateTime(); // обновляем время
|
updateTime(); // обновляем время
|
||||||
sendTimeToSlaves(); // отправляем время слейвам
|
sendTimeToSlaves(); // отправляем время слейвам
|
||||||
trnd.update(now.hour, now.min, now.sec); // обновляем рандомайзер
|
trnd.update(now.hour, now.min, now.sec); // обновляем рандомайзер
|
||||||
if (gotNTP) checkWorkTime(); // проверяем расписание, если подключены к Интернет
|
if (gotNTP || gotTime) checkWorkTime(); // проверяем расписание, если знаем время
|
||||||
checkTurnoff(); // проверяем таймер отключения
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,68 +25,68 @@ void updateTime() {
|
|||||||
now.sec = ntp.getSeconds();
|
now.sec = ntp.getSeconds();
|
||||||
now.min = ntp.getMinutes();
|
now.min = ntp.getMinutes();
|
||||||
now.hour = ntp.getHours();
|
now.hour = ntp.getHours();
|
||||||
now.day = ntp.getDay();
|
now.day = ntp.getDay(); // вс 0, сб 6
|
||||||
now.day = (now.day == 0) ? 6 : (now.day - 1); // перевод из вс0 в пн0
|
|
||||||
now.weekMs = now.getWeekS() * 1000ul + ntp.getMillis();
|
now.weekMs = now.getWeekS() * 1000ul + ntp.getMillis();
|
||||||
now.setMs(ntp.getMillis());
|
now.setMs(ntp.getMillis());
|
||||||
if (now.min % NTP_UPD_PRD == 0 && now.sec == 0) {
|
if (now.min % NTP_UPD_PRD == 0 && now.sec == 0) {
|
||||||
// берём время с интернета каждую NTP_UPD_PRD минуту, ставим флаг что данные с NTP получены, значит мы онлайн
|
// берём время с интернета каждую NTP_UPD_PRD минуту, ставим флаг что данные с NTP получены, значит мы онлайн
|
||||||
if (ntp.update() && !gotNTP) gotNTP = true;
|
if (ntp.update() && !gotNTP) gotNTP = true;
|
||||||
}
|
}
|
||||||
|
checkDawn();
|
||||||
} else { // если нет
|
} else { // если нет
|
||||||
now.tick(); // тикаем своим счётчиком
|
now.tick(); // тикаем своим счётчиком
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendTimeToSlaves() {
|
void sendTimeToSlaves() {
|
||||||
if (!cfg.WiFimode) { // если мы AP
|
if (!cfg.WiFimode) { // если мы AP
|
||||||
static byte prevSec = 0;
|
static byte prevSec = 0;
|
||||||
if (prevSec != now.sec) { // новая секунда
|
if (prevSec != now.sec) { // новая секунда
|
||||||
prevSec = now.sec;
|
prevSec = now.sec;
|
||||||
if (now.min % 1 == 0 && now.sec == 0) sendTime(); // ровно каждые 5 мин отправляем время
|
if (now.min % 5 == 0 && now.sec == 0) sendTime(); // ровно каждые 5 мин отправляем время
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkTurnoff() {
|
void checkDawn() {
|
||||||
if (turnoffTmr.isReady()) {
|
if (now.sec == 0 && dawn.state[now.day] && !dawnTmr.running()) { // рассвет включен но не запущен
|
||||||
turnoffTmr.stop();
|
int dawnMinute = dawn.hour[now.day] * 60 + dawn.minute[now.day] - dawn.time;
|
||||||
setPower(0);
|
if (dawnMinute < 0) dawnMinute += 1440;
|
||||||
|
if (dawnMinute == now.hour * 60 + now.min) {
|
||||||
|
DEBUGLN("dawn start");
|
||||||
|
dawnTmr.setInterval(dawn.time * 60000ul);
|
||||||
|
dawnTmr.restart();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkWorkTime() {
|
void checkWorkTime() {
|
||||||
if (!isWorkTime(now.hour, cfg.workFrom, cfg.workTo)) {
|
static byte prevState = 2; // для первого запуска
|
||||||
if (cfg.state) {
|
byte curState = isWorkTime(now.hour, cfg.workFrom, cfg.workTo);
|
||||||
cfg.state = false;
|
if (prevState != curState) { // переключение расписания
|
||||||
FastLED.clear();
|
prevState = curState;
|
||||||
FastLED.show();
|
if (curState && !cfg.state && !cfg.manualOff) setPower(1); // нужно включить, а лампа выключена и не выключалась вручную
|
||||||
}
|
if (!curState && cfg.state) setPower(0); // нужно выключить, а лампа включена
|
||||||
} else {
|
|
||||||
if (!cfg.state && !cfg.manualOff) {
|
|
||||||
cfg.state = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendTime() {
|
void sendTime() {
|
||||||
IPAddress ip = WiFi.localIP();
|
IPAddress ip = WiFi.localIP();
|
||||||
ip[3] = 255;
|
ip[3] = 255;
|
||||||
char reply[20] = GL_KEY;
|
char reply[25] = GL_KEY;
|
||||||
byte keylen = strlen(GL_KEY);
|
mString packet(reply, sizeof(reply));
|
||||||
reply[keylen++] = ',';
|
packet.clear();
|
||||||
reply[keylen++] = 0 + '0';
|
packet += GL_KEY;
|
||||||
reply[keylen++] = ',';
|
packet += ',';
|
||||||
char hours[4];
|
packet += 0;
|
||||||
itoa(now.hour, hours, DEC);
|
packet += ',';
|
||||||
strncpy(reply + keylen, hours, 3);
|
packet += now.day;
|
||||||
keylen += strlen(hours);
|
packet += ',';
|
||||||
reply[keylen++] = ',';
|
packet += now.hour;
|
||||||
char mins[4];
|
packet += ',';
|
||||||
itoa(now.min, mins, DEC);
|
packet += now.min;
|
||||||
strncpy(reply + keylen, mins, 3);
|
packet += ',';
|
||||||
keylen += strlen(mins);
|
packet += now.sec;
|
||||||
reply[keylen++] = NULL;
|
|
||||||
|
|
||||||
DEBUG("Sending time: ");
|
DEBUG("Sending time: ");
|
||||||
DEBUGLN(reply);
|
DEBUGLN(reply);
|
||||||
|
@@ -12,7 +12,6 @@ class timerMillis {
|
|||||||
}
|
}
|
||||||
boolean isReady() {
|
boolean isReady() {
|
||||||
if (_active && millis() - _tmr >= _interval) {
|
if (_active && millis() - _tmr >= _interval) {
|
||||||
//_tmr += _interval;
|
|
||||||
reset();
|
reset();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -28,6 +27,12 @@ class timerMillis {
|
|||||||
void stop() {
|
void stop() {
|
||||||
_active = false;
|
_active = false;
|
||||||
}
|
}
|
||||||
|
bool running() {
|
||||||
|
return _active;
|
||||||
|
}
|
||||||
|
byte getLength8() {
|
||||||
|
return (millis() - _tmr) * 255ul / _interval;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t _tmr = 0;
|
uint32_t _tmr = 0;
|
||||||
|
Reference in New Issue
Block a user