diff --git a/wled00/html_other.h b/wled00/html_other.h index c7d3e855..e27c64dd 100644 --- a/wled00/html_other.h +++ b/wled00/html_other.h @@ -15,6 +15,36 @@ const char PAGE_msg[] PROGMEM = R"=====(

%MSG%)====="; +//DMX channel map +const char PAGE_dmxmap[] PROGMEM = R"=====( + +DMX Map + + +
...
)====="; + //firmware update page const char PAGE_update[] PROGMEM = R"=====( diff --git a/wled00/html_settings.h b/wled00/html_settings.h index a3ba54a2..157d6b4c 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -1,23 +1,23 @@ /* - * Settings html - */ + Settings html +*/ //common CSS of settings pages const char PAGE_settingsCss[] PROGMEM = R"=====()====="; - //settings menu const char PAGE_settings[] PROGMEM = R"=====( -WLED Settings +WLED Settings
-
+
%DMXMENU%
+ )====="; @@ -172,6 +172,64 @@ Skip first LED:
)====="; +#ifdef WLED_ENABLE_DMX +//DMX Output settings +const char PAGE_settings_dmx[] PROGMEM = R"=====( +DMX Settings"); } diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index f7485917..0f2cb9ef 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -27,8 +27,9 @@ bool isAsterisksOnly(const char* str, byte maxLen) //called upon POST settings form submit void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) { - //0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec - if (subPage <1 || subPage >6) return; + + //0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec 7: DMX + if (subPage <1 || subPage >7) return; //WIFI SETTINGS if (subPage == 1) @@ -293,6 +294,29 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) aOtaEnabled = request->hasArg("AO"); } } + #ifdef WLED_ENABLE_DMX // include only if DMX is enabled + if (subPage == 7) + { + int t = request->arg("CN").toInt(); + if (t>0 && t<16) { + DMXChannels = t; + } + t = request->arg("CS").toInt(); + if (t>0 && t<513) { + DMXStart = t; + } + t = request->arg("CG").toInt(); + if (t>0 && t<513) { + DMXGap = t; + } + for (int i=0; i<15; i++) { + String argname = "CH" + String((i+1)); + t = request->arg(argname).toInt(); + DMXFixtureMap[i] = t; + } + } + + #endif if (subPage != 6 || !doReboot) saveSettingsToEEPROM(); //do not save if factory reset if (subPage == 2) { strip.init(useRGBW,ledCount,skipFirstLed); diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index c4f0b45b..bf1be5d9 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -83,7 +83,9 @@ void wledInit() 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(); } diff --git a/wled00/wled08_led.ino b/wled00/wled08_led.ino index 8aeac5df..d1ccc0d6 100644 --- a/wled00/wled08_led.ino +++ b/wled00/wled08_led.ino @@ -231,15 +231,15 @@ void handleNightlight() nightlightDelayMs = (int)(nightlightDelayMins*60000); nightlightActiveOld = true; briNlT = bri; - for (byte i=0; i<4; i++) colNlT[i] = col[i]; // remember starting color + for (byte i=0; i<4; i++) colNlT[i] = colT[i]; // remember starting color } float nper = (millis() - nightlightStartTime)/((float)nightlightDelayMs); if (nightlightFade) { bri = briNlT + ((nightlightTargetBri - briNlT)*nper); - if (nightlightColorFade) // color fading only is enabled with "NF=2" + if (nightlightColorFade) // color fading only is enabled with "NF=2" { - for (byte i=0; i<4; i++) col[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color + for (byte i=0; i<4; i++) colT[i] = colNlT[i]+ ((colSecT[i] - colNlT[i])*nper); // fading from actual color to secondary color } colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY); } diff --git a/wled00/wled18_server.ino b/wled00/wled18_server.ino index f7162d3e..cf67e79f 100644 --- a/wled00/wled18_server.ino +++ b/wled00/wled18_server.ino @@ -82,6 +82,11 @@ void initServer() serveMessage(request, 200,"UI settings saved.","Redirecting...",1); }); + server.on("/settings/dmx", HTTP_POST, [](AsyncWebServerRequest *request){ + handleSettingsSet(request, 7); + serveMessage(request, 200,"UI settings saved.","Redirecting...",1); + }); + server.on("/settings/sync", HTTP_POST, [](AsyncWebServerRequest *request){ handleSettingsSet(request, 4); serveMessage(request, 200,"Sync settings saved.","Redirecting...",1); @@ -201,6 +206,16 @@ void initServer() }); } + + #ifdef WLED_ENABLE_DMX + server.on("/dmxmap", HTTP_GET, [](AsyncWebServerRequest *request){ + request->send_P(200, "text/html", PAGE_dmxmap , dmxProcessor); + }); + #else + server.on("/dmxmap", HTTP_GET, [](AsyncWebServerRequest *request){ + serveMessage(request, 501, "Not implemented", "DMX support is not enabled in this build.", 254); + }); + #endif server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ if (captivePortal(request)) return; serveIndexOrWelcome(request); @@ -301,10 +316,38 @@ String settingsProcessor(const String& var) getSettingsJS(optionType, buf); return String(buf); } + + #ifdef WLED_ENABLE_DMX + + if (var == "DMXMENU") { + return String("
"); + } + + #endif if (var == "SCSS") return String(FPSTR(PAGE_settingsCss)); return String(); } +String dmxProcessor(const String& var) +{ + String mapJS; + #ifdef WLED_ENABLE_DMX + if (var == "DMXVARS") { + mapJS += "\nCN=" + String(DMXChannels) + ";\n"; + mapJS += "CS=" + String(DMXStart) + ";\n"; + mapJS += "CG=" + String(DMXGap) + ";\n"; + mapJS += "LC=" + String(ledCount) + ";\n"; + mapJS += "var CH=["; + for (int i=0;i<15;i++) { + mapJS += String(DMXFixtureMap[i]) + ","; + } + mapJS += "0];"; + } + #endif + + return mapJS; +} + void serveSettings(AsyncWebServerRequest* request) { @@ -318,6 +361,9 @@ void serveSettings(AsyncWebServerRequest* request) else if (url.indexOf("sync") > 0) subPage = 4; else if (url.indexOf("time") > 0) subPage = 5; else if (url.indexOf("sec") > 0) subPage = 6; + #ifdef WLED_ENABLE_DMX // include only if DMX is enabled + else if (url.indexOf("dmx") > 0) subPage = 7; + #endif } else subPage = 255; //welcome page if (subPage == 1 && wifiLock && otaLock) @@ -339,7 +385,8 @@ void serveSettings(AsyncWebServerRequest* request) case 4: request->send_P(200, "text/html", PAGE_settings_sync, settingsProcessor); break; case 5: request->send_P(200, "text/html", PAGE_settings_time, settingsProcessor); break; case 6: request->send_P(200, "text/html", PAGE_settings_sec , settingsProcessor); break; + case 7: request->send_P(200, "text/html", PAGE_settings_dmx , settingsProcessor); break; case 255: request->send_P(200, "text/html", PAGE_welcome); break; - default: request->send_P(200, "text/html", PAGE_settings); + default: request->send_P(200, "text/html", PAGE_settings , settingsProcessor); } } diff --git a/wled00/wled21_dmx.ino b/wled00/wled21_dmx.ino new file mode 100644 index 00000000..4230f07d --- /dev/null +++ b/wled00/wled21_dmx.ino @@ -0,0 +1,55 @@ +/* + * 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