This commit is contained in:
Alex
2021-02-27 15:48:45 +03:00
parent 7b0333190a
commit 70a42bfe67
11 changed files with 250 additions and 155 deletions

View File

@@ -0,0 +1,23 @@
void sendUDP(char *data) {
IPAddress ip = WiFi.localIP();
ip[3] = 255;
Udp.beginPacket(ip, 50000 + cfg.group);
Udp.write(data);
Udp.endPacket();
}
void restartUDP() {
DEBUG("UDP port: ");
DEBUGLN(50000 + cfg.group);
Udp.stop();
Udp.begin(50000 + cfg.group);
}
void blink8(CRGB color) {
FOR_i(0, 3) {
fill_solid(leds, 8, color);
FastLED.show();
delay(300);
FastLED.clear();
FastLED.show();
delay(300);
}
}

View File

@@ -1,4 +1,12 @@
/*
Версия 0.18b
Уменьшена чувствительность хлопков
Увеличена плавность светомузыки
Переделана сетевая политика
Микрофон и датчик света опрашивает только мастер и отсылает данные слейвам своей группы
4 клика - включить первый режим
Отправка точного времени на лампу в режиме АР для работы рассвета и синхронизации эффектов
Версия 0.17b
Автосмена отключается 30 сек во время настройки режимов
Убрана кнопка upload в режимах
@@ -38,7 +46,6 @@
TODO:
плавная смена режимов
4 клика вкл выкл смену?
Mqtt?
Базовый пак
Предложения Серёги крутского
@@ -86,7 +93,7 @@ const char AP_NameChar[] = "GyverLamp2";
const char WiFiPassword[] = "12345678";
// ------------ Прочее -------------
#define GL_VERSION 017 // код версии прошивки
#define GL_VERSION 18 // код версии прошивки
#define EE_TOUT 30000 // таймаут сохранения епром после изменения, мс
//#define DEBUG_SERIAL // закомментируй чтобы выключить отладку (скорость 115200)
#define EE_KEY 55 // ключ сброса WiFi (измени для сброса всех настроек)
@@ -94,17 +101,18 @@ const char WiFiPassword[] = "12345678";
//#define SKIP_WIFI // пропустить подключение к вафле (для отладки)
// ------------ БИЛДЕР -------------
//#define MAX_LEDS 1200
#define MAX_LEDS 1200
// esp01
//#define BTN_PIN 0
//#define STRIP_PIN 2
//#define USE_ADC 0
#define BTN_PIN 0
#define STRIP_PIN 2
#define USE_ADC 0
// GL2 module
//#define STRIP_PIN 5 // GPIO5 на gl module (D1 на wemos/node)
// ---------- БИБЛИОТЕКИ -----------
#define FASTLED_ALLOW_INTERRUPTS 0
#include "data.h" // данные
#include "Time.h" // часы
#include "TimeRandom.h" // случайные числа по времени
@@ -115,7 +123,6 @@ const char WiFiPassword[] = "12345678";
#include "timerMillis.h" // таймер миллис
#include "VolAnalyzer.h" // анализатор громкости
#include "FFT_C.h" // фурье
#define FASTLED_ALLOW_INTERRUPTS 0
#include <FastLED.h> // лента
#include <ESP8266WiFi.h> // базовая либа есп
#include <WiFiUdp.h> // общение по UDP
@@ -146,7 +153,9 @@ byte btnClicks = 0, brTicks = 0;
unsigned char matrixValue[11][16];
bool gotNTP = false, gotTime = false;
bool loading = true;
void blink8(CRGB color);
int udpLength = 0, udpWidth = 0;
byte udpScale = 0, udpBright = 0;
// ------------------- SETUP --------------------
void setup() {

View File

@@ -1,6 +1,8 @@
#if (USE_ADC == 1)
void setupADC() {
clap.setTimeout(500);
clap.setTrsh(250);
low.setDt(0);
low.setPeriod(0);
low.setWindow(0);
@@ -8,9 +10,9 @@ void setupADC() {
high.setPeriod(0);
high.setWindow(0);
vol.setVolK(20);
low.setVolK(20);
high.setVolK(20);
vol.setVolK(26);
low.setVolK(26);
high.setVolK(26);
vol.setTrsh(50);
low.setTrsh(50);
@@ -33,7 +35,7 @@ void setupADC() {
void checkAnalog() {
//if (cfg.state) {
if (cfg.role) {
switch (cfg.adcMode) {
case GL_ADC_NONE: break;
case GL_ADC_BRI: checkPhot(); break;
@@ -52,7 +54,7 @@ void checkAnalog() {
}
break;
}
//}
}
}
void checkMusic() {

View File

@@ -27,11 +27,17 @@ void button() {
changePreset(-1);
sendToSlaves(1, cfg.curPreset);
break;
case 4:
setPreset(0);
sendToSlaves(1, cfg.curPreset);
break;
case 5:
cfg.role = 0;
blink8(CRGB::DarkSlateBlue);
break;
case 6:
cfg.role = 1;
blink8(CRGB::Maroon);
break;
}
EE_updateCfg();

View File

@@ -56,6 +56,7 @@ const char NTPserver[] = "pool.ntp.org";
//"ntp2.stratum2.ru"
//"ntp.msk-ix.ru"
#define PAL_SIZE 49
struct Palette {
byte size = 1;
byte strip[16 * 3];
@@ -120,6 +121,7 @@ struct Preset {
byte rnd = 0; // случайный (0/1)
};
#define DAWN_SIZE 23
struct Dawn {
byte state[7] = {0, 0, 0, 0, 0, 0, 0}; // (1/0)
byte hour[7] = {0, 0, 0, 0, 0, 0, 0}; // (0.. 59)

View File

@@ -16,10 +16,33 @@ void effectsRoutine() {
}
if (cfg.state && effTmr.isReady()) {
int thisLength = getLength();
byte thisScale = getScale();
int thisWidth = (cfg.deviceType > 1) ? cfg.width : 1;
byte thisBright = getBright();
int thisLength, thisWidth;
byte thisScale, thisBright;
if (cfg.adcMode > 1) { // музыка или яркость
if (cfg.role) {
thisLength = getLength();
thisScale = getScale();
thisWidth = (cfg.deviceType > 1) ? cfg.width : 1;
thisBright = getBright();
char reply[25];
mString packet(reply, sizeof(reply));
packet.clear();
packet = packet + GL_KEY + ",7," + thisLength + ',' + thisScale + ',' + thisWidth + ',' + thisBright;
sendUDP(reply);
} else {
thisLength = udpLength;
thisScale = udpScale;
thisWidth = udpWidth;
thisBright = udpBright;
}
} else { // нет
thisLength = getLength();
thisScale = getScale();
thisWidth = (cfg.deviceType > 1) ? cfg.width : 1;
thisBright = getBright();
}
if (turnoffTmr.running()) thisBright = scaleFF(thisBright, 255 - turnoffTmr.getLength8());
else if (blinkTmr.runningStop()) thisBright = scaleFF(thisBright, blinkTmr.getLength8());
@@ -273,17 +296,6 @@ void updPal() {
if (pal.size < 16) paletteArr[0][pal.size] = paletteArr[0][0];
}
void blink8(CRGB color) {
FOR_i(0, 3) {
fill_solid(leds, 8, color);
FastLED.show();
delay(300);
FastLED.clear();
FastLED.show();
delay(300);
}
}
byte scalePal(byte val) {
if (CUR_PRES.palette == 1) val = val * pal.size / 16;
return val;

View File

@@ -43,68 +43,67 @@ char* mFtoa(double value, int8_t decimals, char *buffer) {
class mString {
public:
int size = 0;
char* buf;
// system*this = buf;
int size = 0;
uint16_t length() {
return strlen(buf);
}
void clear() {
buf[0] = 0;
buf[0] = NULL;
}
// constructor
mString(char* buffer, int newSize) {
//*this = buf;
buf = buffer;
size = newSize;
}
/*mString (const char c) {
init();
//init();
add(c);
}
mString (const char* data) {
init();
//init();
add(data);
}
mString (const __FlashStringHelper *data) {
init();
//init();
add(data);
}
mString (uint32_t value) {
init();
//init();
add(value);
}
mString (int32_t value) {
init();
//init();
add(value);
}
mString (uint16_t value) {
init();
//init();
add(value);
}
mString (int16_t value) {
init();
//init();
add(value);
}
mString (uint8_t value) {
init();
//init();
add(value);
}
mString (int8_t value) {
init();
//init();
add(value);
}
mString (double value, byte dec = 2) {
init();
//init();
add(value, dec);
}*/
// add
mString& add(const char c) {
byte len = length();
if (len + 1 >= size) return *this;
buf[len++] = c;
buf[len++] = 0;
buf[len++] = NULL;
return *this;
}
mString& add(const char* data) {
@@ -112,11 +111,13 @@ class mString {
do {
buf[len] = *(data++);
} while (buf[len++] != 0);*/
if (length() + strlen(data) >= size) return *this;
strcpy(buf + length(), data);
return *this;
}
mString& add(const __FlashStringHelper *data) {
PGM_P p = reinterpret_cast<PGM_P>(data);
if (length() + strlen_P(p) >= size) return *this;
strcpy_P(buf + length(), p);
return *this;
/*do {
@@ -125,10 +126,9 @@ class mString {
*/
}
mString& add(uint32_t value) {
//char buf[11];
//return add(mUtoa(value, buf));
utoa(value, buf + length(), DEC);
return *this;
char vBuf[11];
utoa(value, vBuf, DEC);
return add(vBuf);
}
mString& add(uint16_t value) {
return add((uint32_t)value);
@@ -137,10 +137,9 @@ class mString {
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;
char vBuf[11];
ltoa(value, vBuf, DEC);
return add(vBuf);
}
mString& add(int16_t value) {
return add((int32_t)value);
@@ -149,11 +148,13 @@ class mString {
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;
char vBuf[20];
mFtoa(value, dec, vBuf);
return add(vBuf);
}
/*mString& add(mString data) {
return add(data.buf);
}*/
// add +=
mString& operator += (const char c) {
@@ -186,6 +187,44 @@ class mString {
mString& operator += (double value) {
return add(value);
}
/*mString& operator += (mString data) {
return add(data);
}*/
// +
mString operator + (const char c) {
return mString(*this) += c;
}
mString operator + (const char* data) {
return mString(*this) += data;
}
mString operator + (const __FlashStringHelper *data) {
return mString(*this) += data;
}
mString operator + (uint32_t value) {
return mString(*this) += value;
}
mString operator + (int32_t value) {
return mString(*this) += value;
}
mString operator + (uint16_t value) {
return mString(*this) += value;
}
mString operator + (int16_t value) {
return mString(*this) += value;
}
mString operator + (uint8_t value) {
return mString(*this) += value;
}
mString operator + (int8_t value) {
return mString(*this) += value;
}
mString operator + (double value) {
return mString(*this) += value;
}
/*mString operator + (mString data) {
return mString(*this) += data;
}*/
// assign
mString& operator = (const char c) {
@@ -228,6 +267,10 @@ class mString {
clear();
return add(value);
}
/*mString& operator = (mString data) {
clear();
return add(data);
}*/
// compare
bool operator == (const char c) {
@@ -248,15 +291,17 @@ class mString {
char valBuf[20];
return !strcmp(buf, mFtoa(value, 2, valBuf));
}
/*bool operator == (mString data) {
return (buf == data.buf);
}*/
// convert & parse
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);
}

View File

@@ -2,18 +2,29 @@ void parsing() {
if (Udp.parsePacket()) {
static uint32_t tmr = 0;
static char buf[UDP_TX_PACKET_MAX_SIZE + 1];
int n = Udp.read(buf, UDP_TX_PACKET_MAX_SIZE);
if (millis() - tmr < 500) return; // принимаем посылки не чаще 2 раз в секунду
tmr = millis();
buf[n] = NULL;
DEBUGLN(buf); // пакет вида <ключ>,<канал>,<тип>,<дата1>,<дата2>...
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 + 5);
if (buf[keyLen + 1] == '7') { // принимаем данные звука и ацп
int data[4];
mString ints(buf + keyLen + 3, 100);
ints.parseInts(data, 4);
udpLength = data[0];
udpScale = data[1];
udpWidth = data[2];
udpBright = data[3];
return;
}
if (millis() - tmr < 500) return; // принимаем посылки не чаще 2 раз в секунду
tmr = millis();
byte data[MAX_PRESETS * PRES_SIZE + 10];
memset(data, 0, MAX_PRESETS * PRES_SIZE + 10);
int count = 0;
char *str, *p = buf + keyLen; // сдвиг до даты
char *ssid, *pass;
@@ -39,8 +50,9 @@ void parsing() {
}
}
// широковещательный запрос времени для local устройств в сети AP лампы
// широковещательный запрос (адрес 0) времени для local устройств в сети AP лампы
if (data[0] == 0 && cfg.WiFimode && !gotNTP) {
now.day = data[1];
now.hour = data[2];
now.min = data[3];
@@ -62,7 +74,7 @@ void parsing() {
case 6: setPreset(data[3] - 1); break; // конкретный пресет data[3]
case 7: cfg.WiFimode = data[3]; EE_updCfgRst(); break; // смена режима WiFi
case 8: cfg.role = data[3]; break; // смена роли
case 9: cfg.group = data[3]; break; // смена группы
case 9: cfg.group = data[3]; restartUDP(); break; // смена группы
case 10: // установка настроек WiFi
strcpy(cfg.ssid, ssid);
strcpy(cfg.pass, pass);
@@ -90,6 +102,7 @@ void parsing() {
}
break;
}
if (data[2] < 7) setTime(data[3], data[4], data[5], data[6]);
EE_updCfg();
break;
@@ -97,6 +110,7 @@ void parsing() {
FOR_i(0, CFG_SIZE) {
*((byte*)&cfg + i) = data[i + 2]; // загоняем в структуру
}
setTime(data[CFG_SIZE + 10 + 2], data[CFG_SIZE + 10 + 3], data[CFG_SIZE + 10 + 4], data[CFG_SIZE + 10 + 5]);
if (cfg.deviceType == GL_TYPE_STRIP) {
if (cfg.length > MAX_LEDS) cfg.length = MAX_LEDS;
cfg.width = 1;
@@ -111,6 +125,7 @@ void parsing() {
break;
case 2: DEBUGLN("Preset");
{
cfg.presetAmount = data[2]; // кол-во режимов
FOR_j(0, cfg.presetAmount) {
FOR_i(0, PRES_SIZE) {
@@ -118,17 +133,22 @@ void parsing() {
}
}
//if (!cfg.rotation) setPreset(data[cfg.presetAmount * PRES_SIZE + 3] - 1);
setPreset(data[cfg.presetAmount * PRES_SIZE + 3] - 1);
byte dataStart = cfg.presetAmount * PRES_SIZE + 3;
setPreset(data[dataStart] - 1);
setTime(data[dataStart + 1], data[dataStart + 2], data[dataStart + 3], data[dataStart + 4]);
EE_updatePreset();
//presetRotation(true); // форсировать смену режима
holdPresTmr.restart();
loading = true;
}
break;
case 3: DEBUGLN("Dawn"); blinkTmr.restart();
FOR_i(0, (2 + 3 * 7)) {
FOR_i(0, DAWN_SIZE) {
*((byte*)&dawn + i) = data[i + 2]; // загоняем в структуру
}
setTime(data[DAWN_SIZE + 2], data[DAWN_SIZE + 3], data[DAWN_SIZE + 4], data[DAWN_SIZE + 5]);
EE_updateDawn();
break;
@@ -144,21 +164,13 @@ void parsing() {
break;
case 5: DEBUGLN("Palette"); blinkTmr.restart();
FOR_i(0, 1 + 16 * 3) {
FOR_i(0, PAL_SIZE) {
*((byte*)&pal + i) = data[i + 2]; // загоняем в структуру
}
setTime(data[PAL_SIZE + 2], data[PAL_SIZE + 3], data[PAL_SIZE + 4], data[PAL_SIZE + 5]);
updPal();
EE_updatePal();
break;
case 6: DEBUGLN("Time"); blinkTmr.restart();
if (!cfg.WiFimode) { // если мы AP
now.day = data[2];
now.hour = data[3];
now.min = data[4];
}
gotTime = true;
break;
}
FastLED.clear(); // на всякий случай
}
@@ -166,27 +178,16 @@ void parsing() {
void sendToSlaves(byte data1, byte data2) {
if (cfg.role == GL_MASTER) {
IPAddress ip = WiFi.localIP();
ip[3] = 255;
char reply[20];
mString packet(reply, sizeof(reply));
packet.clear();
packet += GL_KEY;
packet += ',';
packet += cfg.group;
packet += ",4,";
packet += data1;
packet += ',';
packet += data2;
packet = packet + GL_KEY + ',' + cfg.group + ",4," + data1 + ',' + data2;
DEBUG("Sending to Slaves: ");
DEBUGLN(reply);
FOR_i(0, 3) {
Udp.beginPacket(ip, 8888);
Udp.write(reply);
Udp.endPacket();
sendUDP(reply);
delay(10);
}
}

View File

@@ -14,14 +14,14 @@ void presetRotation(bool force) {
}
void changePreset(int dir) {
if (!cfg.rotation) { // ручная смена
//if (!cfg.rotation) { // ручная смена
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) {

View File

@@ -86,9 +86,7 @@ void startWiFi() {
if (!cfg.WiFimode) setupAP(); // режим точки доступа
else setupLocal(); // подключаемся к точке
DEBUG("UDP port: ");
DEBUGLN(8888);
Udp.begin(8888);
restartUDP();
FastLED.clear();
FastLED.show();
}

View File

@@ -23,6 +23,17 @@ void timeTicker() {
}
}
void setTime(byte day, byte hour, byte min, byte sec) {
if (!cfg.WiFimode || !gotNTP) { // если мы AP или не получили NTP
now.day = day;
now.hour = hour;
now.min = min;
now.sec = sec;
now.setMs(0);
gotTime = true;
}
}
void updateTime() {
if (cfg.WiFimode && WiFi.status() == WL_CONNECTED) { // если вайфай подключен
now.sec = ntp.getSeconds();
@@ -38,7 +49,7 @@ void updateTime() {
} else { // если нет
now.tick(); // тикаем своим счётчиком
}
if (gotNTP || gotTime) checkDawn();
if (gotNTP || gotTime) checkDawn(); // рассвет, если знаем точное время
}
void sendTimeToSlaves() {
@@ -76,28 +87,14 @@ void checkWorkTime() {
}
void sendTime() {
IPAddress ip = WiFi.localIP();
ip[3] = 255;
char reply[25] = GL_KEY;
char reply[25];
mString packet(reply, sizeof(reply));
packet.clear();
packet += GL_KEY;
packet += ',';
packet += 0;
packet += ',';
packet += now.day;
packet += ',';
packet += now.hour;
packet += ',';
packet += now.min;
packet += ',';
packet += now.sec;
packet = packet + GL_KEY + ",0," + now.day + ',' + now.hour + ',' + now.min + ',' + now.sec;
DEBUG("Sending time: ");
DEBUGLN(reply);
Udp.beginPacket(ip, 8888);
Udp.write(reply);
Udp.endPacket();
sendUDP(reply);
}
bool isWorkTime(byte t, byte from, byte to) {