This commit is contained in:
Alex
2021-02-25 02:29:25 +03:00
parent 4ea34e6cfd
commit a3b58c876e
13 changed files with 256 additions and 103 deletions

View File

@@ -0,0 +1,89 @@
#pragma once
#include <Arduino.h>
class Clap {
public:
void tick(int val) {
if (millis() - _tmr >= 10) {
_tmr = millis();
int der = val - _prevVal;
_prevVal = val;
int signal = 0;
int front = 0;
if (der > _trsh) signal = 1;
if (der < -_trsh) signal = -1;
if (_prevSignal == 0 && signal == 1) front = 1;
if (_prevSignal == 0 && signal == -1) front = -1;
_prevSignal = signal;
uint32_t deb = millis() - _tmr2;
if (front == 1 && _state == 0) {
_state = 1;
if (!_startClap) {
_claps = 0;
_ready = 0;
}
_startClap = 1;
_clap = 0;
_tmr2 = millis();
} else if (front == -1 && _state == 1 && deb <= 200) {
_state = 2;
_tmr2 = millis();
} else if (front == 0 && _state == 2 && deb <= 200) {
_state = 0;
_claps++;
_clap = 1;
_tmr2 = millis();
} else if (_startClap && deb > _tout) {
_state = 0;
_startClap = 0;
if (_claps != 0) _ready = 1;
}
}
}
void setTrsh(int trsh) {
_trsh = trsh;
}
void setTimeout(int tout) {
_tout = tout;
}
bool isClap() {
if (_clap) {
_clap = 0;
return 1;
}
return 0;
}
bool hasClaps(byte claps) {
if (_ready && _claps == claps) {
_ready = 0;
_claps = 0;
return 1;
}
return 0;
}
bool hasClaps() {
return _ready;
}
byte getClaps() {
if (_ready) {
_ready = 0;
byte buf = _claps;
_claps = 0;
return buf;
} return 0;
}
private:
uint32_t _tmr = 0, _tmr2 = 0;
int _prevVal = 0;
int _trsh = 150;
byte _state = 0;
int8_t _prevSignal = 0;
int _tout = 700;
byte _claps = 0;
bool _ready = 0;
bool _clap = 0;
bool _startClap = 0;
};

View File

@@ -8,6 +8,10 @@
class FastFilter {
public:
FastFilter(byte k = 20, int dt = 0) {
setK(k);
setDt(dt);
}
void setK(byte k) {
_k1 = k;
_k2 = 32 - k;

View File

@@ -1,4 +1,13 @@
/*
Версия 0.17b
Автосмена отключается 30 сек во время настройки режимов
Убрана кнопка upload в режимах
Лампа чуть мигает при получении данных
Кастом палитра работает на огне 2020
Вкл выкл двумя хлопками
Плавное выключение
Починил рассвет
Версия 0.16b
Исправлен масштаб огня 2020
Фикс невыключения рассвета
@@ -27,13 +36,12 @@
Выключение по таймеру теперь плавное
Добавлен рассвет
TODO:
TODO:
плавная смена режимов
4 клика вкл выкл смену?
Mqtt?
Базовый пак
Предложения Серёги крутского
Убрать аплод?
Эффект погода https://it4it.club/topic/40-esp8266-i-parsing-pogodyi-s-openweathermap/
Эффект часы
*/
@@ -55,6 +63,7 @@
// ------------- АЦП --------------
#define USE_ADC 1 // можно выпилить АЦП
#define USE_CLAP 1 // два хлопка в ладоши вкл выкл лампу
#define MIC_VCC 12 // питание микрофона GPIO12 (D6 на wemos/node)
#define PHOT_VCC 14 // питание фоторезистора GPIO14 (D5 на wemos/node)
@@ -77,10 +86,10 @@ const char AP_NameChar[] = "GyverLamp2";
const char WiFiPassword[] = "12345678";
// ------------ Прочее -------------
#define GL_VERSION 016 // код версии прошивки
#define GL_VERSION 017 // код версии прошивки
#define EE_TOUT 30000 // таймаут сохранения епром после изменения, мс
//#define DEBUG_SERIAL // закомментируй чтобы выключить отладку (скорость 115200)
#define EE_KEY 52 // ключ сброса WiFi (измени для сброса всех настроек)
#define EE_KEY 55 // ключ сброса WiFi (измени для сброса всех настроек)
#define NTP_UPD_PRD 5 // период обновления времени с NTP сервера, минут
//#define SKIP_WIFI // пропустить подключение к вафле (для отладки)
@@ -113,6 +122,7 @@ const char WiFiPassword[] = "12345678";
#include <EEPROM.h> // епром
#include "ESP8266httpUpdate.h" // OTA
#include "mString.h" // стринг билдер
#include "Clap.h" // обработка хлопков
// ------------------- ДАТА --------------------
Config cfg;
@@ -126,10 +136,11 @@ NTPClient ntp(ntpUDP);
CRGB leds[MAX_LEDS];
Time now;
Button btn(BTN_PIN);
timerMillis EEtmr(EE_TOUT), turnoffTmr, connTmr(120000), dawnTmr;
timerMillis EEtmr(EE_TOUT), turnoffTmr, connTmr(120000ul), dawnTmr, holdPresTmr(30000ul), blinkTmr(300);
TimeRandom trnd;
VolAnalyzer vol(A0), low, high;
FastFilter phot;
Clap clap;
byte btnClicks = 0, brTicks = 0;
unsigned char matrixValue[11][16];
@@ -145,7 +156,7 @@ void setup() {
Serial.begin(115200);
DEBUGLN();
#endif
EEPROM.begin(512); // старт епром
EEPROM.begin(1000); // старт епром
startStrip(); // старт ленты
btn.setLevel(digitalRead(BTN_PIN)); // смотрим что за кнопка
EE_startup(); // читаем епром

View File

@@ -49,8 +49,8 @@ class VolAnalyzer {
}
bool tick(int thisRead = -1) {
volF.compute();
if (millis() - tmr4 >= _ampliDt) { // период сглаживания амплитуды
tmr4 = millis();
if (millis() - tmr3 >= _ampliDt) { // период сглаживания амплитуды
tmr3 = millis();
maxF.setRaw(maxs);
minF.setRaw(mins);
maxF.compute();
@@ -68,11 +68,13 @@ class VolAnalyzer {
maxF.setFil(thisRead);
minF.setFil(thisRead);
}
if (++count >= _window) { // выборка завершена
tmr1 = millis();
raw = max;
if (max > maxs) maxs = max; // максимумы среди максимумов
if (max < mins) mins = max; // минимумы реди максимумов
rawMax = maxs;
maxF.checkPass(max); // проверка выше максимума
if (getMax() - getMin() < _trsh) max = 0; // если окно громкости меньше порого то 0
else max = constrain(map(max, getMin(), getMax(), _volMin, _volMax), _volMin, _volMax); // перевод в громкость
@@ -89,6 +91,9 @@ class VolAnalyzer {
int getRaw() {
return raw;
}
int getRawMax() {
return rawMax;
}
int getVol() {
return volF.getFil();
}
@@ -108,15 +113,16 @@ class VolAnalyzer {
private:
int _pin;
int _dt = 600; // 600 мкс между сэмплами достаточно для музыки
int _period = 5; // 5 мс между выборами достаточно
int _dt = 500; // 500 мкс между сэмплами достаточно для музыки
int _period = 4; // 4 мс между выборами достаточно
int _ampliDt = 150;
int _window = 20; // при таком размере окна получаем длительность оцифровки 12 мс, вполне хватает
uint32_t tmr1 = 0, tmr2 = 0, tmr3 = 0, tmr4 = 0;
int _window = 20; // при таком размере окна получаем длительность оцифровки вполне хватает
uint32_t tmr1 = 0, tmr2 = 0, tmr3 = 0;
int raw = 0;
int rawMax = 0;
int max = 0, count = 0;
int maxs = 0, mins = 1023;
int _volMin = 0, _volMax = 100, _trsh = 30;
bool _pulse = 0, _first = 0;
bool _pulse = 0, _first = 0;
FastFilter minF, maxF, volF;
};

View File

@@ -1,5 +1,6 @@
#if (USE_ADC == 1)
void setupADC() {
clap.setTimeout(500);
low.setDt(0);
low.setPeriod(0);
low.setWindow(0);
@@ -32,32 +33,36 @@ void setupADC() {
void checkAnalog() {
if (cfg.state) {
switch (cfg.adcMode) {
case GL_ADC_NONE: break;
case GL_ADC_BRI: checkPhot(); break;
case GL_ADC_MIC: checkMusic(); break;
case GL_ADC_BOTH:
{
static timerMillis tmr(1000, 1);
if (tmr.isReady()) {
switchToPhot();
phot.setRaw(analogRead(A0));
switchToMic();
} else {
checkMusic();
}
phot.compute();
//if (cfg.state) {
switch (cfg.adcMode) {
case GL_ADC_NONE: break;
case GL_ADC_BRI: checkPhot(); break;
case GL_ADC_MIC: checkMusic(); break;
case GL_ADC_BOTH:
{
static timerMillis tmr(1000, 1);
if (tmr.isReady()) {
switchToPhot();
phot.setRaw(analogRead(A0));
switchToMic();
} else {
checkMusic();
}
break;
}
phot.compute();
}
break;
}
//}
}
void checkMusic() {
if (CUR_PRES.advMode == GL_ADV_VOL) { // громкость
vol.tick();
} else if (CUR_PRES.advMode == GL_ADV_LOW || CUR_PRES.advMode == GL_ADV_HIGH) { // частоты
vol.tick();
#if (USE_CLAP == 1)
clap.tick(vol.getRawMax());
if (clap.hasClaps(2)) controlHandler(!cfg.state);
#endif
if (CUR_PRES.advMode == GL_ADV_LOW || CUR_PRES.advMode == GL_ADV_HIGH) { // частоты
int raw[FFT_SIZE], spectr[FFT_SIZE];
for (int i = 0; i < FFT_SIZE; i++) raw[i] = analogRead(A0);
FFT(raw, spectr);

View File

@@ -16,7 +16,7 @@
#define GL_REACT_LEN 3
#define GL_SLAVE 0
#define GL_MASTER 1
#define MAX_PRESETS 25 // макс количество режимов
#define MAX_PRESETS 40 // макс количество режимов
// ------------------- МАКРО --------------------
#ifdef DEBUG_SERIAL
@@ -61,9 +61,8 @@ struct Palette {
byte strip[16 * 3];
};
#define CFG_SIZE 13
#define CFG_SIZE 12
struct Config {
byte GMT = 3; // часовой пояс +13
byte bright = 100; // яркость
byte adcMode = 1; // режим ацп (1 выкл, 2 ярк, 3 муз)
byte minBright = 0; // мин яркость
@@ -79,7 +78,15 @@ struct Config {
int16_t length = 16; // длина ленты
int16_t width = 16; // ширина матрицы
byte GMT = 3; // часовой пояс +13
uint32_t cityID = 1; // city ID
bool mqtt = 0; // mqtt
char mqttID[32]; //
char mqttHost[32]; //
int mqttPort = 0; //
char mqttLogin[16]; //
char mqttPass[16]; //
byte state = 1; // состояние 0 выкл, 1 вкл
byte group = 1; // группа девайса (1-10)

View File

@@ -5,23 +5,23 @@ bool EEpalFlag = false;
void EE_startup() {
// старт епром
if (EEPROM.read(511) != EE_KEY) {
EEPROM.write(511, EE_KEY);
EEPROM.put(0, cfg);
EEPROM.put(sizeof(cfg), dawn);
EEPROM.put(sizeof(cfg) + sizeof(dawn), pal);
EEPROM.put(sizeof(cfg) + sizeof(dawn) + sizeof(pal), preset);
if (EEPROM.read(0) != EE_KEY) {
EEPROM.write(0, EE_KEY);
EEPROM.put(1, cfg);
EEPROM.put(sizeof(cfg) + 1, dawn);
EEPROM.put(sizeof(cfg) + sizeof(dawn) + 1, pal);
EEPROM.put(sizeof(cfg) + sizeof(dawn) + sizeof(pal) + 1, preset);
EEPROM.commit();
blink8(CRGB::Magenta);
DEBUGLN("First start");
}
EEPROM.get(0, cfg);
EEPROM.get(sizeof(cfg), dawn);
EEPROM.get(sizeof(cfg) + sizeof(dawn), pal);
EEPROM.get(sizeof(cfg) + sizeof(dawn) + sizeof(pal), preset);
EEPROM.get(1, cfg);
EEPROM.get(sizeof(cfg) + 1, dawn);
EEPROM.get(sizeof(cfg) + sizeof(dawn) + 1, pal);
EEPROM.get(sizeof(cfg) + sizeof(dawn) + sizeof(pal) + 1, preset);
DEBUG("EEPR size: ");
DEBUGLN(sizeof(cfg) + sizeof(dawn) + sizeof(pal) + sizeof(preset));
DEBUGLN(sizeof(cfg) + sizeof(dawn) + sizeof(pal) + sizeof(preset) + 1);
// запускаем всё
FastLED.setMaxPowerInVoltsAndMilliamps(STRIP_VOLT, cfg.maxCur * 100);
@@ -49,24 +49,24 @@ void checkEEupdate() {
if (EEcfgFlag || EEdawnFlag || EEpresetFlag) {
if (EEcfgFlag) {
EEcfgFlag = false;
EEPROM.put(0, cfg);
EEPROM.put(1, cfg);
DEBUGLN("save cfg");
}
if (EEdawnFlag) {
EEdawnFlag = false;
EEPROM.put(sizeof(cfg), dawn);
EEPROM.put(sizeof(cfg) + 1, dawn);
DEBUGLN("save dawn");
}
if (EEpalFlag) {
EEpalFlag = false;
EEPROM.put(sizeof(cfg) + sizeof(dawn), pal);
EEPROM.put(sizeof(cfg) + sizeof(dawn) + 1, pal);
DEBUGLN("save pal");
}
if (EEpresetFlag) {
EEpresetFlag = false;
EEPROM.put(sizeof(cfg) + sizeof(dawn) + sizeof(pal), preset);
EEPROM.put(sizeof(cfg) + sizeof(dawn) + sizeof(pal) + 1, preset);
DEBUGLN("save preset");
}
}
EEPROM.commit();
}
EEtmr.stop();
@@ -79,6 +79,6 @@ void EE_updCfgRst() {
ESP.restart();
}
void EE_updCfg() {
EEPROM.put(0, cfg);
EEPROM.put(1, cfg);
EEPROM.commit();
}

View File

@@ -22,6 +22,7 @@ void effectsRoutine() {
byte thisBright = getBright();
if (turnoffTmr.running()) thisBright = scaleFF(thisBright, 255 - turnoffTmr.getLength8());
else if (blinkTmr.runningStop()) thisBright = scaleFF(thisBright, blinkTmr.getLength8());
if (turnoffTmr.isReady()) {
turnoffTmr.stop();
setPower(0);
@@ -40,12 +41,12 @@ void effectsRoutine() {
if (cfg.deviceType > 1) {
FOR_j(0, cfg.length) {
FOR_i(0, cfg.width) {
leds[getPix(i, j)] = ColorFromPalette(paletteArr[CUR_PRES.palette - 1],
scalePal(inoise8(
i * (thisScale / 5) - cfg.width * (thisScale / 5) / 2,
j * (thisScale / 5) - cfg.length * (thisScale / 5) / 2,
(now.weekMs >> 1) * CUR_PRES.speed / 255)),
255, LINEARBLEND);
setPix(i, j, ColorFromPalette(paletteArr[CUR_PRES.palette - 1],
scalePal(inoise8(
i * (thisScale / 5) - cfg.width * (thisScale / 5) / 2,
j * (thisScale / 5) - cfg.length * (thisScale / 5) / 2,
(now.weekMs >> 1) * CUR_PRES.speed / 255)),
255, LINEARBLEND));
}
}
@@ -169,7 +170,7 @@ void effectsRoutine() {
case 7: // ==================================== ОГОНЬ 2020 ====================================
FastLED.clear();
if (cfg.deviceType > 1) { // 2D огонь
if (cfg.deviceType > 1) { // 2D огонь
fire2020(CUR_PRES.scale, thisLength);
} else { // 1D огонь
static byte heat[MAX_LEDS];

View File

@@ -31,7 +31,7 @@ void fire2020(byte scale, int len) {
}
for (uint8_t i = 0; i < cfg.width; i++) {
for (uint8_t j = 0; j < len; j++) {
leds[getPix(i, len - 1U - j)] = ColorFromPalette(paletteArr[CUR_PRES.palette - 1], qsub8(inoise8(i * deltaValue, (j + ff_y + random8(2)) * deltaHue, ff_z), shiftHue[j]), 255U);
leds[getPix(i, len - 1U - j)] = ColorFromPalette(paletteArr[CUR_PRES.palette - 1], scalePal(qsub8(inoise8(i * deltaValue, (j + ff_y + random8(2)) * deltaHue, ff_z), shiftHue[j])), 255U);
}
}

View File

@@ -9,17 +9,15 @@ void parsing() {
buf[n] = NULL;
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
if (strncmp(buf, GL_KEY, keyLen)) return; // не наш ключ
byte data[MAX_PRESETS * PRES_SIZE + 5];
memset(data, 0, MAX_PRESETS * PRES_SIZE + keyLen);
memset(data, 0, MAX_PRESETS * PRES_SIZE + 5);
int count = 0;
char *str, *p = buf + keyLen; // сдвиг до даты
char *ssid, *pass;
uint32_t city = 0;
uint16_t stripL, stripW;
while ((str = strtok_r(p, ",", &p)) != NULL) {
uint32_t thisInt = atoi(str);
data[count++] = (byte)thisInt;
@@ -28,9 +26,16 @@ void parsing() {
if (count == 5) pass = str;
}
if (data[1] == 1) {
if (count == 16) stripL = thisInt;
if (count == 17) stripW = thisInt;
if (count == 18) city = thisInt;
if (count == 15) cfg.length = thisInt;
if (count == 16) cfg.width = thisInt;
if (count == 17) cfg.GMT = byte(thisInt);
if (count == 18) cfg.cityID = thisInt;
if (count == 19) cfg.mqtt = byte(thisInt);
if (count == 20) strcpy(cfg.mqttID, str);
if (count == 21) strcpy(cfg.mqttHost, str);
if (count == 22) cfg.mqttPort = thisInt;
if (count == 23) strcpy(cfg.mqttLogin, str);
if (count == 24) strcpy(cfg.mqttPass, str);
}
}
@@ -46,7 +51,7 @@ void parsing() {
if (data[0] != cfg.group) return; // не наш адрес, выходим
switch (data[1]) { // тип 0 - control, 1 - config, 2 - effects, 3 - dawn, 4 - from master, 5 - palette
case 0: DEBUGLN("Control");
case 0: DEBUGLN("Control"); blinkTmr.restart();
switch (data[2]) {
case 0: controlHandler(0); break; // выкл
case 1: controlHandler(1); break; // вкл
@@ -81,24 +86,21 @@ void parsing() {
case 13: // выключить через
if (data[3] == 0) turnoffTmr.stop();
else {
turnoffTmr.setInterval((uint32_t)data[3] * 60000ul);
turnoffTmr.restart();
fadeDown((uint32_t)data[3] * 60000ul);
}
break;
}
EE_updCfg();
break;
case 1: DEBUGLN("Config");
case 1: DEBUGLN("Config"); blinkTmr.restart();
FOR_i(0, CFG_SIZE) {
*((byte*)&cfg + i) = data[i + 2]; // загоняем в структуру
}
cfg.length = stripL;
cfg.width = stripW;
cfg.cityID = city;
if (cfg.length > MAX_LEDS) cfg.length = MAX_LEDS;
if (cfg.deviceType == GL_TYPE_STRIP) cfg.width = 1;
if (cfg.deviceType == GL_TYPE_STRIP) {
if (cfg.length > MAX_LEDS) cfg.length = MAX_LEDS;
cfg.width = 1;
}
if (cfg.length * cfg.width > MAX_LEDS) cfg.width = MAX_LEDS / cfg.length;
ntp.setTimeOffset((cfg.GMT - 13) * 3600);
FastLED.setMaxPowerInVoltsAndMilliamps(STRIP_VOLT, cfg.maxCur * 100);
@@ -115,13 +117,15 @@ void parsing() {
*((byte*)&preset + j * PRES_SIZE + i) = data[j * PRES_SIZE + i + 3]; // загоняем в структуру
}
}
if (!cfg.rotation) setPreset(data[cfg.presetAmount * PRES_SIZE + 3] - 1);
//if (!cfg.rotation) setPreset(data[cfg.presetAmount * PRES_SIZE + 3] - 1);
setPreset(data[cfg.presetAmount * PRES_SIZE + 3] - 1);
EE_updatePreset();
presetRotation(true); // форсировать смену режима
//presetRotation(true); // форсировать смену режима
holdPresTmr.restart();
loading = true;
break;
case 3: DEBUGLN("Dawn");
case 3: DEBUGLN("Dawn"); blinkTmr.restart();
FOR_i(0, (2 + 3 * 7)) {
*((byte*)&dawn + i) = data[i + 2]; // загоняем в структуру
}
@@ -131,7 +135,7 @@ void parsing() {
case 4: DEBUGLN("From master");
if (cfg.role == GL_SLAVE) {
switch (data[2]) {
case 0: setPower(data[3]); break; // вкл выкл
case 0: fade(data[3]); break; // вкл выкл
case 1: setPreset(data[3]); break; // пресет
case 2: cfg.bright = data[3]; break; // яркость
}
@@ -139,7 +143,7 @@ void parsing() {
}
break;
case 5: DEBUGLN("Palette");
case 5: DEBUGLN("Palette"); blinkTmr.restart();
FOR_i(0, 1 + 16 * 3) {
*((byte*)&pal + i) = data[i + 2]; // загоняем в структуру
}
@@ -147,7 +151,7 @@ void parsing() {
EE_updatePal();
break;
case 6: DEBUGLN("Time");
case 6: DEBUGLN("Time"); blinkTmr.restart();
if (!cfg.WiFimode) { // если мы AP
now.day = data[2];
now.hour = data[3];

View File

@@ -1,5 +1,6 @@
void presetRotation(bool force) {
if (cfg.rotation && (now.newMin() || force)) { // если автосмена и новая минута
if (holdPresTmr.runningStop()) return;
if (cfg.rotation && (now.newMin() || force)) { // если автосмена и новая минута
if (cfg.rotRnd) { // случайная
cfg.curPreset = trnd.fromMin(cfg.rotPeriod, cfg.presetAmount);
DEBUG("Rnd changed to ");
@@ -17,35 +18,46 @@ void changePreset(int dir) {
cfg.curPreset += dir;
if (cfg.curPreset >= cfg.presetAmount) cfg.curPreset = 0;
if (cfg.curPreset < 0) cfg.curPreset = cfg.presetAmount - 1;
holdPresTmr.restart();
DEBUG("Preset changed to ");
DEBUGLN(cfg.curPreset);
}
}
void setPreset(byte pres) {
if (!cfg.rotation) { // ручная смена
cfg.curPreset = constrain(pres, 0, cfg.presetAmount - 1);
DEBUG("Preset set to ");
DEBUGLN(cfg.curPreset);
}
//if (!cfg.rotation) { // ручная смена
cfg.curPreset = constrain(pres, 0, cfg.presetAmount - 1);
holdPresTmr.restart();
DEBUG("Preset set to ");
DEBUGLN(cfg.curPreset);
//}
}
void controlHandler(bool state) {
if (turnoffTmr.running()) {
turnoffTmr.stop();
delay(50);
FastLED.clear();
FastLED.show();
DEBUGLN("stop off timer");
return;
}
if (dawnTmr.running()) {
dawnTmr.stop();
delay(50);
FastLED.clear();
FastLED.show();
DEBUGLN("stop dawn timer");
return;
}
}
if (state) cfg.manualOff = 0;
if (cfg.state && !state) cfg.manualOff = 1;
setPower(state);
fade(state);
}
void fade(bool state) {
if (cfg.state && !state) fadeDown(600);
else setPower(state);
}
void setPower(bool state) {
@@ -58,3 +70,8 @@ void setPower(bool state) {
sendToSlaves(0, cfg.state);
DEBUGLN(state ? "Power on" : "Power off");
}
void fadeDown(uint32_t time) {
turnoffTmr.setInterval(time);
turnoffTmr.restart();
}

View File

@@ -5,7 +5,10 @@ void setupTime() {
if (cfg.WiFimode) {
// если подключены - запрашиваем время с сервера
ntp.begin();
if (ntp.update() && !gotNTP) gotNTP = true;
if (ntp.update() && !gotNTP) {
gotNTP = true;
DEBUGLN("Got ntp");
}
}
}
@@ -31,11 +34,11 @@ void updateTime() {
if (now.min % NTP_UPD_PRD == 0 && now.sec == 0) {
// берём время с интернета каждую NTP_UPD_PRD минуту, ставим флаг что данные с NTP получены, значит мы онлайн
if (ntp.update() && !gotNTP) gotNTP = true;
}
checkDawn();
}
} else { // если нет
now.tick(); // тикаем своим счётчиком
}
if (gotNTP || gotTime) checkDawn();
}
void sendTimeToSlaves() {
@@ -53,9 +56,11 @@ void checkDawn() {
int dawnMinute = dawn.hour[now.day] * 60 + dawn.minute[now.day] - dawn.time;
if (dawnMinute < 0) dawnMinute += 1440;
if (dawnMinute == now.hour * 60 + now.min) {
DEBUGLN("dawn start");
DEBUG("dawn start ");
DEBUGLN(dawn.time * 60000ul);
dawnTmr.setInterval(dawn.time * 60000ul);
dawnTmr.restart();
FastLED.setBrightness(255);
}
}
}
@@ -65,8 +70,8 @@ void checkWorkTime() {
byte curState = isWorkTime(now.hour, cfg.workFrom, cfg.workTo);
if (prevState != curState) { // переключение расписания
prevState = curState;
if (curState && !cfg.state && !cfg.manualOff) setPower(1); // нужно включить, а лампа выключена и не выключалась вручную
if (!curState && cfg.state) setPower(0); // нужно выключить, а лампа включена
if (curState && !cfg.state && !cfg.manualOff) fade(1); // нужно включить, а лампа выключена и не выключалась вручную
if (!curState && cfg.state) fade(0); // нужно выключить, а лампа включена
}
}

View File

@@ -17,6 +17,10 @@ class timerMillis {
}
return false;
}
boolean runningStop() {
if (_active && millis() - _tmr >= _interval) stop();
return _active;
}
void reset() {
_tmr = millis();
}
@@ -31,7 +35,7 @@ class timerMillis {
return _active;
}
byte getLength8() {
return (millis() - _tmr) * 255ul / _interval;
return (_active) ? ((millis() - _tmr) * 255ul / _interval) : 0;
}
private: