diff --git a/.gitignore b/.gitignore index ea49cb51f..5e61e1565 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /wled00/Release /wled00/extLibs /platformio_override.ini +.clang-format diff --git a/usermods/blynk_relay_control/wled06_usermod.ino b/usermods/blynk_relay_control/wled06_usermod.ino index 1004b1ed3..d4028ea5d 100644 --- a/usermods/blynk_relay_control/wled06_usermod.ino +++ b/usermods/blynk_relay_control/wled06_usermod.ino @@ -1,7 +1,7 @@ /* * This file allows you to add own functionality to WLED more easily * See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality - * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled01_eeprom.h) + * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled_eeprom.h) * bytes 2400+ are currently ununsed, but might be used for future wled features */ diff --git a/usermods/stairway_wipe_basic/wled06_usermod.ino b/usermods/stairway_wipe_basic/wled06_usermod.ino index 3d493cc1d..0cc85df74 100644 --- a/usermods/stairway_wipe_basic/wled06_usermod.ino +++ b/usermods/stairway_wipe_basic/wled06_usermod.ino @@ -1,7 +1,7 @@ /* * This file allows you to add own functionality to WLED more easily * See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality - * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled01_eeprom.h) + * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled_eeprom.h) * bytes 2400+ are currently ununsed, but might be used for future wled features */ diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 1e3ec2d98..7230a9b3e 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -601,7 +601,7 @@ uint16_t WS2812FX::mode_hyper_sparkle(void) { } if(random8(5) < 2) { - for(uint16_t i = 0; i < max(1, SEGLEN/3); i++) { + for(uint16_t i = 0; i < MAX(1, SEGLEN/3); i++) { setPixelColor(random16(SEGLEN), SEGCOLOR(1)); } return 20; @@ -1115,7 +1115,7 @@ uint16_t WS2812FX::mode_fireworks() { if (valid1) setPixelColor(SEGENV.aux0 , sv1); if (valid2) setPixelColor(SEGENV.aux1, sv2); - for(uint16_t i=0; i> 1)) == 0) { uint16_t index = random(SEGLEN); setPixelColor(index, color_from_palette(random8(), false, false, 0)); @@ -1162,12 +1162,12 @@ uint16_t WS2812FX::mode_fire_flicker(void) { byte r = (SEGCOLOR(0) >> 16) & 0xFF; byte g = (SEGCOLOR(0) >> 8) & 0xFF; byte b = (SEGCOLOR(0) & 0xFF); - byte lum = (SEGMENT.palette == 0) ? max(w, max(r, max(g, b))) : 255; + byte lum = (SEGMENT.palette == 0) ? MAX(w, MAX(r, MAX(g, b))) : 255; lum /= (((256-SEGMENT.intensity)/16)+1); for(uint16_t i = 0; i < SEGLEN; i++) { byte flicker = random8(lum); if (SEGMENT.palette == 0) { - setPixelColor(i, max(r - flicker, 0), max(g - flicker, 0), max(b - flicker, 0), max(w - flicker, 0)); + setPixelColor(i, MAX(r - flicker, 0), MAX(g - flicker, 0), MAX(b - flicker, 0), MAX(w - flicker, 0)); } else { setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, 255 - flicker)); } @@ -1197,7 +1197,7 @@ uint16_t WS2812FX::gradient_base(bool loading) { { val = abs(((i>pp) ? p2:pp) -i); } else { - val = min(abs(pp-i),min(abs(p1-i),abs(p2-i))); + val = MIN(abs(pp-i),MIN(abs(p1-i),abs(p2-i))); } val = (brd > val) ? val/brd * 255 : 255; setPixelColor(i, color_blend(SEGCOLOR(0), color_from_palette(i, true, PALETTE_SOLID_WRAP, 1), val)); @@ -1778,7 +1778,7 @@ uint16_t WS2812FX::mode_fire_2012() // Step 4. Map from heat cells to LED colors for (uint16_t j = 0; j < SEGLEN; j++) { - CRGB color = ColorFromPalette(currentPalette, min(heat[j],240), 255, LINEARBLEND); + CRGB color = ColorFromPalette(currentPalette, MIN(heat[j],240), 255, LINEARBLEND); setPixelColor(j, color.red, color.green, color.blue); } return FRAMETIME; @@ -2573,7 +2573,7 @@ uint16_t WS2812FX::mode_bouncing_balls(void) { uint32_t color = SEGCOLOR(0); if (SEGMENT.palette) { - color = color_wheel(i*(256/max(numBalls, 8))); + color = color_wheel(i*(256/MAX(numBalls, 8))); } else if (hasCol2) { color = SEGCOLOR(i % NUM_COLORS); } @@ -3101,7 +3101,7 @@ uint16_t WS2812FX::mode_plasma(void) { */ uint16_t WS2812FX::mode_percent(void) { - uint8_t percent = max(0, min(200, SEGMENT.intensity)); + uint8_t percent = MAX(0, MIN(200, SEGMENT.intensity)); uint16_t active_leds = (percent < 100) ? SEGLEN * percent / 100.0 : SEGLEN * (200 - percent) / 100.0; diff --git a/wled00/FX.h b/wled00/FX.h index a87da8e25..a38a1f542 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -38,8 +38,8 @@ #define DEFAULT_SPEED (uint8_t)128 #define DEFAULT_COLOR (uint32_t)0xFFAA00 -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)>(b)?(a):(b)) +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MAX(a,b) ((a)>(b)?(a):(b)) /* Not used in all effects yet */ #define WLED_FPS 42 diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 055686237..de89a430e 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -224,7 +224,7 @@ void WS2812FX::show(void) { if(useWackyWS2815PowerModel) { // ignore white component on WS2815 power calculation - powerSum += (max(max(c.R,c.G),c.B)) * 3; + powerSum += (MAX(MAX(c.R,c.G),c.B)) * 3; } else { @@ -647,7 +647,7 @@ uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) { r = random8(); x = abs(pos - r); y = 255 - x; - d = min(x, y); + d = MIN(x, y); } return r; } @@ -730,8 +730,8 @@ void WS2812FX::handle_palette(void) CHSV prim_hsv = rgb2hsv_approximate(prim); targetPalette = CRGBPalette16( CHSV(prim_hsv.h, prim_hsv.s, prim_hsv.v), //color itself - CHSV(prim_hsv.h, max(prim_hsv.s - 50,0), prim_hsv.v), //less saturated - CHSV(prim_hsv.h, prim_hsv.s, max(prim_hsv.v - 50,0)), //darker + CHSV(prim_hsv.h, MAX(prim_hsv.s - 50,0), prim_hsv.v), //less saturated + CHSV(prim_hsv.h, prim_hsv.s, MAX(prim_hsv.v - 50,0)), //darker CHSV(prim_hsv.h, prim_hsv.s, prim_hsv.v)); //color itself break;} case 4: {//primary + secondary diff --git a/wled00/wled12_alexa.ino b/wled00/alexa.cpp similarity index 89% rename from wled00/wled12_alexa.ino rename to wled00/alexa.cpp index 5163640e2..e35f5b358 100644 --- a/wled00/wled12_alexa.ino +++ b/wled00/alexa.cpp @@ -1,10 +1,9 @@ -/* - * Alexa Voice On/Off/Brightness Control. Emulates a Philips Hue bridge to Alexa. - * - * This was put together from these two excellent projects: - * https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch - * https://github.com/probonopd/ESP8266HueEmulator - */ +#include "alexa.h" +#include "wled.h" +#include "const.h" +#include "led.h" +#include "wled_eeprom.h" +#include "colors.h" #ifndef WLED_DISABLE_ALEXA void onAlexaChange(EspalexaDevice* dev); diff --git a/wled00/alexa.h b/wled00/alexa.h new file mode 100644 index 000000000..c2adfebe3 --- /dev/null +++ b/wled00/alexa.h @@ -0,0 +1,17 @@ +#ifndef WLED_ALEXA_H +#define WLED_ALEXA_H +/* + * Alexa Voice On/Off/Brightness Control. Emulates a Philips Hue bridge to Alexa. + * + * This was put together from these two excellent projects: + * https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch + * https://github.com/probonopd/ESP8266HueEmulator + */ +#include "src/dependencies/espalexa/EspalexaDevice.h" + +void onAlexaChange(EspalexaDevice* dev); +void alexaInit(); +void handleAlexa(); +void onAlexaChange(EspalexaDevice* dev); + +#endif // WLED_ALEXA_H \ No newline at end of file diff --git a/wled00/wled16_blynk.ino b/wled00/blynk.cpp similarity index 92% rename from wled00/wled16_blynk.ino rename to wled00/blynk.cpp index ea4d68771..2307a6942 100644 --- a/wled00/wled16_blynk.ino +++ b/wled00/blynk.cpp @@ -1,6 +1,9 @@ -/* - * Remote light control with the free Blynk app - */ +#include "blynk.h" +#include "const.h" +#include "wled.h" +#include "src/dependencies/blynk/Blynk/BlynkHandlers.h" +#include "led.h" +#include "colors.h" uint16_t blHue = 0; byte blSat = 255; diff --git a/wled00/blynk.h b/wled00/blynk.h new file mode 100644 index 000000000..f17f774a0 --- /dev/null +++ b/wled00/blynk.h @@ -0,0 +1,13 @@ +#ifndef WLED_BLYNK_H +#define WLED_BLYNK_H +#include +/* + * Remote light control with the free Blynk app + */ + +void initBlynk(const char* auth); +void handleBlynk(); +void updateBlynk(); +// TODO: Make sure that the macro expansions are handled correctly. + +#endif //WLED_BLYNK_H \ No newline at end of file diff --git a/wled00/wled09_button.ino b/wled00/button.cpp similarity index 95% rename from wled00/wled09_button.ino rename to wled00/button.cpp index 1cd868bec..a80061eeb 100644 --- a/wled00/wled09_button.ino +++ b/wled00/button.cpp @@ -1,3 +1,9 @@ +#include "button.h" +#include "wled.h" +#include "led.h" +#include "wled_eeprom.h" +#include "set.h" + /* * Physical IO */ @@ -44,7 +50,7 @@ void handleButton() if (dur > 6000) //long press { - initAP(true); + WLED::instance().initAP(true); } else if (!buttonLongPressed) { //short press if (macroDoublePress) diff --git a/wled00/button.h b/wled00/button.h new file mode 100644 index 000000000..f974888e7 --- /dev/null +++ b/wled00/button.h @@ -0,0 +1,12 @@ +#ifndef WLED_BUTTON_H +#define WLED_BUTTON_H +#include +/* + * Physical IO + */ + +void shortPressAction(); +void handleButton(); +void handleIO(); + +#endif // WLED_BUTTON_H \ No newline at end of file diff --git a/wled00/wled14_colors.ino b/wled00/colors.cpp similarity index 96% rename from wled00/wled14_colors.ino rename to wled00/colors.cpp index a1db307ae..6f2477574 100644 --- a/wled00/wled14_colors.ino +++ b/wled00/colors.cpp @@ -1,6 +1,5 @@ -/* - * Color conversion methods - */ +#include "colors.h" +#include "wled.h" void colorFromUint32(uint32_t in, bool secondary) { @@ -18,7 +17,7 @@ void colorFromUint32(uint32_t in, bool secondary) } //load a color without affecting the white channel -void colorFromUint24(uint32_t in, bool secondary = false) +void colorFromUint24(uint32_t in, bool secondary) { if (secondary) { colSec[0] = in >> 16 & 0xFF; @@ -32,7 +31,7 @@ void colorFromUint24(uint32_t in, bool secondary = false) } //relatively change white brightness, minumum A=5 -void relativeChangeWhite(int8_t amount, byte lowerBoundary =0) +void relativeChangeWhite(int8_t amount, byte lowerBoundary) { int16_t new_val = (int16_t) col[3] + amount; if (new_val > 0xFF) new_val = 0xFF; @@ -149,7 +148,8 @@ void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.develo xy[0] = X / (X + Y + Z); xy[1] = Y / (X + Y + Z); } -#endif +#endif // WLED_DISABLE_HUESYNC + void colorFromDecOrHexString(byte* rgb, char* in) { diff --git a/wled00/colors.h b/wled00/colors.h new file mode 100644 index 000000000..85e0adb50 --- /dev/null +++ b/wled00/colors.h @@ -0,0 +1,20 @@ +#ifndef WLED_COLORS_H +#define WLED_COLORS_H +#include +/* + * Color conversion methods + */ + +void colorFromUint32(uint32_t in, bool secondary = false); +void colorFromUint24(uint32_t in, bool secondary = false); +void relativeChangeWhite(int8_t amount, byte lowerBoundary = 0); +void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb +void colorCTtoRGB(uint16_t mired, byte* rgb); //white spectrum to rgb + +void colorXYtoRGB(float x, float y, byte* rgb); // only defined if huesync disabled TODO +void colorRGBtoXY(byte* rgb, float* xy); // only defined if huesync disabled TODO + +void colorFromDecOrHexString(byte* rgb, char* in); +void colorRGBtoRGBW(byte* rgb); //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY) + +#endif //WLED_COLORS_H \ No newline at end of file diff --git a/wled00/wled13_cronixie.ino b/wled00/cronixie.cpp similarity index 97% rename from wled00/wled13_cronixie.ino rename to wled00/cronixie.cpp index dd687ca14..e3b951b86 100644 --- a/wled00/wled13_cronixie.ino +++ b/wled00/cronixie.cpp @@ -1,9 +1,8 @@ -/* - * Support for the Cronixie clock - */ +#include "cronixie.h" +#include "wled.h" + #ifndef WLED_DISABLE_CRONIXIE byte _digitOut[6] = {10,10,10,10,10,10}; -#endif byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) { @@ -23,7 +22,6 @@ byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) void setCronixie() { - #ifndef WLED_DISABLE_CRONIXIE /* * digit purpose index * 0-9 | 0-9 (incl. random) @@ -144,12 +142,10 @@ void setCronixie() DEBUG_PRINTLN((int)dP[5]); _overlayCronixie(); //refresh - #endif } void _overlayCronixie() { - #ifndef WLED_DISABLE_CRONIXIE byte h = hour(local); byte h0 = h; byte m = minute(local); @@ -211,12 +207,10 @@ void _overlayCronixie() } } } - #endif } void _drawOverlayCronixie() { - #ifndef WLED_DISABLE_CRONIXIE byte offsets[] = {5, 0, 6, 1, 7, 2, 8, 3, 9, 4}; for (uint16_t i = 0; i < 6; i++) @@ -239,5 +233,11 @@ void _drawOverlayCronixie() } } } - #endif } + +#else // WLED_DISABLE_CRONIXIE +byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) {} +void setCronixie() {} +void _overlayCronixie() {} +void _drawOverlayCronixie() {} +#endif diff --git a/wled00/cronixie.h b/wled00/cronixie.h new file mode 100644 index 000000000..f6eea6b43 --- /dev/null +++ b/wled00/cronixie.h @@ -0,0 +1,13 @@ +#ifndef WLED_CRONIXIE_H +#define WLED_CRONIXIE_H +#include +/* + * Support for the Cronixie clock + */ + +byte getSameCodeLength(char code, int index, char const cronixieDisplay[]); +void setCronixie(); +void _overlayCronixie(); +void _drawOverlayCronixie(); + +#endif // WLED_CRONIXIE_H \ No newline at end of file diff --git a/wled00/dmx.h b/wled00/dmx.h new file mode 100644 index 000000000..0ab2a4a20 --- /dev/null +++ b/wled00/dmx.h @@ -0,0 +1,65 @@ +#ifndef WLED_DMX_H +#define WLED_DMX_H +#include "wled.h" +/* + * Support for DMX via MAX485. + * Change the output pin in src/dependencies/ESPDMX.cpp if needed. + * Library from: + * https://github.com/Rickgg/ESP-Dmx + */ + +#ifdef WLED_ENABLE_DMX +#include "src/dependencies/dmx/ESPDMX.h" +DMXESPSerial dmx; + +void handleDMX() +{ + // TODO: calculate brightness manually if no shutter channel is set + + uint8_t brightness = strip.getBrightness(); + + for (int i = 0; i < ledCount; i++) { // uses the amount of LEDs as fixture count + + uint32_t in = strip.getPixelColor(i); // time to get the colors for the individual fixtures as suggested by AirCookie at issue #462 + byte w = in >> 24 & 0xFF; + byte r = in >> 16 & 0xFF; + byte g = in >> 8 & 0xFF; + byte b = in & 0xFF; + + int DMXFixtureStart = DMXStart + (DMXGap * i); + for (int j = 0; j < DMXChannels; j++) { + int DMXAddr = DMXFixtureStart + j; + switch (DMXFixtureMap[j]) { + case 0: // Set this channel to 0. Good way to tell strobe- and fade-functions to fuck right off. + dmx.write(DMXAddr, 0); + break; + case 1: // Red + dmx.write(DMXAddr, r); + break; + case 2: // Green + dmx.write(DMXAddr, g); + break; + case 3: // Blue + dmx.write(DMXAddr, b); + break; + case 4: // White + dmx.write(DMXAddr, w); + break; + case 5: // Shutter channel. Controls the brightness. + dmx.write(DMXAddr, brightness); + break; + case 6: // Sets this channel to 255. Like 0, but more wholesome. + dmx.write(DMXAddr, 255); + break; + } + } + } + + dmx.update(); // update the DMX bus +} + +#else +void handleDMX() {} +#endif + +#endif //WLED_DMX_H \ No newline at end of file diff --git a/wled00/wled04_file.ino b/wled00/file.cpp similarity index 92% rename from wled00/wled04_file.ino rename to wled00/file.cpp index de7523281..dba27d4fe 100644 --- a/wled00/wled04_file.ino +++ b/wled00/file.cpp @@ -1,6 +1,17 @@ -/* - * Utility for SPIFFS filesystem & Serial console - */ +#include "file.h" +#include "wled.h" +#include "led.h" +#include "notify.h" + +//filesystem +#ifndef WLED_DISABLE_FILESYSTEM +#include +#ifdef ARDUINO_ARCH_ESP32 +#include "SPIFFS.h" +#endif +#include "SPIFFSEditor.h" +#endif + enum class AdaState { Header_A, Header_d, @@ -13,6 +24,7 @@ enum class AdaState { Data_Blue }; +// Maybe Adalight should not be in filehandling? TODO void handleSerial() { #ifdef WLED_ENABLE_ADALIGHT diff --git a/wled00/file.h b/wled00/file.h new file mode 100644 index 000000000..90731db67 --- /dev/null +++ b/wled00/file.h @@ -0,0 +1,12 @@ +#ifndef WLED_FILE_H +#define WLED_FILE_H +#include +#include +/* + * Utility for SPIFFS filesystem & Serial console + */ + +void handleSerial(); +bool handleFileRead(AsyncWebServerRequest*, String path); + +#endif // WLED_FILE_H \ No newline at end of file diff --git a/wled00/wled15_hue.ino b/wled00/hue.cpp similarity index 97% rename from wled00/wled15_hue.ino rename to wled00/hue.cpp index 5f6b8f5bf..a186a3144 100644 --- a/wled00/wled15_hue.ino +++ b/wled00/hue.cpp @@ -1,7 +1,12 @@ -/* - * Sync to Philips hue lights - */ +#include "hue.h" +#include "wled.h" +#include "colors.h" +#include "wled_eeprom.h" +#include "notify.h" +#include "led.h" + #ifndef WLED_DISABLE_HUESYNC + void handleHue() { if (hueReceived) diff --git a/wled00/hue.h b/wled00/hue.h new file mode 100644 index 000000000..7ce629fbe --- /dev/null +++ b/wled00/hue.h @@ -0,0 +1,16 @@ +#ifndef WLED_HUE_H +#define WLED_HUE_H +/* + * Sync to Philips hue lights + */ +#include +class AsyncClient; + +void handleHue(); +void reconnectHue(); +void onHueError(void* arg, AsyncClient* client, int8_t error); +void onHueConnect(void* arg, AsyncClient* client); +void sendHuePoll(); +void onHueData(void* arg, AsyncClient* client, void *data, size_t len); + +#endif //WLED_HUE_H \ No newline at end of file diff --git a/wled00/wled20_ir.ino b/wled00/ir.cpp similarity index 99% rename from wled00/wled20_ir.ino rename to wled00/ir.cpp index 64c131c21..32b0ee937 100644 --- a/wled00/wled20_ir.ino +++ b/wled00/ir.cpp @@ -1,6 +1,8 @@ -/* - * Infrared sensor support for generic 24/40/44 key RGB remotes - */ +#include "ir.h" +#include "wled.h" +#include "led.h" +#include "colors.h" +#include "wled_eeprom.h" #if defined(WLED_DISABLE_INFRARED) void handleIR(){} @@ -35,7 +37,7 @@ bool decodeIRCustom(uint32_t code) //relatively change brightness, minumum A=5 -void relativeChange(byte* property, int8_t amount, byte lowerBoundary = 0, byte higherBoundary = 0xFF) +void relativeChange(byte* property, int8_t amount, byte lowerBoundary, byte higherBoundary) { int16_t new_val = (int16_t) *property + amount; if (new_val > higherBoundary) new_val = higherBoundary; diff --git a/wled00/ir.h b/wled00/ir.h new file mode 100644 index 000000000..e6ecb9668 --- /dev/null +++ b/wled00/ir.h @@ -0,0 +1,24 @@ +#ifndef WLED_IR_H +#define WLED_IR_H +#include +/* + * Infrared sensor support for generic 24/40/44 key RGB remotes + */ + +bool decodeIRCustom(uint32_t code); +void relativeChange(byte* property, int8_t amount, byte lowerBoundary = 0, byte higherBoundary = 0xFF); +void changeEffectSpeed(int8_t amount); +void changeEffectIntensity(int8_t amount); +void decodeIR(uint32_t code); +void decodeIR24(uint32_t code); +void decodeIR24OLD(uint32_t code); +void decodeIR24CT(uint32_t code); +void decodeIR40(uint32_t code); +void decodeIR44(uint32_t code); +void decodeIR21(uint32_t code); +void decodeIR6(uint32_t code); + +void initIR(); +void handleIR(); + +#endif //WLED_IR_H \ No newline at end of file diff --git a/wled00/wled19_json.ino b/wled00/json.cpp similarity index 96% rename from wled00/wled19_json.ino rename to wled00/json.cpp index c0e23b4b5..e79737c43 100644 --- a/wled00/wled19_json.ino +++ b/wled00/json.cpp @@ -1,6 +1,7 @@ -/* - * JSON API (De)serialization - */ +#include "json.h" +#include "wled.h" +#include "wled_eeprom.h" +#include "led.h" void deserializeSegment(JsonObject elem, byte it) { @@ -248,6 +249,26 @@ void serializeState(JsonObject root) } } +//by https://github.com/tzapu/WiFiManager/blob/master/WiFiManager.cpp +int getSignalQuality(int rssi) +{ + int quality = 0; + + if (rssi <= -100) + { + quality = 0; + } + else if (rssi >= -50) + { + quality = 100; + } + else + { + quality = 2 * (rssi + 100); + } + return quality; +} + void serializeInfo(JsonObject root) { root["ver"] = versionString; diff --git a/wled00/json.h b/wled00/json.h new file mode 100644 index 000000000..77d1b616f --- /dev/null +++ b/wled00/json.h @@ -0,0 +1,21 @@ +#ifndef WLED_JSON_H +#define WLED_JSON_H +/* + * JSON API (De)serialization + */ +#include +#include "ESPAsyncWebServer.h" +#include "src/dependencies/json/ArduinoJson-v6.h" +#include "src/dependencies/json/AsyncJson-v6.h" +#include "fx.h" +// TODO: AsynicWebServerRequest conflict? + +void deserializeSegment(JsonObject elem, byte it); +bool deserializeState(JsonObject root); +void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id); +void serializeState(JsonObject root); +void serializeInfo(JsonObject root); +void serveJson(AsyncWebServerRequest* request); +void serveLiveLeds(AsyncWebServerRequest* request); + +#endif //WLED_JSON_H \ No newline at end of file diff --git a/wled00/wled08_led.ino b/wled00/led.cpp similarity index 97% rename from wled00/wled08_led.ino rename to wled00/led.cpp index 63009f983..7f4d63095 100644 --- a/wled00/wled08_led.ino +++ b/wled00/led.cpp @@ -1,6 +1,11 @@ -/* - * LED methods - */ +#include "led.h" +#include "wled.h" +#include "notify.h" +#include "blynk.h" +#include "wled_eeprom.h" +#include "mqtt.h" +#include "colors.h" + void setValuesFromMainSeg() { WS2812FX::Segment& seg = strip.getSegment(strip.getMainSegmentId()); @@ -50,7 +55,7 @@ void setAllLeds() { } -void setLedsStandard(bool justColors = false) +void setLedsStandard(bool justColors) { for (byte i=0; i<4; i++) { diff --git a/wled00/led.h b/wled00/led.h new file mode 100644 index 000000000..d5eb97a8d --- /dev/null +++ b/wled00/led.h @@ -0,0 +1,19 @@ +#ifndef WLED_LED_H +#define WLED_LED_H +#include +/* + * LED methods + */ + +void setValuesFromMainSeg(); +void resetTimebase(); +void toggleOnOff(); +void setAllLeds(); +void setLedsStandard(bool justColors = false); +bool colorChanged(); +void colorUpdated(int callMode); +void updateInterfaces(uint8_t callMode); +void handleTransitions(); +void handleNightlight(); + +#endif \ No newline at end of file diff --git a/wled00/wled17_mqtt.ino b/wled00/mqtt.cpp similarity index 96% rename from wled00/wled17_mqtt.ino rename to wled00/mqtt.cpp index 741c807f8..b84184af0 100644 --- a/wled00/wled17_mqtt.ino +++ b/wled00/mqtt.cpp @@ -1,6 +1,10 @@ -/* - * MQTT communication protocol for home automation - */ +#include "mqtt.h" +#include "wled.h" +#include "notify.h" +#include "led.h" +#include "colors.h" +#include "xml.h" +#include "set.h" #ifdef WLED_ENABLE_MQTT #define MQTT_KEEP_ALIVE_TIME 60 // contact the MQTT broker every 60 seconds diff --git a/wled00/mqtt.h b/wled00/mqtt.h new file mode 100644 index 000000000..de602b981 --- /dev/null +++ b/wled00/mqtt.h @@ -0,0 +1,9 @@ +#ifndef WLED_MQTT_H +#define WLED_MQTT_H +/* + * MQTT communication protocol for home automation + */ +bool initMqtt(); +void publishMqtt(); + +#endif //WLED_MQTT_H \ No newline at end of file diff --git a/wled00/wled07_notify.ino b/wled00/notify.cpp similarity index 98% rename from wled00/wled07_notify.ino rename to wled00/notify.cpp index 8fcbdbe82..30adfee01 100644 --- a/wled00/wled07_notify.ino +++ b/wled00/notify.cpp @@ -1,12 +1,13 @@ -/* - * UDP notifier - */ +#include "notify.h" +#include "wled.h" +#include "src/dependencies/e131/ESPAsyncE131.h" +#include "led.h" #define WLEDPACKETSIZE 29 #define UDP_IN_MAXSIZE 1472 -void notify(byte callMode, bool followUp=false) +void notify(byte callMode, bool followUp) { if (!udpConnected) return; switch (callMode) @@ -71,7 +72,7 @@ void notify(byte callMode, bool followUp=false) } -void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC) +void arlsLock(uint32_t timeoutMs, byte md) { if (!realtimeMode){ for (uint16_t i = 0; i < ledCount; i++) diff --git a/wled00/notify.h b/wled00/notify.h new file mode 100644 index 000000000..a0fbfde2c --- /dev/null +++ b/wled00/notify.h @@ -0,0 +1,18 @@ +#ifndef WLED_NOTIFY_H +#define WLED_NOTIFY_H +#include +#include "src/dependencies/e131/ESPAsyncE131.h" +#include "const.h" +/* + * UDP notifier + */ +//union e131_packet_t; // Will this compile? +class IPAddress; + +void notify(byte callMode, bool followUp=false); +void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC); +void handleE131Packet(e131_packet_t* p, IPAddress clientIP); +void handleNotifications(); +void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w); + +#endif // WLED_NOTIFY_H \ No newline at end of file diff --git a/wled00/wled10_ntp.ino b/wled00/ntp.cpp similarity index 97% rename from wled00/wled10_ntp.ino rename to wled00/ntp.cpp index 2c5a64c45..206631097 100644 --- a/wled00/wled10_ntp.ino +++ b/wled00/ntp.cpp @@ -1,6 +1,7 @@ -/* - * Acquires time from NTP server - */ +#include "ntp.h" +#include "src/dependencies/timezone/Timezone.h" +#include "wled.h" +#include "wled_eeprom.h" TimeChangeRule UTCr = {Last, Sun, Mar, 1, 0}; // UTC Timezone tzUTC(UTCr, UTCr); @@ -57,6 +58,7 @@ Timezone tzNK(NKST, NKST); TimeChangeRule IST = {Last, Sun, Mar, 1, 330}; // India Standard Time = UTC + 5.5 hours Timezone tzIndia(IST, IST); +// Pick your timezone from here. Timezone* timezones[] = {&tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ, &tzNK, &tzIndia, &tzCASaskatchewan}; void handleNetworkTime() diff --git a/wled00/ntp.h b/wled00/ntp.h new file mode 100644 index 000000000..9029661dd --- /dev/null +++ b/wled00/ntp.h @@ -0,0 +1,18 @@ +#ifndef WLED_NTP_H +#define WLED_NTP_H +#include +/* + * Acquires time from NTP server + */ + +void handleNetworkTime(); +void sendNTPPacket(); +bool checkNTPResponse(); +void updateLocalTime(); +void getTimeString(char* out); +bool checkCountdown(); +void setCountdown(); +byte weekdayMondayFirst(); +void checkTimers(); + +#endif // WLED_NTP_H \ No newline at end of file diff --git a/wled00/wled11_ol.ino b/wled00/overlay.cpp similarity index 98% rename from wled00/wled11_ol.ino rename to wled00/overlay.cpp index 93f7b96df..ccdd3d0cd 100644 --- a/wled00/wled11_ol.ino +++ b/wled00/overlay.cpp @@ -1,6 +1,7 @@ -/* - * Used to draw clock overlays over the strip - */ +#include "overlay.h" +#include "wled.h" +#include "cronixie.h" +#include "ntp.h" void initCronixie() { diff --git a/wled00/overlay.h b/wled00/overlay.h new file mode 100644 index 000000000..f7b54d5db --- /dev/null +++ b/wled00/overlay.h @@ -0,0 +1,14 @@ +#ifndef WLED_OVERLAY_H +#define WLED_OVERLAY_H +#include +/* + * Used to draw clock overlays over the strip + */ + +void initCronixie(); +void handleOverlays(); +void handleOverlayDraw(); +void _overlayAnalogCountdown(); +void _overlayAnalogClock(); + +#endif // WLED_OVERLAY_H \ No newline at end of file diff --git a/wled00/wled03_set.ino b/wled00/set.cpp similarity index 98% rename from wled00/wled03_set.ino rename to wled00/set.cpp index fc82256d2..f26795c8e 100644 --- a/wled00/wled03_set.ino +++ b/wled00/set.cpp @@ -1,8 +1,16 @@ -/* - * Receives client input - */ +#include "set.h" +#include "wled.h" +#include "colors.h" +#include "hue.h" +#include "led.h" +#include "blynk.h" +#include "wled_eeprom.h" +#include "alexa.h" +#include "cronixie.h" +#include "xml.h" +#include "wled_server.h" -void _setRandomColor(bool _sec,bool fromButton=false) +void _setRandomColor(bool _sec,bool fromButton) { lastRandomIndex = strip.get_random_wheel_index(lastRandomIndex); if (_sec){ @@ -330,7 +338,7 @@ int getNumVal(const String* req, uint16_t pos) //helper to get int value at a position in string -bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255) +bool updateVal(const String* req, const char* key, byte* val, byte minv, byte maxv) { int pos = req->indexOf(key); if (pos < 1) return false; diff --git a/wled00/set.h b/wled00/set.h new file mode 100644 index 000000000..6bc7dbd6c --- /dev/null +++ b/wled00/set.h @@ -0,0 +1,16 @@ +#ifndef WLED_SET_H +#define WLED_SET_H +#include +#include +/* + * Receives client input + */ + +void _setRandomColor(bool _sec,bool fromButton=false); +bool isAsterisksOnly(const char* str, byte maxLen); +void handleSettingsSet(AsyncWebServerRequest *request, byte subPage); +bool handleSet(AsyncWebServerRequest *request, const String& req); +int getNumVal(const String* req, uint16_t pos); +bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255); + +#endif // WLED_SET_H \ No newline at end of file diff --git a/wled00/src/dependencies/blynk/BlynkSimpleEsp.cpp b/wled00/src/dependencies/blynk/BlynkSimpleEsp.cpp new file mode 100644 index 000000000..a15d2c1bb --- /dev/null +++ b/wled00/src/dependencies/blynk/BlynkSimpleEsp.cpp @@ -0,0 +1,5 @@ +#include "BlynkSimpleEsp.h" + +WiFiClient _blynkWifiClient; +BlynkArduinoClient _blynkTransport(_blynkWifiClient); +BlynkWifi Blynk(_blynkTransport); \ No newline at end of file diff --git a/wled00/src/dependencies/blynk/BlynkSimpleEsp.h b/wled00/src/dependencies/blynk/BlynkSimpleEsp.h index f6b2a0f1c..6697686fa 100644 --- a/wled00/src/dependencies/blynk/BlynkSimpleEsp.h +++ b/wled00/src/dependencies/blynk/BlynkSimpleEsp.h @@ -89,8 +89,6 @@ public: }; -static WiFiClient _blynkWifiClient; -static BlynkArduinoClient _blynkTransport(_blynkWifiClient); -BlynkWifi Blynk(_blynkTransport); +extern BlynkWifi Blynk; #endif diff --git a/wled00/src/dependencies/dmx/ESPDMX.cpp b/wled00/src/dependencies/dmx/ESPDMX.cpp new file mode 100644 index 000000000..f3ece1c8e --- /dev/null +++ b/wled00/src/dependencies/dmx/ESPDMX.cpp @@ -0,0 +1,106 @@ +// - - - - - +// ESPDMX - A Arduino library for sending and receiving DMX using the builtin serial hardware port. +// ESPDMX.cpp: Library implementation file +// +// Copyright (C) 2015 Rick +// This work is licensed under a GNU style license. +// +// Last change: Marcel Seerig +// +// Documentation and samples are available at https://github.com/Rickgg/ESP-Dmx +// - - - - - + +/* ----- LIBRARIES ----- */ +#include + +#include "ESPDMX.h" + + + +#define dmxMaxChannel 512 +#define defaultMax 32 + +#define DMXSPEED 250000 +#define DMXFORMAT SERIAL_8N2 +#define BREAKSPEED 83333 +#define BREAKFORMAT SERIAL_8N1 + +bool dmxStarted = false; +int sendPin = 2; //dafault on ESP8266 + +//DMX value array and size. Entry 0 will hold startbyte +uint8_t dmxData[dmxMaxChannel] = {}; +int chanSize; + + +void DMXESPSerial::init() { + chanSize = defaultMax; + + Serial1.begin(DMXSPEED); + pinMode(sendPin, OUTPUT); + dmxStarted = true; +} + +// Set up the DMX-Protocol +void DMXESPSerial::init(int chanQuant) { + + if (chanQuant > dmxMaxChannel || chanQuant <= 0) { + chanQuant = defaultMax; + } + + chanSize = chanQuant; + + Serial1.begin(DMXSPEED); + pinMode(sendPin, OUTPUT); + dmxStarted = true; +} + +// Function to read DMX data +uint8_t DMXESPSerial::read(int Channel) { + if (dmxStarted == false) init(); + + if (Channel < 1) Channel = 1; + if (Channel > dmxMaxChannel) Channel = dmxMaxChannel; + return(dmxData[Channel]); +} + +// Function to send DMX data +void DMXESPSerial::write(int Channel, uint8_t value) { + if (dmxStarted == false) init(); + + if (Channel < 1) Channel = 1; + if (Channel > chanSize) Channel = chanSize; + if (value < 0) value = 0; + if (value > 255) value = 255; + + dmxData[Channel] = value; +} + +void DMXESPSerial::end() { + delete dmxData; + chanSize = 0; + Serial1.end(); + dmxStarted == false; +} + +void DMXESPSerial::update() { + if (dmxStarted == false) init(); + + //Send break + digitalWrite(sendPin, HIGH); + Serial1.begin(BREAKSPEED, BREAKFORMAT); + Serial1.write(0); + Serial1.flush(); + delay(1); + Serial1.end(); + + //send data + Serial1.begin(DMXSPEED, DMXFORMAT); + digitalWrite(sendPin, LOW); + Serial1.write(dmxData, chanSize); + Serial1.flush(); + delay(1); + Serial1.end(); +} + +// Function to update the DMX bus diff --git a/wled00/src/dependencies/dmx/ESPDMX.h b/wled00/src/dependencies/dmx/ESPDMX.h new file mode 100644 index 000000000..4585bdd26 --- /dev/null +++ b/wled00/src/dependencies/dmx/ESPDMX.h @@ -0,0 +1,31 @@ +// - - - - - +// ESPDMX - A Arduino library for sending and receiving DMX using the builtin serial hardware port. +// ESPDMX.cpp: Library implementation file +// +// Copyright (C) 2015 Rick +// This work is licensed under a GNU style license. +// +// Last change: Marcel Seerig +// +// Documentation and samples are available at https://github.com/Rickgg/ESP-Dmx +// - - - - - + +#include + + +#ifndef ESPDMX_h +#define ESPDMX_h + +// ---- Methods ---- + +class DMXESPSerial { +public: + void init(); + void init(int MaxChan); + uint8_t read(int Channel); + void write(int channel, uint8_t value); + void update(); + void end(); +}; + +#endif diff --git a/wled00/src/dependencies/espalexa/EspalexaDevice.h b/wled00/src/dependencies/espalexa/EspalexaDevice.h index 0653a4188..4ebdd2b8c 100644 --- a/wled00/src/dependencies/espalexa/EspalexaDevice.h +++ b/wled00/src/dependencies/espalexa/EspalexaDevice.h @@ -1,6 +1,6 @@ #ifndef EspalexaDevice_h #define EspalexaDevice_h - +#include #include "Arduino.h" #include diff --git a/wled00/wled06_usermod.ino b/wled00/usermod.cpp similarity index 91% rename from wled00/wled06_usermod.ino rename to wled00/usermod.cpp index 010d0f386..96c1f8a6c 100644 --- a/wled00/wled06_usermod.ino +++ b/wled00/usermod.cpp @@ -1,7 +1,8 @@ +#include "wled.h" /* * This file allows you to add own functionality to WLED more easily * See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality - * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled01_eeprom.h) + * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled_eeprom.h) * bytes 2400+ are currently ununsed, but might be used for future wled features */ diff --git a/wled00/usermod.h b/wled00/usermod.h new file mode 100644 index 000000000..8269c6e92 --- /dev/null +++ b/wled00/usermod.h @@ -0,0 +1,8 @@ +#ifndef WLED_USERMOD_H +#define WLED_USERMOD_H + +void userSetup(); +void userConnected(); +void userLoop(); + +#endif // WLED_USERMOD_H \ No newline at end of file diff --git a/wled00/wled.cpp b/wled00/wled.cpp new file mode 100644 index 000000000..fdb607765 --- /dev/null +++ b/wled00/wled.cpp @@ -0,0 +1,806 @@ +#include "wled.h" +#include "alexa.h" +#include "blynk.h" +#include "button.h" +#include "dmx.h" +#include "file.h" +#include "hue.h" +#include "ir.h" +#include "led.h" +#include "mqtt.h" +#include "notify.h" +#include "ntp.h" +#include "overlay.h" +#include "usermod.h" +#include "wled_eeprom.h" +#include "wled_server.h" +#include + +// Global Variable definitions +char versionString[] = "0.9.1"; + +// AP and OTA default passwords (for maximum change them!) +char apPass[65] = DEFAULT_AP_PASS; +char otaPass[33] = DEFAULT_OTA_PASS; + +// Hardware CONFIG (only changeble HERE, not at runtime) +// LED strip pin, button pin and IR pin changeable in NpbWrapper.h! + +byte auxDefaultState = 0; // 0: input 1: high 2: low +byte auxTriggeredState = 0; // 0: input 1: high 2: low +char ntpServerName[33] = "0.wled.pool.ntp.org"; // NTP server to use + +// WiFi CONFIG (all these can be changed via web UI, no need to set them here) +char clientSSID[33] = CLIENT_SSID; +char clientPass[65] = CLIENT_PASS; +char cmDNS[33] = "x"; // mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) +char apSSID[33] = ""; // AP off by default (unless setup) +byte apChannel = 1; // 2.4GHz WiFi AP channel (1-13) +byte apHide = 0; // hidden AP SSID +byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; // access point opens when no connection after boot by default +IPAddress staticIP(0, 0, 0, 0); // static IP of ESP +IPAddress staticGateway(0, 0, 0, 0); // gateway (router) IP +IPAddress staticSubnet(255, 255, 255, 0); // most common subnet in home networks +bool noWifiSleep = false; // disabling modem sleep modes will increase heat output and power usage, but may help with connection issues + +// LED CONFIG +uint16_t ledCount = 30; // overcurrent prevented by ABL +bool useRGBW = false; // SK6812 strips can contain an extra White channel +bool turnOnAtBoot = true; // turn on LEDs at power-up +byte bootPreset = 0; // save preset to load after power-up + +byte col[] { 255, 160, 0, 0 }; // current RGB(W) primary color. col[] should be updated if you want to change the color. +byte colSec[] { 0, 0, 0, 0 }; // current RGB(W) secondary color +byte briS = 128; // default brightness + +byte nightlightTargetBri = 0; // brightness after nightlight is over +byte nightlightDelayMins = 60; +bool nightlightFade = true; // if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over +bool nightlightColorFade = false; // if enabled, light will gradually fade color from primary to secondary color. +bool fadeTransition = true; // enable crossfading color transition +uint16_t transitionDelay = 750; // default crossfade duration in ms + +bool skipFirstLed = false; // ignore first LED in strip (useful if you need the LED as signal repeater) +byte briMultiplier = 100; // % of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) + +// User Interface CONFIG +char serverDescription[33] = "WLED"; // Name of module +bool syncToggleReceive = false; // UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise + +// Sync CONFIG +bool buttonEnabled = true; +byte irEnabled = 0; // Infrared receiver + +uint16_t udpPort = 21324; // WLED notifier default port +uint16_t udpRgbPort = 19446; // Hyperion port + +bool receiveNotificationBrightness = true; // apply brightness from incoming notifications +bool receiveNotificationColor = true; // apply color +bool receiveNotificationEffects = true; // apply effects setup +bool notifyDirect = false; // send notification if change via UI or HTTP API +bool notifyButton = false; // send if updated by button or infrared remote +bool notifyAlexa = false; // send notification if updated via Alexa +bool notifyMacro = false; // send notification for macro +bool notifyHue = true; // send notification if Hue light changes +bool notifyTwice = false; // notifications use UDP: enable if devices don't sync reliably + +bool alexaEnabled = true; // enable device discovery by Amazon Echo +char alexaInvocationName[33] = "Light"; // speech control name of device. Choose something voice-to-text can understand + +char blynkApiKey[36] = ""; // Auth token for Blynk server. If empty, no connection will be made + +uint16_t realtimeTimeoutMs = 2500; // ms timeout of realtime mode before returning to normal mode +int arlsOffset = 0; // realtime LED offset +bool receiveDirect = true; // receive UDP realtime +bool arlsDisableGammaCorrection = true; // activate if gamma correction is handled by the source +bool arlsForceMaxBri = false; // enable to force max brightness if source has very dark colors that would be black + +uint16_t e131Universe = 1; // settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) +uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; // DMX mode (s.a.) +uint16_t DMXAddress = 1; // DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] +uint8_t DMXOldDimmer = 0; // only update brightness on change +uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; // to detect packet loss +bool e131Multicast = false; // multicast or unicast +bool e131SkipOutOfSequence = false; // freeze instead of flickering + +bool mqttEnabled = false; +char mqttDeviceTopic[33] = ""; // main MQTT topic (individual per device, default is wled/mac) +char mqttGroupTopic[33] = "wled/all"; // second MQTT topic (for example to group devices) +char mqttServer[33] = ""; // both domains and IPs should work (no SSL) +char mqttUser[41] = ""; // optional: username for MQTT auth +char mqttPass[41] = ""; // optional: password for MQTT auth +char mqttClientID[41] = ""; // override the client ID +uint16_t mqttPort = 1883; + +bool huePollingEnabled = false; // poll hue bridge for light state +uint16_t huePollIntervalMs = 2500; // low values (< 1sec) may cause lag but offer quicker response +char hueApiKey[47] = "api"; // key token will be obtained from bridge +byte huePollLightId = 1; // ID of hue lamp to sync to. Find the ID in the hue app ("about" section) +IPAddress hueIP = (0, 0, 0, 0); // IP address of the bridge +bool hueApplyOnOff = true; +bool hueApplyBri = true; +bool hueApplyColor = true; + +// Time CONFIG +bool ntpEnabled = false; // get internet time. Only required if you use clock overlays or time-activated macros +bool useAMPM = false; // 12h/24h clock format +byte currentTimezone = 0; // Timezone ID. Refer to timezones array in wled10_ntp.ino +int utcOffsetSecs = 0; // Seconds to offset from UTC before timzone calculation + +byte overlayDefault = 0; // 0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie +byte overlayMin = 0, overlayMax = ledCount - 1; // boundaries of overlay mode + +byte analogClock12pixel = 0; // The pixel in your strip where "midnight" would be +bool analogClockSecondsTrail = false; // Display seconds as trail of LEDs instead of a single pixel +bool analogClock5MinuteMarks = false; // Light pixels at every 5-minute position + +char cronixieDisplay[7] = "HHMMSS"; // Cronixie Display mask. See wled13_cronixie.ino +bool cronixieBacklight = true; // Allow digits to be back-illuminated + +bool countdownMode = false; // Clock will count down towards date +byte countdownYear = 20, countdownMonth = 1; // Countdown target date, year is last two digits +byte countdownDay = 1, countdownHour = 0; +byte countdownMin = 0, countdownSec = 0; + +byte macroBoot = 0; // macro loaded after startup +byte macroNl = 0; // after nightlight delay over +byte macroCountdown = 0; +byte macroAlexaOn = 0, macroAlexaOff = 0; +byte macroButton = 0, macroLongPress = 0, macroDoublePress = 0; + +// Security CONFIG +bool otaLock = false; // prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks +bool wifiLock = false; // prevents access to WiFi settings when OTA lock is enabled +bool aOtaEnabled = true; // ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on + +uint16_t userVar0 = 0, userVar1 = 0; + +#ifdef WLED_ENABLE_DMX + // dmx CONFIG + byte DMXChannels = 7; // number of channels per fixture + byte DMXFixtureMap[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + // assigns the different channels to different functions. See wled21_dmx.ino for more information. + uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. + uint16_t DMXStart = 10; // start address of the first fixture +#endif + +// internal global variable declarations +// wifi +bool apActive = false; +bool forceReconnect = false; +uint32_t lastReconnectAttempt = 0; +bool interfacesInited = false; +bool wasConnected = false; + +// color +byte colOld[] { 0, 0, 0, 0 }; // color before transition +byte colT[] { 0, 0, 0, 0 }; // color that is currently displayed on the LEDs +byte colIT[] { 0, 0, 0, 0 }; // color that was last sent to LEDs +byte colSecT[] { 0, 0, 0, 0 }; +byte colSecOld[] { 0, 0, 0, 0 }; +byte colSecIT[] { 0, 0, 0, 0 }; + +byte lastRandomIndex = 0; // used to save last random color so the new one is not the same + +// transitions +bool transitionActive = false; +uint16_t transitionDelayDefault = transitionDelay; +uint16_t transitionDelayTemp = transitionDelay; +unsigned long transitionStartTime; +float tperLast = 0; // crossfade transition progress, 0.0f - 1.0f +bool jsonTransitionOnce = false; + +// nightlight +bool nightlightActive = false; +bool nightlightActiveOld = false; +uint32_t nightlightDelayMs = 10; +uint8_t nightlightDelayMinsDefault = nightlightDelayMins; +unsigned long nightlightStartTime; +byte briNlT = 0; // current nightlight brightness +byte colNlT[] { 0, 0, 0, 0 }; // current nightlight color + +// brightness +unsigned long lastOnTime = 0; +bool offMode = !turnOnAtBoot; +byte bri = briS; +byte briOld = 0; +byte briT = 0; +byte briIT = 0; +byte briLast = 128; // brightness before turned off. Used for toggle function +byte whiteLast = 128; // white channel before turned off. Used for toggle function + +// button +bool buttonPressedBefore = false; +bool buttonLongPressed = false; +unsigned long buttonPressedTime = 0; +unsigned long buttonWaitTime = 0; + +// notifications +bool notifyDirectDefault = notifyDirect; +bool receiveNotifications = true; +unsigned long notificationSentTime = 0; +byte notificationSentCallMode = NOTIFIER_CALL_MODE_INIT; +bool notificationTwoRequired = false; + +// effects +byte effectCurrent = 0; +byte effectSpeed = 128; +byte effectIntensity = 128; +byte effectPalette = 0; + +// network +bool udpConnected = false, udpRgbConnected = false; + +// ui style +bool showWelcomePage = false; + +// hue +byte hueError = HUE_ERROR_INACTIVE; +// uint16_t hueFailCount = 0; +float hueXLast = 0, hueYLast = 0; +uint16_t hueHueLast = 0, hueCtLast = 0; +byte hueSatLast = 0, hueBriLast = 0; +unsigned long hueLastRequestSent = 0; +bool hueAuthRequired = false; +bool hueReceived = false; +bool hueStoreAllowed = false, hueNewKey = false; + +// overlays +byte overlayCurrent = overlayDefault; +byte overlaySpeed = 200; +unsigned long overlayRefreshMs = 200; +unsigned long overlayRefreshedTime; + +// cronixie +byte dP[] { 0, 0, 0, 0, 0, 0 }; +bool cronixieInit = false; + +// countdown +unsigned long countdownTime = 1514764800L; +bool countdownOverTriggered = true; + +// timer +byte lastTimerMinute = 0; +byte timerHours[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +byte timerMinutes[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +byte timerMacro[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +byte timerWeekday[] = { 255, 255, 255, 255, 255, 255, 255, 255 }; // weekdays to activate on +// bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity + +// blynk +bool blynkEnabled = false; + +// preset cycling +bool presetCyclingEnabled = false; +byte presetCycleMin = 1, presetCycleMax = 5; +uint16_t presetCycleTime = 1250; +unsigned long presetCycledTime = 0; +byte presetCycCurr = presetCycleMin; +bool presetApplyBri = true; +bool saveCurrPresetCycConf = false; + +// realtime +byte realtimeMode = REALTIME_MODE_INACTIVE; +IPAddress realtimeIP = (0, 0, 0, 0); +unsigned long realtimeTimeout = 0; + +// mqtt +long lastMqttReconnectAttempt = 0; +long lastInterfaceUpdate = 0; +byte interfaceUpdateCallMode = NOTIFIER_CALL_MODE_INIT; +char mqttStatusTopic[40] = ""; // this must be global because of async handlers + +#if AUXPIN >= 0 + // auxiliary debug pin + byte auxTime = 0; + unsigned long auxStartTime = 0; + bool auxActive = false, auxActiveBefore = false; +#endif + +// alexa udp +String escapedMac; +#ifndef WLED_DISABLE_ALEXA + Espalexa espalexa; + EspalexaDevice* espalexaDevice; +#endif + +// dns server +DNSServer dnsServer; + +// network time +bool ntpConnected = false; +time_t local = 0; +unsigned long ntpLastSyncTime = 999000000L; +unsigned long ntpPacketSentTime = 999000000L; +IPAddress ntpServerIP; +uint16_t ntpLocalPort = 2390; + +// Temp buffer +char* obuf; +uint16_t olen = 0; + +// presets +uint16_t savedPresets = 0; +int8_t currentPreset = -1; +bool isPreset = false; + +byte errorFlag = 0; + +String messageHead, messageSub; +byte optionType; + +bool doReboot = false; // flag to initiate reboot from async handlers +bool doPublishMqtt = false; + +// server library objects +AsyncWebServer server(80); +AsyncClient* hueClient = NULL; +AsyncMqttClient* mqtt = NULL; + +// udp interface objects +WiFiUDP notifierUdp, rgbUdp; +WiFiUDP ntpUdp; +ESPAsyncE131 e131(handleE131Packet); +bool e131NewData = false; + +// led fx library object +WS2812FX strip = WS2812FX(); + +// debug macro variable definitions +#ifdef WLED_DEBUG + unsigned long debugTime = 0; + int lastWifiState = 3; + unsigned long wifiStateChangedTime = 0; + int loops = 0; +#endif + +WLED::WLED() +{ +} + +// turns all LEDs off and restarts ESP +void WLED::reset() +{ + briT = 0; + long dly = millis(); + while (millis() - dly < 250) { + yield(); // enough time to send response to client + } + setAllLeds(); + DEBUG_PRINTLN("MODULE RESET"); + ESP.restart(); +} + +bool oappendi(int i) +{ + char s[11]; + sprintf(s, "%ld", i); + return oappend(s); +} + +bool oappend(const char* txt) +{ + uint16_t len = strlen(txt); + if (olen + len >= OMAX) + return false; // buffer full + strcpy(obuf + olen, txt); + olen += len; + return true; +} + +void WLED::loop() +{ + handleIR(); // 2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too + handleConnection(); + handleSerial(); + handleNotifications(); + handleTransitions(); +#ifdef WLED_ENABLE_DMX + handleDMX(); +#endif + userLoop(); + + yield(); + handleIO(); + handleIR(); + handleNetworkTime(); + handleAlexa(); + + handleOverlays(); + yield(); +#ifdef WLED_USE_ANALOG_LEDS + strip.setRgbwPwm(); +#endif + + if (doReboot) + reset(); + + if (!realtimeMode) // block stuff if WARLS/Adalight is enabled + { + if (apActive) + dnsServer.processNextRequest(); +#ifndef WLED_DISABLE_OTA + if (WLED_CONNECTED && aOtaEnabled) + ArduinoOTA.handle(); +#endif + handleNightlight(); + yield(); + + handleHue(); + handleBlynk(); + + yield(); + if (!offMode) + strip.service(); + } + yield(); +#ifdef ESP8266 + MDNS.update(); +#endif + if (millis() - lastMqttReconnectAttempt > 30000) + initMqtt(); + +// DEBUG serial logging +#ifdef WLED_DEBUG + if (millis() - debugTime > 9999) { + DEBUG_PRINTLN("---DEBUG INFO---"); + DEBUG_PRINT("Runtime: "); + DEBUG_PRINTLN(millis()); + DEBUG_PRINT("Unix time: "); + DEBUG_PRINTLN(now()); + DEBUG_PRINT("Free heap: "); + DEBUG_PRINTLN(ESP.getFreeHeap()); + DEBUG_PRINT("Wifi state: "); + DEBUG_PRINTLN(WiFi.status()); + if (WiFi.status() != lastWifiState) { + wifiStateChangedTime = millis(); + } + lastWifiState = WiFi.status(); + DEBUG_PRINT("State time: "); + DEBUG_PRINTLN(wifiStateChangedTime); + DEBUG_PRINT("NTP last sync: "); + DEBUG_PRINTLN(ntpLastSyncTime); + DEBUG_PRINT("Client IP: "); + DEBUG_PRINTLN(WiFi.localIP()); + DEBUG_PRINT("Loops/sec: "); + DEBUG_PRINTLN(loops / 10); + loops = 0; + debugTime = millis(); + } + loops++; +#endif // WLED_DEBU +} + +void WLED::setup() +{ + EEPROM.begin(EEPSIZE); + ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); + if (ledCount > MAX_LEDS || ledCount == 0) + ledCount = 30; + +#ifdef ESP8266 + #if LEDPIN == 3 + if (ledCount > MAX_LEDS_DMA) + ledCount = MAX_LEDS_DMA; // DMA method uses too much ram + #endif +#endif + Serial.begin(115200); + Serial.setTimeout(50); + DEBUG_PRINTLN(); + DEBUG_PRINT("---WLED "); + DEBUG_PRINT(versionString); + DEBUG_PRINT(" "); + DEBUG_PRINT(VERSION); + DEBUG_PRINTLN(" INIT---"); +#ifdef ARDUINO_ARCH_ESP32 + DEBUG_PRINT("esp32 "); + DEBUG_PRINTLN(ESP.getSdkVersion()); +#else + DEBUG_PRINT("esp8266 "); + DEBUG_PRINTLN(ESP.getCoreVersion()); +#endif + int heapPreAlloc = ESP.getFreeHeap(); + DEBUG_PRINT("heap "); + DEBUG_PRINTLN(ESP.getFreeHeap()); + + strip.init(EEPROM.read(372), ledCount, EEPROM.read(2204)); // init LEDs quickly + strip.setBrightness(0); + + DEBUG_PRINT("LEDs inited. heap usage ~"); + DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap()); + +#ifndef WLED_DISABLE_FILESYSTEM + #ifdef ARDUINO_ARCH_ESP32 + SPIFFS.begin(true); + #endif + SPIFFS.begin(); +#endif + + DEBUG_PRINTLN("Load EEPROM"); + loadSettingsFromEEPROM(true); + beginStrip(); + userSetup(); + if (strcmp(clientSSID, DEFAULT_CLIENT_SSID) == 0) + showWelcomePage = true; + WiFi.persistent(false); + + if (macroBoot > 0) + applyMacro(macroBoot); + Serial.println("Ada"); + + // generate module IDs + escapedMac = WiFi.macAddress(); + escapedMac.replace(":", ""); + escapedMac.toLowerCase(); + if (strcmp(cmDNS, "x") == 0) // fill in unique mdns default + { + strcpy(cmDNS, "wled-"); + sprintf(cmDNS + 5, "%*s", 6, escapedMac.c_str() + 6); + } + if (mqttDeviceTopic[0] == 0) { + strcpy(mqttDeviceTopic, "wled/"); + sprintf(mqttDeviceTopic + 5, "%*s", 6, escapedMac.c_str() + 6); + } + if (mqttClientID[0] == 0) { + strcpy(mqttClientID, "WLED-"); + sprintf(mqttClientID + 5, "%*s", 6, escapedMac.c_str() + 6); + } + + strip.service(); + +#ifndef WLED_DISABLE_OTA + if (aOtaEnabled) { + ArduinoOTA.onStart([]() { +#ifdef ESP8266 + wifi_set_sleep_type(NONE_SLEEP_T); +#endif + DEBUG_PRINTLN("Start ArduinoOTA"); + }); + if (strlen(cmDNS) > 0) + ArduinoOTA.setHostname(cmDNS); + } +#endif +#ifdef WLED_ENABLE_DMX + dmx.init(512); // initialize with bus length +#endif + // HTTP server page init + initServer(); +} + +void WLED::beginStrip() +{ + // Initialize NeoPixel Strip and button + strip.setShowCallback(handleOverlayDraw); + +#ifdef BTNPIN + pinMode(BTNPIN, INPUT_PULLUP); +#endif + + if (bootPreset > 0) + applyPreset(bootPreset, turnOnAtBoot); + colorUpdated(NOTIFIER_CALL_MODE_INIT); + +// init relay pin +#if RLYPIN >= 0 + pinMode(RLYPIN, OUTPUT); +#if RLYMDE + digitalWrite(RLYPIN, bri); +#else + digitalWrite(RLYPIN, !bri); +#endif +#endif + + // disable button if it is "pressed" unintentionally +#ifdef BTNPIN + if (digitalRead(BTNPIN) == LOW) + buttonEnabled = false; +#else + buttonEnabled = false; +#endif +} + +void WLED::initAP(bool resetAP) +{ + if (apBehavior == AP_BEHAVIOR_BUTTON_ONLY && !resetAP) + return; + + if (!apSSID[0] || resetAP) + strcpy(apSSID, "WLED-AP"); + if (resetAP) + strcpy(apPass, DEFAULT_AP_PASS); + DEBUG_PRINT("Opening access point "); + DEBUG_PRINTLN(apSSID); + WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255, 255, 255, 0)); + WiFi.softAP(apSSID, apPass, apChannel, apHide); + + if (!apActive) // start captive portal if AP active + { + DEBUG_PRINTLN("Init AP interfaces"); + server.begin(); + if (udpPort > 0 && udpPort != ntpLocalPort) { + udpConnected = notifierUdp.begin(udpPort); + } + if (udpRgbPort > 0 && udpRgbPort != ntpLocalPort && udpRgbPort != udpPort) { + udpRgbConnected = rgbUdp.begin(udpRgbPort); + } + + dnsServer.setErrorReplyCode(DNSReplyCode::NoError); + dnsServer.start(53, "*", WiFi.softAPIP()); + } + apActive = true; +} + +void WLED::initConnection() +{ + WiFi.disconnect(); // close old connections +#ifdef ESP8266 + WiFi.setPhyMode(WIFI_PHY_MODE_11N); +#endif + + if (staticIP[0] != 0 && staticGateway[0] != 0) { + WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(8, 8, 8, 8)); + } else { + WiFi.config(0U, 0U, 0U); + } + + lastReconnectAttempt = millis(); + + if (!WLED_WIFI_CONFIGURED) { + DEBUG_PRINT("No connection configured. "); + if (!apActive) + initAP(); // instantly go to ap mode + return; + } else if (!apActive) { + if (apBehavior == AP_BEHAVIOR_ALWAYS) { + initAP(); + } else { + DEBUG_PRINTLN("Access point disabled."); + WiFi.softAPdisconnect(true); + } + } + showWelcomePage = false; + + DEBUG_PRINT("Connecting to "); + DEBUG_PRINT(clientSSID); + DEBUG_PRINTLN("..."); + +#ifdef ESP8266 + WiFi.hostname(serverDescription); +#endif + + WiFi.begin(clientSSID, clientPass); + +#ifdef ARDUINO_ARCH_ESP32 + WiFi.setSleep(!noWifiSleep); + WiFi.setHostname(serverDescription); +#else + wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); +#endif +} + +void WLED::initInterfaces() +{ + DEBUG_PRINTLN("Init STA interfaces"); + + if (hueIP[0] == 0) { + hueIP[0] = WiFi.localIP()[0]; + hueIP[1] = WiFi.localIP()[1]; + hueIP[2] = WiFi.localIP()[2]; + } + + // init Alexa hue emulation + if (alexaEnabled) + alexaInit(); + +#ifndef WLED_DISABLE_OTA + if (aOtaEnabled) + ArduinoOTA.begin(); +#endif + + strip.service(); + // Set up mDNS responder: + if (strlen(cmDNS) > 0) { + if (!aOtaEnabled) + MDNS.begin(cmDNS); + + DEBUG_PRINTLN("mDNS started"); + MDNS.addService("http", "tcp", 80); + MDNS.addService("wled", "tcp", 80); + MDNS.addServiceTxt("wled", "tcp", "mac", escapedMac.c_str()); + } + server.begin(); + + if (udpPort > 0 && udpPort != ntpLocalPort) { + udpConnected = notifierUdp.begin(udpPort); + if (udpConnected && udpRgbPort != udpPort) + udpRgbConnected = rgbUdp.begin(udpRgbPort); + } + if (ntpEnabled) + ntpConnected = ntpUdp.begin(ntpLocalPort); + + initBlynk(blynkApiKey); + e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST, e131Universe, E131_MAX_UNIVERSE_COUNT); + reconnectHue(); + initMqtt(); + interfacesInited = true; + wasConnected = true; +} + +byte stacO = 0; +uint32_t lastHeap; +unsigned long heapTime = 0; + +void WLED::handleConnection() +{ + if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS)) + return; + if (lastReconnectAttempt == 0) + initConnection(); + + // reconnect WiFi to clear stale allocations if heap gets too low + if (millis() - heapTime > 5000) { + uint32_t heap = ESP.getFreeHeap(); + if (heap < 9000 && lastHeap < 9000) { + DEBUG_PRINT("Heap too low! "); + DEBUG_PRINTLN(heap); + forceReconnect = true; + } + lastHeap = heap; + heapTime = millis(); + } + + byte stac = 0; + if (apActive) { +#ifdef ESP8266 + stac = wifi_softap_get_station_num(); +#else + wifi_sta_list_t stationList; + esp_wifi_ap_get_sta_list(&stationList); + stac = stationList.num; +#endif + if (stac != stacO) { + stacO = stac; + DEBUG_PRINT("Connected AP clients: "); + DEBUG_PRINTLN(stac); + if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) { // trying to connect, but not connected + if (stac) + WiFi.disconnect(); // disable search so that AP can work + else + initConnection(); // restart search + } + } + } + if (forceReconnect) { + DEBUG_PRINTLN("Forcing reconnect."); + initConnection(); + interfacesInited = false; + forceReconnect = false; + wasConnected = false; + return; + } + if (!WLED_CONNECTED) { + if (interfacesInited) { + DEBUG_PRINTLN("Disconnected!"); + interfacesInited = false; + initConnection(); + } + if (millis() - lastReconnectAttempt > ((stac) ? 300000 : 20000) && WLED_WIFI_CONFIGURED) + initConnection(); + if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) + initAP(); + } else if (!interfacesInited) { // newly connected + DEBUG_PRINTLN(""); + DEBUG_PRINT("Connected! IP address: "); + DEBUG_PRINTLN(WiFi.localIP()); + initInterfaces(); + userConnected(); + + // shut down AP + if (apBehavior != AP_BEHAVIOR_ALWAYS && apActive) { + dnsServer.stop(); + WiFi.softAPdisconnect(true); + apActive = false; + DEBUG_PRINTLN("Access point disabled."); + } + } +} diff --git a/wled00/wled.h b/wled00/wled.h new file mode 100644 index 000000000..70b197c8e --- /dev/null +++ b/wled00/wled.h @@ -0,0 +1,409 @@ +#ifndef WLED_H +#define WLED_H +/* + Main sketch, global variable declarations + @title WLED project sketch + @version 0.9.1 + @author Christian Schwinne + */ + +// ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). + +// ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS). +// Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB): +// Alternatively, with platformio pass your chosen flags to your custom build target in platformio.ini.override + +// You are required to disable over-the-air updates: +//#define WLED_DISABLE_OTA // saves 14kb + +// You need to choose some of these features to disable: +//#define WLED_DISABLE_ALEXA // saves 11kb +//#define WLED_DISABLE_BLYNK // saves 6kb +//#define WLED_DISABLE_CRONIXIE // saves 3kb +//#define WLED_DISABLE_HUESYNC // saves 4kb +//#define WLED_DISABLE_INFRARED // there is no pin left for this on ESP8266-01, saves 12kb +#define WLED_ENABLE_MQTT // saves 12kb +#define WLED_ENABLE_ADALIGHT // saves 500b only +//#define WLED_ENABLE_DMX // uses 3.5kb + +#define WLED_DISABLE_FILESYSTEM // SPIFFS is not used by any WLED feature yet +//#define WLED_ENABLE_FS_SERVING // Enable sending html file from SPIFFS before serving progmem version +//#define WLED_ENABLE_FS_EDITOR // enable /edit page for editing SPIFFS content. Will also be disabled with OTA lock + +// to toggle usb serial debug (un)comment the following line +//#define WLED_DEBUG + +// Library inclusions. +#include +#ifdef ESP8266 + #include + #include + #include + extern "C" + { + #include + } +#else // ESP32 + #include + #include "esp_wifi.h" + #include + #include + #include "SPIFFS.h" +#endif + +#include +#include +#include +#include +#ifndef WLED_DISABLE_OTA + #include +#endif +#include +#include "src/dependencies/time/TimeLib.h" +#include "src/dependencies/timezone/Timezone.h" + +#ifndef WLED_DISABLE_ALEXA + #define ESPALEXA_ASYNC + #define ESPALEXA_NO_SUBPAGE + #define ESPALEXA_MAXDEVICES 1 + // #define ESPALEXA_DEBUG + #include "src/dependencies/espalexa/Espalexa.h" +#endif +#ifndef WLED_DISABLE_BLYNK + #include "src/dependencies/blynk/BlynkSimpleEsp.h" +#endif + +#include "src/dependencies/e131/ESPAsyncE131.h" +#include "src/dependencies/async-mqtt-client/AsyncMqttClient.h" +#include "src/dependencies/json/AsyncJson-v6.h" +#include "src/dependencies/json/ArduinoJson-v6.h" + +#include "html_ui.h" +#include "html_settings.h" +#include "html_other.h" +#include "FX.h" +#include "ir_codes.h" +#include "const.h" + +#ifndef CLIENT_SSID + #define CLIENT_SSID DEFAULT_CLIENT_SSID +#endif + +#ifndef CLIENT_PASS + #define CLIENT_PASS "" +#endif + +#if IR_PIN < 0 + #ifndef WLED_DISABLE_INFRARED + #define WLED_DISABLE_INFRARED + #endif +#endif + +#ifndef WLED_DISABLE_INFRARED + #include + #include + #include +#endif + +// remove flicker because PWM signal of RGB channels can become out of phase +#if defined(WLED_USE_ANALOG_LEDS) && defined(ESP8266) + #include "src/dependencies/arduino/core_esp8266_waveform.h" +#endif + +// enable additional debug output +#ifdef WLED_DEBUG + #ifndef ESP8266 + #include + #endif +#endif + +// version code in format yymmddb (b = daily build) +#define VERSION 2003301 + +// Global external variable declaration. See wled.cpp for definitions and comments. +extern char versionString[]; +extern char apPass[65]; +extern char otaPass[33]; +extern byte auxDefaultState; +extern byte auxTriggeredState; +extern char ntpServerName[33]; +extern char clientSSID[33]; +extern char clientPass[65]; +extern char cmDNS[33]; +extern char apSSID[33]; +extern byte apChannel; +extern byte apHide; +extern byte apBehavior; +extern IPAddress staticIP; +extern IPAddress staticGateway; +extern IPAddress staticSubnet; +extern bool noWifiSleep; +extern uint16_t ledCount; +extern bool useRGBW; +#define ABL_MILLIAMPS_DEFAULT 850; // auto lower brightness to stay close to milliampere limit +extern bool turnOnAtBoot; +extern byte bootPreset; +extern byte col[]; +extern byte colSec[]; +extern byte briS; +extern byte nightlightTargetBri; +extern byte nightlightDelayMins; +extern bool nightlightFade; +extern bool nightlightColorFade; +extern bool fadeTransition; +extern uint16_t transitionDelay; +extern bool skipFirstLed; +extern byte briMultiplier; +extern char serverDescription[33]; +extern bool syncToggleReceive; +extern bool buttonEnabled; +extern byte irEnabled; +extern uint16_t udpPort; +extern uint16_t udpRgbPort; +extern bool receiveNotificationBrightness; +extern bool receiveNotificationColor; +extern bool receiveNotificationEffects; +extern bool notifyDirect; +extern bool notifyButton; +extern bool notifyAlexa; +extern bool notifyMacro; +extern bool notifyHue; +extern bool notifyTwice; +extern bool alexaEnabled; +extern char alexaInvocationName[33]; +extern char blynkApiKey[36]; +extern uint16_t realtimeTimeoutMs; +extern int arlsOffset; +extern bool receiveDirect; +extern bool arlsDisableGammaCorrection; +extern bool arlsForceMaxBri; +#define E131_MAX_UNIVERSE_COUNT 9 +extern uint16_t e131Universe; +extern uint8_t DMXMode; +extern uint16_t DMXAddress; +extern uint8_t DMXOldDimmer; +extern uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; +extern bool e131Multicast; +extern bool e131SkipOutOfSequence; +extern bool mqttEnabled; +extern char mqttDeviceTopic[33]; +extern char mqttGroupTopic[33]; +extern char mqttServer[33]; +extern char mqttUser[41]; +extern char mqttPass[41]; +extern char mqttClientID[41]; +extern uint16_t mqttPort; +extern bool huePollingEnabled; +extern uint16_t huePollIntervalMs; +extern char hueApiKey[47]; +extern byte huePollLightId; +extern IPAddress hueIP; +extern bool hueApplyOnOff; +extern bool hueApplyBri; +extern bool hueApplyColor; +extern bool ntpEnabled; +extern bool useAMPM; +extern byte currentTimezone; +extern int utcOffsetSecs; +extern byte overlayDefault; +extern byte overlayMin; +extern byte overlayMax; +extern byte analogClock12pixel; +extern bool analogClockSecondsTrail; +extern bool analogClock5MinuteMarks; +extern char cronixieDisplay[7]; +extern bool cronixieBacklight; +extern bool countdownMode; +extern byte countdownYear, countdownMonth; +extern byte countdownDay, countdownHour; +extern byte countdownMin, countdownSec; +extern byte macroBoot; +extern byte macroNl; +extern byte macroCountdown; +extern byte macroAlexaOn, macroAlexaOff; +extern byte macroButton, macroLongPress, macroDoublePress; +extern bool otaLock; +extern bool wifiLock; +extern bool aOtaEnabled; +extern uint16_t userVar0, userVar1; +#ifdef WLED_ENABLE_DMX + extern byte DMXChannels; + extern byte DMXFixtureMap[15]; + extern uint16_t DMXGap; + extern uint16_t DMXStart; +#endif +extern bool apActive; +extern bool forceReconnect; +extern uint32_t lastReconnectAttempt; +extern bool interfacesInited; +extern bool wasConnected; +extern byte colOld[]; +extern byte colT[]; +extern byte colIT[]; +extern byte colSecT[]; +extern byte colSecOld[]; +extern byte colSecIT[]; +extern byte lastRandomIndex; +extern bool transitionActive; +extern uint16_t transitionDelayDefault; +extern uint16_t transitionDelayTemp; +extern unsigned long transitionStartTime; +extern float tperLast; +extern bool jsonTransitionOnce; +extern bool nightlightActive; +extern bool nightlightActiveOld; +extern uint32_t nightlightDelayMs; +extern uint8_t nightlightDelayMinsDefault; +extern unsigned long nightlightStartTime; +extern byte briNlT; +extern byte colNlT[]; +extern unsigned long lastOnTime; +extern bool offMode; +extern byte bri; +extern byte briOld; +extern byte briT; +extern byte briIT; +extern byte briLast; +extern byte whiteLast; +extern bool buttonPressedBefore; +extern bool buttonLongPressed; +extern unsigned long buttonPressedTime; +extern unsigned long buttonWaitTime; +extern bool notifyDirectDefault; +extern bool receiveNotifications; +extern unsigned long notificationSentTime; +extern byte notificationSentCallMode; +extern bool notificationTwoRequired; +extern byte effectCurrent; +extern byte effectSpeed; +extern byte effectIntensity; +extern byte effectPalette; +extern bool udpConnected, udpRgbConnected; +extern bool showWelcomePage; +extern byte hueError; +extern float hueXLast, hueYLast; +extern uint16_t hueHueLast, hueCtLast; +extern byte hueSatLast, hueBriLast; +extern unsigned long hueLastRequestSent; +extern bool hueAuthRequired; +extern bool hueReceived; +extern bool hueStoreAllowed, hueNewKey; +extern byte overlayCurrent; +extern byte overlaySpeed; +extern unsigned long overlayRefreshMs; +extern unsigned long overlayRefreshedTime; +extern byte dP[]; +extern bool cronixieInit; +extern unsigned long countdownTime; +extern bool countdownOverTriggered; +extern byte lastTimerMinute; +extern byte timerHours[]; +extern byte timerMinutes[]; +extern byte timerMacro[]; +extern byte timerWeekday[]; +extern bool blynkEnabled; +extern bool presetCyclingEnabled; +extern byte presetCycleMin, presetCycleMax; +extern uint16_t presetCycleTime; +extern unsigned long presetCycledTime; +extern byte presetCycCurr; +extern bool presetApplyBri; +extern bool saveCurrPresetCycConf; +extern byte realtimeMode; +extern IPAddress realtimeIP; +extern unsigned long realtimeTimeout; +extern long lastMqttReconnectAttempt; +extern long lastInterfaceUpdate; +extern byte interfaceUpdateCallMode; +extern char mqttStatusTopic[40]; +#if AUXPIN >= 0 + extern byte auxTime; + extern unsigned long auxStartTime; + extern bool auxActive; +#endif +extern String escapedMac; +#ifndef WLED_DISABLE_ALEXA + extern Espalexa espalexa; + extern EspalexaDevice *espalexaDevice; +#endif + +#define NTP_PACKET_SIZE 48 +extern DNSServer dnsServer; +extern bool ntpConnected; +extern time_t local; +extern unsigned long ntpLastSyncTime; +extern unsigned long ntpPacketSentTime; +extern IPAddress ntpServerIP; +extern uint16_t ntpLocalPort; + +// maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue +#define MAX_LEDS 1500 +#define MAX_LEDS_DMA 500 + +// string temp buffer (now stored in stack locally) +#define OMAX 2048 +extern char* obuf; +extern uint16_t olen; + +extern uint16_t savedPresets; +extern int8_t currentPreset; +extern bool isPreset; +extern byte errorFlag; +extern String messageHead, messageSub; +extern byte optionType; +extern bool doReboot; +extern bool doPublishMqtt; +extern AsyncWebServer server; +extern AsyncClient* hueClient; +extern AsyncMqttClient* mqtt; +extern WiFiUDP notifierUdp, rgbUdp; +extern WiFiUDP ntpUdp; +extern ESPAsyncE131 e131; +extern bool e131NewData; +extern WS2812FX strip; + +#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) +#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) + +// debug macros +#ifdef WLED_DEBUG + #define DEBUG_PRINT(x) Serial.print(x) + #define DEBUG_PRINTLN(x) Serial.println(x) + #define DEBUG_PRINTF(x) Serial.printf(x) + extern unsigned long debugTime; + extern int lastWifiState; + extern unsigned long wifiStateChangedTime; + extern int loops; +#else + #define DEBUG_PRINT(x) + #define DEBUG_PRINTLN(x) + #define DEBUG_PRINTF(x) +#endif + +// append new c string to temp buffer efficiently +bool oappend(const char* txt); +// append new number to temp buffer efficiently +bool oappendi(int i); + +class WLED { +public: + WLED(); + static WLED& instance() + { + static WLED instance; + return instance; + } + + // boot starts here + void setup(); + + void loop(); + void reset(); + + void beginStrip(); + void handleConnection(); + void initAP(bool resetAP = false); + void initConnection(); + void initInterfaces(); +}; +#endif // WLED_H diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 728c5ef66..e33348379 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -1,617 +1,12 @@ /* - Main sketch, global variable declarations + Arduino Studio support file. */ -/* - * @title WLED project sketch - * @version 0.9.1 - * @author Christian Schwinne - */ +#include "wled.h" -//ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). - -//ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS). -//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB): - -//You are required to disable over-the-air updates: -//#define WLED_DISABLE_OTA //saves 14kb - -//You need to choose some of these features to disable: -//#define WLED_DISABLE_ALEXA //saves 11kb -//#define WLED_DISABLE_BLYNK //saves 6kb -//#define WLED_DISABLE_CRONIXIE //saves 3kb -//#define WLED_DISABLE_HUESYNC //saves 4kb -//#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01, saves 12kb -#define WLED_ENABLE_MQTT //saves 12kb -#define WLED_ENABLE_ADALIGHT //saves 500b only -//#define WLED_ENABLE_DMX //uses 3.5kb - -#define WLED_DISABLE_FILESYSTEM //SPIFFS is not used by any WLED feature yet -//#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version -//#define WLED_ENABLE_FS_EDITOR //enable /edit page for editing SPIFFS content. Will also be disabled with OTA lock - -//to toggle usb serial debug (un)comment the following line -//#define WLED_DEBUG - -//library inclusions -#include -#ifdef WLED_ENABLE_DMX - #include - DMXESPSerial dmx; -#endif -#ifdef ESP8266 - #include - #include - #include - extern "C" { - #include - } -#else //ESP32 - #include - #include "esp_wifi.h" - #include - #include - #include "SPIFFS.h" -#endif - -#include -#include -#include -#include -#ifndef WLED_DISABLE_OTA - #include -#endif -#include -#include "src/dependencies/time/TimeLib.h" -#include "src/dependencies/timezone/Timezone.h" -#ifndef WLED_DISABLE_ALEXA - #define ESPALEXA_ASYNC - #define ESPALEXA_NO_SUBPAGE - #define ESPALEXA_MAXDEVICES 1 - // #define ESPALEXA_DEBUG - #include "src/dependencies/espalexa/Espalexa.h" -#endif -#ifndef WLED_DISABLE_BLYNK - #include "src/dependencies/blynk/BlynkSimpleEsp.h" -#endif -#include "src/dependencies/e131/ESPAsyncE131.h" -#include "src/dependencies/async-mqtt-client/AsyncMqttClient.h" -#include "src/dependencies/json/AsyncJson-v6.h" -#include "src/dependencies/json/ArduinoJson-v6.h" -#include "html_ui.h" -#include "html_settings.h" -#include "html_other.h" -#include "FX.h" -#include "ir_codes.h" -#include "const.h" - -#ifndef CLIENT_SSID -#define CLIENT_SSID DEFAULT_CLIENT_SSID -#endif - -#ifndef CLIENT_PASS -#define CLIENT_PASS "" -#endif - - -#if IR_PIN < 0 - #ifndef WLED_DISABLE_INFRARED - #define WLED_DISABLE_INFRARED - #endif -#endif - -#ifndef WLED_DISABLE_INFRARED - #include - #include - #include -#endif - -// remove flicker because PWM signal of RGB channels can become out of phase -#if defined(WLED_USE_ANALOG_LEDS) && defined(ESP8266) - #include "src/dependencies/arduino/core_esp8266_waveform.h" -#endif - -// enable additional debug output -#ifdef WLED_DEBUG - #ifndef ESP8266 - #include - #endif -#endif - -//version code in format yymmddb (b = daily build) -#define VERSION 2003262 - -char versionString[] = "0.9.1"; - - -//AP and OTA default passwords (for maximum change them!) -char apPass[65] = DEFAULT_AP_PASS; -char otaPass[33] = DEFAULT_OTA_PASS; - - -//Hardware CONFIG (only changeble HERE, not at runtime) -//LED strip pin, button pin and IR pin changeable in NpbWrapper.h! - -byte auxDefaultState = 0; //0: input 1: high 2: low -byte auxTriggeredState = 0; //0: input 1: high 2: low -char ntpServerName[33] = "0.wled.pool.ntp.org";//NTP server to use - - -//WiFi CONFIG (all these can be changed via web UI, no need to set them here) -char clientSSID[33] = CLIENT_SSID; -char clientPass[65] = CLIENT_PASS; -char cmDNS[33] = "x"; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) -char apSSID[33] = ""; //AP off by default (unless setup) -byte apChannel = 1; //2.4GHz WiFi AP channel (1-13) -byte apHide = 0; //hidden AP SSID -byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; //access point opens when no connection after boot by default -IPAddress staticIP(0, 0, 0, 0); //static IP of ESP -IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP -IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks -bool noWifiSleep = false; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues - - -//LED CONFIG -uint16_t ledCount = 30; //overcurrent prevented by ABL -bool useRGBW = false; //SK6812 strips can contain an extra White channel -#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit -bool turnOnAtBoot = true; //turn on LEDs at power-up -byte bootPreset = 0; //save preset to load after power-up - -byte col[] {255, 160, 0, 0}; //current RGB(W) primary color. col[] should be updated if you want to change the color. -byte colSec[] {0, 0, 0, 0}; //current RGB(W) secondary color -byte briS = 128; //default brightness - -byte nightlightTargetBri = 0; //brightness after nightlight is over -byte nightlightDelayMins = 60; -bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over -bool nightlightColorFade = false; //if enabled, light will gradually fade color from primary to secondary color. -bool fadeTransition = true; //enable crossfading color transition -uint16_t transitionDelay = 750; //default crossfade duration in ms - -bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) -byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) - - -//User Interface CONFIG -char serverDescription[33] = "WLED"; //Name of module -bool syncToggleReceive = false; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise - - -//Sync CONFIG -bool buttonEnabled = true; -byte irEnabled = 0; //Infrared receiver - -uint16_t udpPort = 21324; //WLED notifier default port -uint16_t udpRgbPort = 19446; //Hyperion port - -bool receiveNotificationBrightness = true; //apply brightness from incoming notifications -bool receiveNotificationColor = true; //apply color -bool receiveNotificationEffects = true; //apply effects setup -bool notifyDirect = false; //send notification if change via UI or HTTP API -bool notifyButton = false; //send if updated by button or infrared remote -bool notifyAlexa = false; //send notification if updated via Alexa -bool notifyMacro = false; //send notification for macro -bool notifyHue = true; //send notification if Hue light changes -bool notifyTwice = false; //notifications use UDP: enable if devices don't sync reliably - -bool alexaEnabled = true; //enable device discovery by Amazon Echo -char alexaInvocationName[33] = "Light"; //speech control name of device. Choose something voice-to-text can understand - -char blynkApiKey[36] = ""; //Auth token for Blynk server. If empty, no connection will be made - -uint16_t realtimeTimeoutMs = 2500; //ms timeout of realtime mode before returning to normal mode -int arlsOffset = 0; //realtime LED offset -bool receiveDirect = true; //receive UDP realtime -bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source -bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black - -#define E131_MAX_UNIVERSE_COUNT 9 -uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) -uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.) -uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] -uint8_t DMXOldDimmer = 0; //only update brightness on change -uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss -bool e131Multicast = false; //multicast or unicast -bool e131SkipOutOfSequence = false; //freeze instead of flickering - -bool mqttEnabled = false; -char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac) -char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices) -char mqttServer[33] = ""; //both domains and IPs should work (no SSL) -char mqttUser[41] = ""; //optional: username for MQTT auth -char mqttPass[41] = ""; //optional: password for MQTT auth -char mqttClientID[41] = ""; //override the client ID -uint16_t mqttPort = 1883; - -bool huePollingEnabled = false; //poll hue bridge for light state -uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response -char hueApiKey[47] = "api"; //key token will be obtained from bridge -byte huePollLightId = 1; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) -IPAddress hueIP = (0, 0, 0, 0); //IP address of the bridge -bool hueApplyOnOff = true; -bool hueApplyBri = true; -bool hueApplyColor = true; - - -//Time CONFIG -bool ntpEnabled = false; //get internet time. Only required if you use clock overlays or time-activated macros -bool useAMPM = false; //12h/24h clock format -byte currentTimezone = 0; //Timezone ID. Refer to timezones array in wled10_ntp.ino -int utcOffsetSecs = 0; //Seconds to offset from UTC before timzone calculation - -byte overlayDefault = 0; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie -byte overlayMin = 0, overlayMax = ledCount - 1; //boundaries of overlay mode - -byte analogClock12pixel = 0; //The pixel in your strip where "midnight" would be -bool analogClockSecondsTrail = false; //Display seconds as trail of LEDs instead of a single pixel -bool analogClock5MinuteMarks = false; //Light pixels at every 5-minute position - -char cronixieDisplay[7] = "HHMMSS"; //Cronixie Display mask. See wled13_cronixie.ino -bool cronixieBacklight = true; //Allow digits to be back-illuminated - -bool countdownMode = false; //Clock will count down towards date -byte countdownYear = 20, countdownMonth = 1; //Countdown target date, year is last two digits -byte countdownDay = 1, countdownHour = 0; -byte countdownMin = 0, countdownSec = 0; - - -byte macroBoot = 0; //macro loaded after startup -byte macroNl = 0; //after nightlight delay over -byte macroCountdown = 0; -byte macroAlexaOn = 0, macroAlexaOff = 0; -byte macroButton = 0, macroLongPress = 0, macroDoublePress = 0; - - -//Security CONFIG -bool otaLock = false; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks -bool wifiLock = false; //prevents access to WiFi settings when OTA lock is enabled -bool aOtaEnabled = true; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on - - -uint16_t userVar0 = 0, userVar1 = 0; - -#ifdef WLED_ENABLE_DMX - //dmx CONFIG - byte DMXChannels = 7; // number of channels per fixture - byte DMXFixtureMap[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - // assigns the different channels to different functions. See wled21_dmx.ino for more information. - uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. - uint16_t DMXStart = 10; // start address of the first fixture -#endif - - -//internal global variable declarations -//wifi -bool apActive = false; -bool forceReconnect = false; -uint32_t lastReconnectAttempt = 0; -bool interfacesInited = false; -bool wasConnected = false; - -//color -byte colOld[] {0, 0, 0, 0}; //color before transition -byte colT[] {0, 0, 0, 0}; //color that is currently displayed on the LEDs -byte colIT[] {0, 0, 0, 0}; //color that was last sent to LEDs -byte colSecT[] {0, 0, 0, 0}; -byte colSecOld[] {0, 0, 0, 0}; -byte colSecIT[] {0, 0, 0, 0}; - -byte lastRandomIndex = 0; //used to save last random color so the new one is not the same - -//transitions -bool transitionActive = false; -uint16_t transitionDelayDefault = transitionDelay; -uint16_t transitionDelayTemp = transitionDelay; -unsigned long transitionStartTime; -float tperLast = 0; //crossfade transition progress, 0.0f - 1.0f -bool jsonTransitionOnce = false; - -//nightlight -bool nightlightActive = false; -bool nightlightActiveOld = false; -uint32_t nightlightDelayMs = 10; -uint8_t nightlightDelayMinsDefault = nightlightDelayMins; -unsigned long nightlightStartTime; -byte briNlT = 0; //current nightlight brightness -byte colNlT[] {0, 0, 0, 0}; //current nightlight color - -//brightness -unsigned long lastOnTime = 0; -bool offMode = !turnOnAtBoot; -byte bri = briS; -byte briOld = 0; -byte briT = 0; -byte briIT = 0; -byte briLast = 128; //brightness before turned off. Used for toggle function -byte whiteLast = 128; //white channel before turned off. Used for toggle function - -//button -bool buttonPressedBefore = false; -bool buttonLongPressed = false; -unsigned long buttonPressedTime = 0; -unsigned long buttonWaitTime = 0; - -//notifications -bool notifyDirectDefault = notifyDirect; -bool receiveNotifications = true; -unsigned long notificationSentTime = 0; -byte notificationSentCallMode = NOTIFIER_CALL_MODE_INIT; -bool notificationTwoRequired = false; - -//effects -byte effectCurrent = 0; -byte effectSpeed = 128; -byte effectIntensity = 128; -byte effectPalette = 0; - -//network -bool udpConnected = false, udpRgbConnected = false; - -//ui style -bool showWelcomePage = false; - -//hue -byte hueError = HUE_ERROR_INACTIVE; -//uint16_t hueFailCount = 0; -float hueXLast = 0, hueYLast = 0; -uint16_t hueHueLast = 0, hueCtLast = 0; -byte hueSatLast = 0, hueBriLast = 0; -unsigned long hueLastRequestSent = 0; -bool hueAuthRequired = false; -bool hueReceived = false; -bool hueStoreAllowed = false, hueNewKey = false; - -//overlays -byte overlayCurrent = overlayDefault; -byte overlaySpeed = 200; -unsigned long overlayRefreshMs = 200; -unsigned long overlayRefreshedTime; - -//cronixie -byte dP[] {0, 0, 0, 0, 0, 0}; -bool cronixieInit = false; - -//countdown -unsigned long countdownTime = 1514764800L; -bool countdownOverTriggered = true; - -//timer -byte lastTimerMinute = 0; -byte timerHours[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerMinutes[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerMacro[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerWeekday[] = {255, 255, 255, 255, 255, 255, 255, 255}; //weekdays to activate on -//bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity - -//blynk -bool blynkEnabled = false; - -//preset cycling -bool presetCyclingEnabled = false; -byte presetCycleMin = 1, presetCycleMax = 5; -uint16_t presetCycleTime = 1250; -unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin; -bool presetApplyBri = true; -bool saveCurrPresetCycConf = false; - -//realtime -byte realtimeMode = REALTIME_MODE_INACTIVE; -IPAddress realtimeIP = (0,0,0,0); -unsigned long realtimeTimeout = 0; - -//mqtt -long lastMqttReconnectAttempt = 0; -long lastInterfaceUpdate = 0; -byte interfaceUpdateCallMode = NOTIFIER_CALL_MODE_INIT; -char mqttStatusTopic[40] = ""; //this must be global because of async handlers - -#if AUXPIN >= 0 - //auxiliary debug pin - byte auxTime = 0; - unsigned long auxStartTime = 0; - bool auxActive = false, auxActiveBefore = false; -#endif - -//alexa udp -String escapedMac; -#ifndef WLED_DISABLE_ALEXA - Espalexa espalexa; - EspalexaDevice* espalexaDevice; -#endif - -//dns server -DNSServer dnsServer; - -//network time -bool ntpConnected = false; -time_t local = 0; -unsigned long ntpLastSyncTime = 999000000L; -unsigned long ntpPacketSentTime = 999000000L; -IPAddress ntpServerIP; -uint16_t ntpLocalPort = 2390; -#define NTP_PACKET_SIZE 48 - -//maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue -#define MAX_LEDS 1500 -#define MAX_LEDS_DMA 500 - -//string temp buffer (now stored in stack locally) -#define OMAX 2048 -char* obuf; -uint16_t olen = 0; - -//presets -uint16_t savedPresets = 0; -int8_t currentPreset = -1; -bool isPreset = false; - -byte errorFlag = 0; - -String messageHead, messageSub; -byte optionType; - -bool doReboot = false; //flag to initiate reboot from async handlers -bool doPublishMqtt = false; - -//server library objects -AsyncWebServer server(80); -AsyncClient* hueClient = NULL; -AsyncMqttClient* mqtt = NULL; - -//function prototypes -void colorFromUint32(uint32_t, bool = false); -void serveMessage(AsyncWebServerRequest*, uint16_t, String, String, byte); -void handleE131Packet(e131_packet_t*, IPAddress); -void arlsLock(uint32_t,byte); -void handleOverlayDraw(); - -//udp interface objects -WiFiUDP notifierUdp, rgbUdp; -WiFiUDP ntpUdp; -ESPAsyncE131 e131(handleE131Packet); -bool e131NewData = false; - -//led fx library object -WS2812FX strip = WS2812FX(); - -#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) -#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID,DEFAULT_CLIENT_SSID) != 0) - -//debug macros -#ifdef WLED_DEBUG - #define DEBUG_PRINT(x) Serial.print (x) - #define DEBUG_PRINTLN(x) Serial.println (x) - #define DEBUG_PRINTF(x) Serial.printf (x) - unsigned long debugTime = 0; - int lastWifiState = 3; - unsigned long wifiStateChangedTime = 0; - int loops = 0; -#else - #define DEBUG_PRINT(x) - #define DEBUG_PRINTLN(x) - #define DEBUG_PRINTF(x) -#endif - -//filesystem -#ifndef WLED_DISABLE_FILESYSTEM - #include - #ifdef ARDUINO_ARCH_ESP32 - #include "SPIFFS.h" - #endif - #include "SPIFFSEditor.h" -#endif - - - -//turns all LEDs off and restarts ESP -void reset() -{ - briT = 0; - long dly = millis(); - while (millis() - dly < 250) - { - yield(); //enough time to send response to client - } - setAllLeds(); - DEBUG_PRINTLN("MODULE RESET"); - ESP.restart(); -} - - -//append new c string to temp buffer efficiently -bool oappend(const char* txt) -{ - uint16_t len = strlen(txt); - if (olen + len >= OMAX) return false; //buffer full - strcpy(obuf + olen, txt); - olen += len; - return true; -} - - -//append new number to temp buffer efficiently -bool oappendi(int i) -{ - char s[11]; - sprintf(s, "%ld", i); - return oappend(s); -} - - -//boot starts here void setup() { - wledInit(); + WLED::instance().setup(); } - -//main program loop void loop() { - handleIR(); //2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too - handleConnection(); - handleSerial(); - handleNotifications(); - handleTransitions(); -#ifdef WLED_ENABLE_DMX - handleDMX(); -#endif - userLoop(); - - yield(); - handleIO(); - handleIR(); - handleNetworkTime(); - handleAlexa(); - - handleOverlays(); - yield(); -#ifdef WLED_USE_ANALOG_LEDS - strip.setRgbwPwm(); -#endif - - if (doReboot) reset(); - - if (!realtimeMode) //block stuff if WARLS/Adalight is enabled - { - if (apActive) dnsServer.processNextRequest(); -#ifndef WLED_DISABLE_OTA - if (WLED_CONNECTED && aOtaEnabled) ArduinoOTA.handle(); -#endif - handleNightlight(); - yield(); - - handleHue(); - handleBlynk(); - - yield(); - if (!offMode) strip.service(); - } - yield(); -#ifdef ESP8266 - MDNS.update(); -#endif - if (millis() - lastMqttReconnectAttempt > 30000) initMqtt(); - - //DEBUG serial logging -#ifdef WLED_DEBUG - if (millis() - debugTime > 9999) - { - DEBUG_PRINTLN("---DEBUG INFO---"); - DEBUG_PRINT("Runtime: "); DEBUG_PRINTLN(millis()); - DEBUG_PRINT("Unix time: "); DEBUG_PRINTLN(now()); - DEBUG_PRINT("Free heap: "); DEBUG_PRINTLN(ESP.getFreeHeap()); - DEBUG_PRINT("Wifi state: "); DEBUG_PRINTLN(WiFi.status()); - if (WiFi.status() != lastWifiState) - { - wifiStateChangedTime = millis(); - } - lastWifiState = WiFi.status(); - DEBUG_PRINT("State time: "); DEBUG_PRINTLN(wifiStateChangedTime); - DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime); - DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP()); - DEBUG_PRINT("Loops/sec: "); DEBUG_PRINTLN(loops / 10); - loops = 0; - debugTime = millis(); - } - loops++; -#endif -} + WLED::instance().loop(); +} \ No newline at end of file diff --git a/wled00/wled00.vcxproj b/wled00/wled00.vcxproj index 2183ad262..e095b8f76 100644 --- a/wled00/wled00.vcxproj +++ b/wled00/wled00.vcxproj @@ -104,231 +104,103 @@ CppCode - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -350,6 +222,11 @@ + + + + + VisualMicroDebugger @@ -362,4 +239,4 @@ - \ No newline at end of file + diff --git a/wled00/wled00.vcxproj.filters b/wled00/wled00.vcxproj.filters index e2c2b219c..39fe509e9 100644 --- a/wled00/wled00.vcxproj.filters +++ b/wled00/wled00.vcxproj.filters @@ -1,272 +1,387 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {72fe60da-ba26-45b4-82c1-bdff809975da} + + + {8880888d-efea-4189-a25a-834b7b3bb756} + + + + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + \ No newline at end of file diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino deleted file mode 100644 index 29ae0e7ab..000000000 --- a/wled00/wled05_init.ino +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Setup code - */ - -void wledInit() -{ - EEPROM.begin(EEPSIZE); - ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); - if (ledCount > MAX_LEDS || ledCount == 0) ledCount = 30; - - #ifdef ESP8266 - #if LEDPIN == 3 - if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram - #endif - #endif - Serial.begin(115200); - Serial.setTimeout(50); - DEBUG_PRINTLN(); - DEBUG_PRINT("---WLED "); DEBUG_PRINT(versionString); DEBUG_PRINT(" "); DEBUG_PRINT(VERSION); DEBUG_PRINTLN(" INIT---"); - #ifdef ARDUINO_ARCH_ESP32 - DEBUG_PRINT("esp32 "); DEBUG_PRINTLN(ESP.getSdkVersion()); - #else - DEBUG_PRINT("esp8266 "); DEBUG_PRINTLN(ESP.getCoreVersion()); - #endif - int heapPreAlloc = ESP.getFreeHeap(); - DEBUG_PRINT("heap "); - DEBUG_PRINTLN(ESP.getFreeHeap()); - - strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204)); //init LEDs quickly - strip.setBrightness(0); - - DEBUG_PRINT("LEDs inited. heap usage ~"); - DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap()); - - #ifndef WLED_DISABLE_FILESYSTEM - #ifdef ARDUINO_ARCH_ESP32 - SPIFFS.begin(true); - #endif - SPIFFS.begin(); - #endif - - DEBUG_PRINTLN("Load EEPROM"); - loadSettingsFromEEPROM(true); - beginStrip(); - userSetup(); - if (strcmp(clientSSID,DEFAULT_CLIENT_SSID) == 0) showWelcomePage = true; - WiFi.persistent(false); - - if (macroBoot>0) applyMacro(macroBoot); - Serial.println("Ada"); - - //generate module IDs - escapedMac = WiFi.macAddress(); - escapedMac.replace(":", ""); - escapedMac.toLowerCase(); - if (strcmp(cmDNS,"x") == 0) //fill in unique mdns default - { - strcpy(cmDNS, "wled-"); - sprintf(cmDNS+5, "%*s", 6, escapedMac.c_str()+6); - } - if (mqttDeviceTopic[0] == 0) - { - strcpy(mqttDeviceTopic, "wled/"); - sprintf(mqttDeviceTopic+5, "%*s", 6, escapedMac.c_str()+6); - } - if (mqttClientID[0] == 0) - { - strcpy(mqttClientID, "WLED-"); - sprintf(mqttClientID+5, "%*s", 6, escapedMac.c_str()+6); - } - - strip.service(); - - #ifndef WLED_DISABLE_OTA - if (aOtaEnabled) - { - ArduinoOTA.onStart([]() { - #ifdef ESP8266 - wifi_set_sleep_type(NONE_SLEEP_T); - #endif - DEBUG_PRINTLN("Start ArduinoOTA"); - }); - if (strlen(cmDNS) > 0) ArduinoOTA.setHostname(cmDNS); - } - #endif - #ifdef WLED_ENABLE_DMX - dmx.init(512); // initialize with bus length - #endif - //HTTP server page init - initServer(); -} - - -void beginStrip() -{ - // Initialize NeoPixel Strip and button - strip.setShowCallback(handleOverlayDraw); - -#ifdef BTNPIN - pinMode(BTNPIN, INPUT_PULLUP); -#endif - - if (bootPreset > 0) applyPreset(bootPreset, turnOnAtBoot); - colorUpdated(NOTIFIER_CALL_MODE_INIT); - - //init relay pin - #if RLYPIN >= 0 - pinMode(RLYPIN, OUTPUT); - #if RLYMDE - digitalWrite(RLYPIN, bri); - #else - digitalWrite(RLYPIN, !bri); - #endif - #endif - - //disable button if it is "pressed" unintentionally -#ifdef BTNPIN - if(digitalRead(BTNPIN) == LOW) buttonEnabled = false; -#else - buttonEnabled = false; -#endif -} - - -void initAP(bool resetAP=false){ - if (apBehavior == AP_BEHAVIOR_BUTTON_ONLY && !resetAP) return; - - if (!apSSID[0] || resetAP) strcpy(apSSID, "WLED-AP"); - if (resetAP) strcpy(apPass,DEFAULT_AP_PASS); - DEBUG_PRINT("Opening access point "); - DEBUG_PRINTLN(apSSID); - WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255,255,255,0)); - WiFi.softAP(apSSID, apPass, apChannel, apHide); - - if (!apActive) //start captive portal if AP active - { - DEBUG_PRINTLN("Init AP interfaces"); - server.begin(); - if (udpPort > 0 && udpPort != ntpLocalPort) - { - udpConnected = notifierUdp.begin(udpPort); - } - if (udpRgbPort > 0 && udpRgbPort != ntpLocalPort && udpRgbPort != udpPort) - { - udpRgbConnected = rgbUdp.begin(udpRgbPort); - } - - dnsServer.setErrorReplyCode(DNSReplyCode::NoError); - dnsServer.start(53, "*", WiFi.softAPIP()); - } - apActive = true; -} - -void initConnection() -{ - WiFi.disconnect(); //close old connections - #ifdef ESP8266 - WiFi.setPhyMode(WIFI_PHY_MODE_11N); - #endif - - if (staticIP[0] != 0 && staticGateway[0] != 0) - { - WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(8,8,8,8)); - } else - { - WiFi.config(0U, 0U, 0U); - } - - lastReconnectAttempt = millis(); - - if (!WLED_WIFI_CONFIGURED) - { - DEBUG_PRINT("No connection configured. "); - if (!apActive) initAP(); //instantly go to ap mode - return; - } else if (!apActive) { - if (apBehavior == AP_BEHAVIOR_ALWAYS) - { - initAP(); - } else - { - DEBUG_PRINTLN("Access point disabled."); - WiFi.softAPdisconnect(true); - } - } - showWelcomePage = false; - - DEBUG_PRINT("Connecting to "); - DEBUG_PRINT(clientSSID); - DEBUG_PRINTLN("..."); - - #ifdef ESP8266 - WiFi.hostname(serverDescription); - #endif - - WiFi.begin(clientSSID, clientPass); - - #ifdef ARDUINO_ARCH_ESP32 - WiFi.setSleep(!noWifiSleep); - WiFi.setHostname(serverDescription); - #else - wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); - #endif -} - -void initInterfaces() { - DEBUG_PRINTLN("Init STA interfaces"); - - if (hueIP[0] == 0) - { - hueIP[0] = WiFi.localIP()[0]; - hueIP[1] = WiFi.localIP()[1]; - hueIP[2] = WiFi.localIP()[2]; - } - - //init Alexa hue emulation - if (alexaEnabled) alexaInit(); - - #ifndef WLED_DISABLE_OTA - if (aOtaEnabled) ArduinoOTA.begin(); - #endif - - strip.service(); - // Set up mDNS responder: - if (strlen(cmDNS) > 0) - { - if (!aOtaEnabled) MDNS.begin(cmDNS); - - DEBUG_PRINTLN("mDNS started"); - MDNS.addService("http", "tcp", 80); - MDNS.addService("wled", "tcp", 80); - MDNS.addServiceTxt("wled", "tcp", "mac", escapedMac.c_str()); - } - server.begin(); - - if (udpPort > 0 && udpPort != ntpLocalPort) - { - udpConnected = notifierUdp.begin(udpPort); - if (udpConnected && udpRgbPort != udpPort) udpRgbConnected = rgbUdp.begin(udpRgbPort); - } - if (ntpEnabled) ntpConnected = ntpUdp.begin(ntpLocalPort); - - initBlynk(blynkApiKey); - e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe, E131_MAX_UNIVERSE_COUNT); - reconnectHue(); - initMqtt(); - interfacesInited = true; - wasConnected = true; -} - -byte stacO = 0; -uint32_t lastHeap; -unsigned long heapTime = 0; - -void handleConnection() { - if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS)) return; - if (lastReconnectAttempt == 0) initConnection(); - - //reconnect WiFi to clear stale allocations if heap gets too low - if (millis() - heapTime > 5000) - { - uint32_t heap = ESP.getFreeHeap(); - if (heap < 9000 && lastHeap < 9000) { - DEBUG_PRINT("Heap too low! "); - DEBUG_PRINTLN(heap); - forceReconnect = true; - } - lastHeap = heap; - heapTime = millis(); - } - - byte stac = 0; - if (apActive) { - #ifdef ESP8266 - stac = wifi_softap_get_station_num(); - #else - wifi_sta_list_t stationList; - esp_wifi_ap_get_sta_list(&stationList); - stac = stationList.num; - #endif - if (stac != stacO) - { - stacO = stac; - DEBUG_PRINT("Connected AP clients: "); - DEBUG_PRINTLN(stac); - if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) { //trying to connect, but not connected - if (stac) WiFi.disconnect(); //disable search so that AP can work - else initConnection(); //restart search - } - } - } - if (forceReconnect) { - DEBUG_PRINTLN("Forcing reconnect."); - initConnection(); - interfacesInited = false; - forceReconnect = false; - wasConnected = false; - return; - } - if (!WLED_CONNECTED) { - if (interfacesInited) { - DEBUG_PRINTLN("Disconnected!"); - interfacesInited = false; - initConnection(); - } - if (millis() - lastReconnectAttempt > ((stac) ? 300000 : 20000) && WLED_WIFI_CONFIGURED) initConnection(); - if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) initAP(); - } else if (!interfacesInited) { //newly connected - DEBUG_PRINTLN(""); - DEBUG_PRINT("Connected! IP address: "); - DEBUG_PRINTLN(WiFi.localIP()); - initInterfaces(); - userConnected(); - - //shut down AP - if (apBehavior != AP_BEHAVIOR_ALWAYS && apActive) - { - dnsServer.stop(); - WiFi.softAPdisconnect(true); - apActive = false; - DEBUG_PRINTLN("Access point disabled."); - } - } -} - -//by https://github.com/tzapu/WiFiManager/blob/master/WiFiManager.cpp -int getSignalQuality(int rssi) -{ - int quality = 0; - - if (rssi <= -100) { - quality = 0; - } else if (rssi >= -50) { - quality = 100; - } else { - quality = 2 * (rssi + 100); - } - return quality; -} diff --git a/wled00/wled21_dmx.ino b/wled00/wled21_dmx.ino deleted file mode 100644 index 4230f07d8..000000000 --- a/wled00/wled21_dmx.ino +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Support for DMX via MAX485. - * Needs the espdmx library. You might have to change the output pin within the library. Sketchy, i know. - * https://github.com/Rickgg/ESP-Dmx - */ -#ifdef WLED_ENABLE_DMX - -void handleDMX() { - // TODO: calculate brightness manually if no shutter channel is set - - uint8_t brightness = strip.getBrightness(); - - for (int i = 0; i < ledCount; i++) { // uses the amount of LEDs as fixture count - - uint32_t in = strip.getPixelColor(i); // time to get the colors for the individual fixtures as suggested by AirCookie at issue #462 - byte w = in >> 24 & 0xFF; - byte r = in >> 16 & 0xFF; - byte g = in >> 8 & 0xFF; - byte b = in & 0xFF; - - int DMXFixtureStart = DMXStart + (DMXGap * i); - for (int j = 0; j < DMXChannels; j++) { - int DMXAddr = DMXFixtureStart + j; - switch (DMXFixtureMap[j]) { - case 0: // Set this channel to 0. Good way to tell strobe- and fade-functions to fuck right off. - dmx.write(DMXAddr, 0); - break; - case 1: // Red - dmx.write(DMXAddr, r); - break; - case 2: // Green - dmx.write(DMXAddr, g); - break; - case 3: // Blue - dmx.write(DMXAddr, b); - break; - case 4: // White - dmx.write(DMXAddr, w); - break; - case 5: // Shutter channel. Controls the brightness. - dmx.write(DMXAddr, brightness); - break; - case 6:// Sets this channel to 255. Like 0, but more wholesome. - dmx.write(DMXAddr, 255); - break; - } - } - } - - dmx.update(); // update the DMX bus -} - -#else -void handleDMX() {} -#endif diff --git a/wled00/wled01_eeprom.ino b/wled00/wled_eeprom.cpp similarity index 98% rename from wled00/wled01_eeprom.ino rename to wled00/wled_eeprom.cpp index 1f0e8426f..0087641aa 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled_eeprom.cpp @@ -1,9 +1,11 @@ -/* - * Methods to handle saving and loading to non-volatile memory - * EEPROM Map: https://github.com/Aircoookie/WLED/wiki/EEPROM-Map - */ +#include "wled_eeprom.h" +#include +#include "wled.h" +#include "cronixie.h" +#include "ntp.h" +#include "set.h" +#include "led.h" -#define EEPSIZE 2560 //Maximum is 4096 //eeprom Version code, enables default settings instead of 0 init on update #define EEPVER 18 @@ -591,7 +593,7 @@ void savedToPresets() } } -bool applyPreset(byte index, bool loadBri = true) +bool applyPreset(byte index, bool loadBri) { if (index == 255 || index == 0) { @@ -629,7 +631,7 @@ bool applyPreset(byte index, bool loadBri = true) return true; } -void savePreset(byte index, bool persist = true) +void savePreset(byte index, bool persist) { if (index > 16) return; if (index < 1) {saveSettingsToEEPROM();return;} @@ -697,7 +699,7 @@ void applyMacro(byte index) } -void saveMacro(byte index, String mc, bool persist = true) //only commit on single save, not in settings +void saveMacro(byte index, String mc, bool persist) //only commit on single save, not in settings { index-=1; if (index > 15) return; diff --git a/wled00/wled_eeprom.h b/wled00/wled_eeprom.h new file mode 100644 index 000000000..eae52b128 --- /dev/null +++ b/wled00/wled_eeprom.h @@ -0,0 +1,23 @@ +#ifndef WLED_EPPROM_H +#define WLED_EPPROM_H +#include +/* + * Methods to handle saving and loading to non-volatile memory + * EEPROM Map: https://github.com/Aircoookie/WLED/wiki/EEPROM-Map + */ +#define EEPSIZE 2560 //Maximum is 4096 + +void commit(); +void clearEEPROM(); +void writeStringToEEPROM(uint16_t pos, char* str, uint16_t len); +void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len); +void saveSettingsToEEPROM(); +void loadSettingsFromEEPROM(bool first); +void savedToPresets(); +bool applyPreset(byte index, bool loadBri = true); +void savePreset(byte index, bool persist = true); +void loadMacro(byte index, char* m); +void applyMacro(byte index); +void saveMacro(byte index, String mc, bool persist = true); //only commit on single save, not in settings + +#endif //WLED_EPPROM_H diff --git a/wled00/wled18_server.ino b/wled00/wled_server.cpp similarity index 98% rename from wled00/wled18_server.ino rename to wled00/wled_server.cpp index f11a64bec..d5b4eebce 100644 --- a/wled00/wled18_server.ino +++ b/wled00/wled_server.cpp @@ -1,6 +1,10 @@ -/* - * Server page definitions - */ +#include "wled_server.h" +#include "wled.h" +#include "file.h" +#include "set.h" +#include "json.h" +#include "xml.h" + //Is this an IP? bool isIp(String str) { @@ -303,7 +307,7 @@ String msgProcessor(const String& var) } -void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl="", byte optionT=255) +void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl, byte optionT) { messageHead = headl; messageSub = subl; diff --git a/wled00/wled_server.h b/wled00/wled_server.h new file mode 100644 index 000000000..ff7133d63 --- /dev/null +++ b/wled00/wled_server.h @@ -0,0 +1,21 @@ +#ifndef WLED_SERVER_H +#define WLED_SERVER_H +#include +/* + * Server page declarations + */ +class AsyncWebServerRequest; + + +bool isIp(String str); +bool captivePortal(AsyncWebServerRequest *request); +void initServer(); +void serveIndexOrWelcome(AsyncWebServerRequest *request); +void serveIndex(AsyncWebServerRequest* request); +String msgProcessor(const String& var); +void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl="", byte optionT=255); +String settingsProcessor(const String& var); +String dmxProcessor(const String& var); +void serveSettings(AsyncWebServerRequest* request); + +#endif //WLED_SERVER_H \ No newline at end of file diff --git a/wled00/wled02_xml.ino b/wled00/xml.cpp similarity index 98% rename from wled00/wled02_xml.ino rename to wled00/xml.cpp index 100be4822..09e42011d 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/xml.cpp @@ -1,9 +1,11 @@ -/* - * Sending XML status files to client - */ +#include "xml.h" +#include "wled.h" +#include "wled_eeprom.h" +#include "ntp.h" + //build XML response to HTTP /win API request -char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr) +char* XML_response(AsyncWebServerRequest *request, char* dest) { char sbuf[(dest == nullptr)?1024:1]; //allocate local buffer if none passed obuf = (dest == nullptr)? sbuf:dest; diff --git a/wled00/xml.h b/wled00/xml.h new file mode 100644 index 000000000..022982959 --- /dev/null +++ b/wled00/xml.h @@ -0,0 +1,15 @@ +#ifndef WLED_XML_H +#define WLED_XML_H +#include +#include + +/* + * Sending XML status files to client + */ +char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr); +char* URL_response(AsyncWebServerRequest *request); +void sappend(char stype, const char* key, int val); +void sappends(char stype, const char* key, char* val); +void getSettingsJS(byte subPage, char* dest); + +#endif // WLED_XML_H \ No newline at end of file