diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index e30be759b6..4e0a5ce4bd 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -736,11 +736,15 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { CJSON(DMXStartLED,dmx[F("start-led")]); JsonArray dmx_fixmap = dmx[F("fixmap")]; - for (int i = 0; i < dmx_fixmap.size(); i++) { - if (i > 14) break; + for (int i = 0; i < MIN(dmx_fixmap.size(), WLED_DMX_MAX_CHANNELS_PER_FIXTURE); i++) { CJSON(DMXFixtureMap[i],dmx_fixmap[i]); } + JsonArray dmx_chsval = dmx[F("chsval")]; + for (int i = 0; i < MIN(dmx_chsval.size(), WLED_DMX_MAX_CHANNELS_PER_FIXTURE); i++) { + CJSON(DMXChannelsValue[i],dmx_chsval[i]); + } + CJSON(e131ProxyUniverse, dmx[F("e131proxy")]); #endif @@ -1237,10 +1241,15 @@ void serializeConfig(JsonObject root) { dmx[F("start-led")] = DMXStartLED; JsonArray dmx_fixmap = dmx.createNestedArray(F("fixmap")); - for (unsigned i = 0; i < 15; i++) { + for (unsigned i = 0; i < WLED_DMX_MAX_CHANNELS_PER_FIXTURE; i++) { dmx_fixmap.add(DMXFixtureMap[i]); } + JsonArray dmx_chsval = dmx.createNestedArray(F("chsval")); + for (unsigned i = 0; i < WLED_DMX_MAX_CHANNELS_PER_FIXTURE; i++) { + dmx_chsval.add(DMXChannelsValue[i]); + } + dmx[F("e131proxy")] = e131ProxyUniverse; #endif diff --git a/wled00/const.h b/wled00/const.h index 6d1825d574..e4f5b70c6e 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -686,4 +686,6 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit"); #define WLED_O2_ATTR __attribute__((optimize("O2"))) +#define WLED_DMX_MAX_CHANNELS_PER_FIXTURE 15 + #endif diff --git a/wled00/data/settings_dmx.htm b/wled00/data/settings_dmx.htm index 391c2bdc97..24955ff1d2 100644 --- a/wled00/data/settings_dmx.htm +++ b/wled00/data/settings_dmx.htm @@ -15,10 +15,20 @@ document.head.appendChild(l); })(); function HW(){window.open("https://kno.wled.ge/interfaces/dmx-output/");} - function GCH(num) { + function GCH(num){ gId('dmxchannels').innerHTML += ""; for (i=0;iChannel " + (i+1) + ":
\n"; + gId('dmxchannels').innerHTML += "Channel " + (i+1) + ":
\n"; + } + for (i=0;i { + if (event.target.value == 0) { + dv.style.display = "inline"; + } else { + dv.style.display = "none"; + } + }); } } function mMap(){ @@ -30,14 +40,17 @@ gId("gapwarning").style.display="none"; } for (i=0;i<15;i++) { + const ch = gId("CH" + (i+1)); if (i>=numCh) { gId("CH"+(i+1) + "s").style.opacity = "0.5"; - gId("CH"+(i+1)).disabled = true; - + ch.disabled = true; + gId("DV"+(i+1)).disabled = true; } else { gId("CH"+(i+1) + "s").style.opacity = "1"; - gId("CH"+(i+1)).disabled = false; + ch.disabled = false; + gId("DV"+(i+1)).disabled = false; } + ch.dispatchEvent(new Event("change")); } } function S(){ diff --git a/wled00/dmx_output.cpp b/wled00/dmx_output.cpp index eace2145e6..28a83662e1 100644 --- a/wled00/dmx_output.cpp +++ b/wled00/dmx_output.cpp @@ -40,8 +40,8 @@ void handleDMXOutput() 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); + case 0: // Set this channel to the selected value (custom DV per channel). + dmx.write(DMXAddr, DMXChannelsValue[j]); break; case 1: // Red dmx.write(DMXAddr, calc_brightness ? (r * brightness) / 255 : r); @@ -58,7 +58,7 @@ void handleDMXOutput() case 5: // Shutter channel. Controls the brightness. dmx.write(DMXAddr, brightness); break; - case 6: // Sets this channel to 255. Like 0, but more wholesome. + case 6: // Legacy: "Set to 255" (pre-custom DV). Keep for backward-compatibility. dmx.write(DMXAddr, 255); break; } diff --git a/wled00/set.cpp b/wled00/set.cpp index db8b30bac8..5df81de468 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -640,11 +640,16 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) if (t>=0 && t < MAX_LEDS) { DMXStartLED = t; } - for (int i=0; i<15; i++) { + for (int i=0; iarg(argname).toInt(); DMXFixtureMap[i] = t; } + for (int i=0; iarg(argname).toInt(); + DMXChannelsValue[i] = constrain(t, 0, 255); + } } #endif diff --git a/wled00/wled.h b/wled00/wled.h index 66b33740d6..d3ab346be7 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -462,7 +462,8 @@ WLED_GLOBAL bool arlsForceMaxBri _INIT(false); // enable to f WLED_GLOBAL uint16_t e131ProxyUniverse _INIT(0); // output this E1.31 (sACN) / ArtNet universe via MAX485 (0 = disabled) // dmx CONFIG WLED_GLOBAL byte DMXChannels _INIT(7); // number of channels per fixture - WLED_GLOBAL byte DMXFixtureMap[15] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 })); + WLED_GLOBAL byte DMXFixtureMap[WLED_DMX_MAX_CHANNELS_PER_FIXTURE] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 })); + WLED_GLOBAL byte DMXChannelsValue[WLED_DMX_MAX_CHANNELS_PER_FIXTURE] _INIT_N(({ 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. WLED_GLOBAL uint16_t DMXGap _INIT(10); // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. WLED_GLOBAL uint16_t DMXStart _INIT(10); // start address of the first fixture diff --git a/wled00/wled_server.cpp b/wled00/wled_server.cpp index ffb259b858..a170ae6b65 100644 --- a/wled00/wled_server.cpp +++ b/wled00/wled_server.cpp @@ -1,7 +1,7 @@ #include "wled.h" #ifndef WLED_DISABLE_OTA - #include "ota_update.h" + #include "ota_update.h" #endif #include "html_ui.h" #include "html_settings.h" @@ -144,10 +144,15 @@ static String dmxProcessor(const String& var) mapJS += F(";\nLC="); mapJS += String(strip.getLengthTotal()); mapJS += F(";\nvar CH=["); - for (int i=0; i<15; i++) { + for (int i=0; iclient()->remoteIP(); - if (((otaSameSubnet && !inSameSubnet(client)) && !strlen(settingsPIN)) || (!otaSameSubnet && !inLocalSubnet(client))) { + if (((otaSameSubnet && !inSameSubnet(client)) && !strlen(settingsPIN)) || (!otaSameSubnet && !inLocalSubnet(client))) { DEBUG_PRINTLN(F("Attempted OTA update from different/non-local subnet!")); serveMessage(request, 401, FPSTR(s_accessdenied), F("Client is not on local subnet."), 254); setOTAReplied(request); @@ -525,7 +530,7 @@ void initServer() serveMessage(request, 401, FPSTR(s_accessdenied), FPSTR(s_unlock_ota), 254); setOTAReplied(request); return; - } + } } handleOTAData(request, index, data, len, isFinal); @@ -693,7 +698,7 @@ void serveSettingsJS(AsyncWebServerRequest* request) request->send_P(401, FPSTR(CONTENT_TYPE_JAVASCRIPT), PSTR("alert('PIN incorrect.');")); return; } - + AsyncResponseStream *response = request->beginResponseStream(FPSTR(CONTENT_TYPE_JAVASCRIPT)); response->addHeader(FPSTR(s_cache_control), FPSTR(s_no_store)); response->addHeader(FPSTR(s_expires), F("0")); diff --git a/wled00/xml.cpp b/wled00/xml.cpp index 194256d82e..63e239fa41 100644 --- a/wled00/xml.cpp +++ b/wled00/xml.cpp @@ -413,7 +413,7 @@ void getSettingsJS(byte subPage, Print& settingsScript) #ifndef WLED_DISABLE_INFRARED printSetFormValue(settingsScript,PSTR("IR"),irPin); printSetFormValue(settingsScript,PSTR("IT"),irEnabled); -#endif +#endif printSetFormCheckbox(settingsScript,PSTR("MSO"),!irApplyToAllSelected); } @@ -637,21 +637,17 @@ void getSettingsJS(byte subPage, Print& settingsScript) printSetFormValue(settingsScript,PSTR("CS"),DMXStart); printSetFormValue(settingsScript,PSTR("SL"),DMXStartLED); - printSetFormIndex(settingsScript,PSTR("CH1"),DMXFixtureMap[0]); - printSetFormIndex(settingsScript,PSTR("CH2"),DMXFixtureMap[1]); - printSetFormIndex(settingsScript,PSTR("CH3"),DMXFixtureMap[2]); - printSetFormIndex(settingsScript,PSTR("CH4"),DMXFixtureMap[3]); - printSetFormIndex(settingsScript,PSTR("CH5"),DMXFixtureMap[4]); - printSetFormIndex(settingsScript,PSTR("CH6"),DMXFixtureMap[5]); - printSetFormIndex(settingsScript,PSTR("CH7"),DMXFixtureMap[6]); - printSetFormIndex(settingsScript,PSTR("CH8"),DMXFixtureMap[7]); - printSetFormIndex(settingsScript,PSTR("CH9"),DMXFixtureMap[8]); - printSetFormIndex(settingsScript,PSTR("CH10"),DMXFixtureMap[9]); - printSetFormIndex(settingsScript,PSTR("CH11"),DMXFixtureMap[10]); - printSetFormIndex(settingsScript,PSTR("CH12"),DMXFixtureMap[11]); - printSetFormIndex(settingsScript,PSTR("CH13"),DMXFixtureMap[12]); - printSetFormIndex(settingsScript,PSTR("CH14"),DMXFixtureMap[13]); - printSetFormIndex(settingsScript,PSTR("CH15"),DMXFixtureMap[14]); + for (int i = 0; i < WLED_DMX_MAX_CHANNELS_PER_FIXTURE; i++) { + char buf[5]; + snprintf_P(buf, sizeof(buf), PSTR("CH%d"), i+1); + printSetFormIndex(settingsScript,buf,DMXFixtureMap[i]); + } + + for (int i = 0; i < WLED_DMX_MAX_CHANNELS_PER_FIXTURE; i++) { + char buf[5]; + snprintf_P(buf, sizeof(buf), PSTR("DV%d"), i+1); + printSetFormValue(settingsScript,buf,DMXChannelsValue[i]); + } } #endif