This commit is contained in:
cschwinne 2020-02-24 12:45:47 +01:00
commit 5ffd29e31a
10 changed files with 433 additions and 100 deletions

View File

@ -15,6 +15,36 @@ const char PAGE_msg[] PROGMEM = R"=====(<!DOCTYPE html>
<style>.bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}</style></head> <style>.bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}</style></head>
<body><h2>%MSG%</body></html>)====="; <body><h2>%MSG%</body></html>)=====";
//DMX channel map
const char PAGE_dmxmap[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><meta content='width=device-width' name='viewport'>
<title>DMX Map</title>
<script>function B(){window.history.back()};function RS(){window.location = "/settings";}function RP(){top.location.href="/";}function FM() {%DMXVARS%
var dmxlabels = ["SET 0","RED","GREEN","BLUE","WHITE","SHUTTER","SET 255", "DISABLED"];
var dmxchans = [];
for (i=0;i<512;i++) {
dmxchans.push(7); // set all to DISABLED
}
for (i=0;i<LC;i++) {
FS = CS + (CG * i);
for (j=0;j<CN;j++) {
DA=FS+j;
dmxchans[DA-1] = CH[j];
}
}
DMXMap = "";
for (i=0;i<512;i++) {
isstart = "";
if ((i+1) % 10 == 0) {
isstart="S"
}
DMXMap += "<div class=\"anytype " + isstart + " type" + dmxchans[i] + "\">" + String(i+1) + "<br />" + dmxlabels[dmxchans[i]] + "</div>";
}
document.getElementById("map").innerHTML = DMXMap;
}</script>
<style>.anytype{border: 1px solid white; margin: 1px; float: left; width: 100px; height: 100px;}.S { margin: 0px; border: 2px solid white;} .type7{color: #888; border: 1px dotted grey;}.type6{color: #FFF;}.type4{color: #FFF; font-weight: bold; }.type3{color: #00F; font-weight: bold; }.type2{color: #0F0; font-weight: bold; }.type1{color: #F00; font-weight: bold; } .bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}</style></head>
<body onload="FM();"><div id="map">...</div></body></html>)=====";
//firmware update page //firmware update page
const char PAGE_update[] PROGMEM = R"=====(<!DOCTYPE html> const char PAGE_update[] PROGMEM = R"=====(<!DOCTYPE html>

View File

@ -1,23 +1,23 @@
/* /*
* Settings html Settings html
*/ */
//common CSS of settings pages //common CSS of settings pages
const char PAGE_settingsCss[] PROGMEM = R"=====(<style>body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}hr{border-color:#666}button{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}.helpB{text-align:left;position:absolute;width:60px}input{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}input[type=number]{width:4em}select{background:#333;color:#fff;font-family:Verdana,sans-serif;border:0.5ch solid #333}td{padding:2px;}</style>)====="; const char PAGE_settingsCss[] PROGMEM = R"=====(<style>body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}hr{border-color:#666}button{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}.helpB{text-align:left;position:absolute;width:60px}input{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}input[type=number]{width:4em}select{background:#333;color:#fff;font-family:Verdana,sans-serif;border:0.5ch solid #333}td{padding:2px;}</style>)=====";
//settings menu //settings menu
const char PAGE_settings[] PROGMEM = R"=====(<!DOCTYPE html> const char PAGE_settings[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><title>WLED Settings</title><style>body{text-align:center;background:#222;height:100%;margin:0}html{--h:11.55vh}button{background:#333;color:#fff;font-family:Verdana,Helvetica,sans-serif;border:.3ch solid #333;display:inline-block;font-size:8vmin;height:var(--h);width:95%;margin-top:2.4vh}</style> <html><head><title>WLED Settings</title><style>body{text-align:center;background:#222;height:100%%;margin:0}html{--h:11.55vh}button{background:#333;color:#fff;font-family:Verdana,Helvetica,sans-serif;border:.3ch solid #333;display:inline-block;font-size:8vmin;height:var(--h);width:95%%;margin-top:2.4vh}</style>
<script>function BB(){if(window.frameElement){document.getElementById("b").style.display="none";document.documentElement.style.setProperty("--h","13.86vh")}};</script></head> <script>function BB(){if(window.frameElement){document.getElementById("b").style.display="none";document.documentElement.style.setProperty("--h","13.86vh")}};</script></head>
<body onload=BB()> <body onload=BB()>
<form action=/><button type=submit id=b>Back</button></form> <form action=/><button type=submit id=b>Back</button></form>
<form action=/settings/wifi><button type=submit>WiFi Setup</button></form> <form action=/settings/wifi><button type=submit>WiFi Setup</button></form>
<form action=/settings/leds><button type=submit>LED Preferences</button></form> <form action=/settings/leds><button type=submit>LED Preferences</button></form>
<form action=/settings/ui><button type=submit>User Interface</button></form> <form action=/settings/ui><button type=submit>User Interface</button></form>%DMXMENU%
<form action=/settings/sync><button type=submit>Sync Interfaces</button></form> <form action=/settings/sync><button type=submit>Sync Interfaces</button></form>
<form action=/settings/time><button type=submit>Time & Macros</button></form> <form action=/settings/time><button type=submit>Time & Macros</button></form>
<form action=/settings/sec><button type=submit>Security & Updates</button></form> <form action=/settings/sec><button type=submit>Security & Updates</button></form>
</body></html>)====="; </body></html>)=====";
@ -172,6 +172,64 @@ Skip first LED: <input type=checkbox name=SL><hr>
</form></body></html>)====="; </form></body></html>)=====";
#ifdef WLED_ENABLE_DMX
//DMX Output settings
const char PAGE_settings_dmx[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>DMX Settings</title><script>
function GCH(num) {
d=document;
d.getElementById('dmxchannels').innerHTML += "";
for (i=0;i<num;i++) {
d.getElementById('dmxchannels').innerHTML += "<span id=CH" + (i+1) + "s >Channel " + (i+1) + ": <select name=CH" + (i+1) + " id=\"CH" + (i+1) + "\"><option value=0>Set to 0</option><option value=1>Red</option><option value=2>Green</option><option value=3>Blue</option><option value=4>White</option><option value=5>Shutter (Brightness)</option><option value=6>Set to 255</option></select></span><br />\n";
}
}
function mMap(){
d=document;
numCh=document.Sf.CN.value;
numGap=document.Sf.CG.value;
if (parseInt(numCh)>parseInt(numGap)) {
d.getElementById("gapwarning").style.display="block";
} else {
d.getElementById("gapwarning").style.display="none";
}
for (i=0;i<15;i++) {
if (i>=numCh) {
d.getElementById("CH"+(i+1) + "s").style.opacity = "0.5";
d.getElementById("CH"+(i+1)).disabled = true;
} else {
d.getElementById("CH"+(i+1) + "s").style.opacity = "1";
d.getElementById("CH"+(i+1)).disabled = false;
}
}
}
function S(){GCH(15);GetV();mMap();}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/DMX");}function B(){window.history.back();}function GetV(){var d=document;
%CSS%%SCSS%</head>
<body onload="S()">
<form id="form_s" name="Sf" method="post">
<div class="helpB"><button type="button" onclick="H()">?</button></div>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
<h2>Imma firin ma lazer (if it has DMX support)</h2><!-- TODO: Change to something less-meme-related //-->
<i>Number of fixtures is taken from LED config page</i><br>
channels per fixture (15 max): <input type="number" min="1" max="15" name="CN" maxlength="2" onchange="mMap();"><br />
start channel: <input type="number" min="1" max="512" name="CS" maxlength="2"><br />
spacing between start channels: <input type="number" min="1" max="512" name="CG" maxlength="2" onchange="mMap();"> [ <a href="javascript:alert('if set to 10, first fixture will start at 10,\nsecond will start at 20 etc.\nRegardless of the channel count.\nMakes memorizing channel numbers easier.');">info</a> ]<br>
<div id="gapwarning" style="color: orange; display: none;">WARNING: Channel gap is lower than channels per fixture.<br />This will cause overlap.</div>
<button type="button" onclick="location.href='/dmxmap';">DMX Map</button>
<h3>channel functions</h3>
<div id="dmxchannels"></div>
<hr><button type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form>
</body>
</html>)=====";
#else
const char PAGE_settings_dmx[] PROGMEM = R"=====()=====";
#endif
//User Interface settings //User Interface settings
const char PAGE_settings_ui[] PROGMEM = R"=====(<!DOCTYPE html> const char PAGE_settings_ui[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>UI Settings</title><script> <html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>UI Settings</title><script>
@ -190,6 +248,7 @@ Sync button toggles both send and receive: <input type="checkbox" name="ST"><br>
</html>)====="; </html>)=====";
//sync settings //sync settings
const char PAGE_settings_sync[] PROGMEM = R"=====(<!DOCTYPE html> const char PAGE_settings_sync[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>Sync Settings</title> <html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>Sync Settings</title>

View File

@ -1,5 +1,5 @@
/* /*
* Main sketch, global variable declarations Main sketch, global variable declarations
*/ */
/* /*
* @title WLED project sketch * @title WLED project sketch
@ -24,6 +24,7 @@
//#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01, saves 12kb //#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_MQTT //saves 12kb
#define WLED_ENABLE_ADALIGHT //saves 500b only #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_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_SERVING //Enable sending html file from SPIFFS before serving progmem version
@ -34,6 +35,10 @@
//library inclusions //library inclusions
#include <Arduino.h> #include <Arduino.h>
#ifdef WLED_ENABLE_DMX
#include <ESPDMX.h>
DMXESPSerial dmx;
#endif
#ifdef ESP8266 #ifdef ESP8266
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <ESP8266mDNS.h> #include <ESP8266mDNS.h>
@ -106,7 +111,7 @@
#endif #endif
//version code in format yymmddb (b = daily build) //version code in format yymmddb (b = daily build)
#define VERSION 2002222 #define VERSION 2002241
char versionString[] = "0.9.1"; char versionString[] = "0.9.1";
@ -257,6 +262,14 @@ bool aOtaEnabled = true; //ArduinoOTA allows easy updates d
uint16_t userVar0 = 0, userVar1 = 0; uint16_t userVar0 = 0, userVar1 = 0;
//dmx CONFIG
uint16_t DMXChannels = 7; // number of channels per fixture
uint16_t 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
//internal global variable declarations //internal global variable declarations
//wifi //wifi
@ -480,6 +493,8 @@ WS2812FX strip = WS2812FX();
#include "SPIFFSEditor.h" #include "SPIFFSEditor.h"
#endif #endif
//turns all LEDs off and restarts ESP //turns all LEDs off and restarts ESP
void reset() void reset()
{ {
@ -517,6 +532,8 @@ bool oappendi(int i)
//boot starts here //boot starts here
void setup() { void setup() {
wledInit(); wledInit();
} }
@ -528,6 +545,7 @@ void loop() {
handleSerial(); handleSerial();
handleNotifications(); handleNotifications();
handleTransitions(); handleTransitions();
handleDMX();
userLoop(); userLoop();
yield(); yield();

View File

@ -6,7 +6,7 @@
#define EEPSIZE 2560 //Maximum is 4096 #define EEPSIZE 2560 //Maximum is 4096
//eeprom Version code, enables default settings instead of 0 init on update //eeprom Version code, enables default settings instead of 0 init on update
#define EEPVER 16 #define EEPVER 17
//0 -> old version, default //0 -> old version, default
//1 -> 0.4p 1711272 and up //1 -> 0.4p 1711272 and up
//2 -> 0.4p 1711302 and up //2 -> 0.4p 1711302 and up
@ -24,6 +24,7 @@
//14-> 0.9.0-b1 //14-> 0.9.0-b1
//15-> 0.9.0-b3 //15-> 0.9.0-b3
//16-> 0.9.1 //16-> 0.9.1
//17-> 0.9.1-dmx
void commit() void commit()
{ {
@ -63,7 +64,6 @@ void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len)
str[len] = 0; //make sure every string is properly terminated. str must be at least len +1 big. str[len] = 0; //make sure every string is properly terminated. str must be at least len +1 big.
} }
/* /*
* Write configuration to flash * Write configuration to flash
*/ */
@ -257,6 +257,17 @@ void saveSettingsToEEPROM()
EEPROM.write(2522, mqttPort & 0xFF); EEPROM.write(2522, mqttPort & 0xFF);
EEPROM.write(2523, (mqttPort >> 8) & 0xFF); EEPROM.write(2523, (mqttPort >> 8) & 0xFF);
// DMX (2530 - 2549)
EEPROM.write(2530, DMXChannels);
EEPROM.write(2531, DMXGap & 0xFF);
EEPROM.write(2532, (DMXGap >> 8) & 0xFF);
EEPROM.write(2533, DMXStart & 0xFF);
EEPROM.write(2534, (DMXStart >> 8) & 0xFF);
for (int i=0;i<15;i++) {
EEPROM.write(2535+i, DMXFixtureMap[i]);
} // last used: 2549. maybe leave a few bytes for future expansion and go on with 2600 kthxbye.
commit(); commit();
} }
@ -525,6 +536,17 @@ void loadSettingsFromEEPROM(bool first)
readStringFromEEPROM(2220, blynkApiKey, 35); readStringFromEEPROM(2220, blynkApiKey, 35);
if (strlen(blynkApiKey) < 25) blynkApiKey[0] = 0; if (strlen(blynkApiKey) < 25) blynkApiKey[0] = 0;
// DMX (2530 - 2549)2535
DMXChannels = EEPROM.read(2530);
DMXGap = EEPROM.read(2531) + ((EEPROM.read(2532) << 8) & 0xFF00);
DMXStart = EEPROM.read(2533) + ((EEPROM.read(2534) << 8) & 0xFF00);
for (int i=0;i<15;i++) {
DMXFixtureMap[i] = EEPROM.read(2535+i);
} //last used: 2549. maybe leave a few bytes for future expansion and go on with 2600 kthxbye.
//user MOD memory //user MOD memory
//2944 - 3071 reserved //2944 - 3071 reserved

View File

@ -99,6 +99,53 @@ char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr)
if (request != nullptr) request->send(200, "text/xml", obuf); if (request != nullptr) request->send(200, "text/xml", obuf);
} }
char* URL_response(AsyncWebServerRequest *request)
{
char sbuf[256]; //allocate local buffer if none passed
char s2buf[100];
obuf = s2buf;
olen = 0;
char s[16];
oappend("http://");
IPAddress localIP = WiFi.localIP();
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
oappend(s);
oappend("/win&A=");
oappendi(bri);
oappend("&CL=h");
for (int i = 0; i < 3; i++)
{
sprintf(s,"%02X", col[i]);
oappend(s);
}
oappend("&C2=h");
for (int i = 0; i < 3; i++)
{
sprintf(s,"%02X", colSec[i]);
oappend(s);
}
oappend("&FX=");
oappendi(effectCurrent);
oappend("&SX=");
oappendi(effectSpeed);
oappend("&IX=");
oappendi(effectIntensity);
oappend("&FP=");
oappendi(effectPalette);
obuf = sbuf;
olen = 0;
oappend("<html><body><a href=\"");
oappend(s2buf);
oappend("\" target=\"_blank\">");
oappend(s2buf);
oappend("</a></body></html>");
if (request != nullptr) request->send(200, "text/html", obuf);
}
//append a numeric setting to string buffer //append a numeric setting to string buffer
void sappend(char stype, const char* key, int val) void sappend(char stype, const char* key, int val)
{ {
@ -162,7 +209,7 @@ void getSettingsJS(byte subPage, char* dest)
obuf = dest; obuf = dest;
olen = 0; olen = 0;
if (subPage <1 || subPage >6) return; if (subPage <1 || subPage >7) return;
if (subPage == 1) { if (subPage == 1) {
sappends('s',"CS",clientSSID); sappends('s',"CS",clientSSID);
@ -391,5 +438,30 @@ void getSettingsJS(byte subPage, char* dest)
oappendi(VERSION); oappendi(VERSION);
oappend(") OK\";"); oappend(") OK\";");
} }
#ifdef WLED_ENABLE_DMX // include only if DMX is enabled
if (subPage == 7)
{
sappend('v',"CN",DMXChannels);
sappend('v',"CG",DMXGap);
sappend('v',"CS",DMXStart);
sappend('i',"CH1",DMXFixtureMap[0]);
sappend('i',"CH2",DMXFixtureMap[1]);
sappend('i',"CH3",DMXFixtureMap[2]);
sappend('i',"CH4",DMXFixtureMap[3]);
sappend('i',"CH5",DMXFixtureMap[4]);
sappend('i',"CH6",DMXFixtureMap[5]);
sappend('i',"CH7",DMXFixtureMap[6]);
sappend('i',"CH8",DMXFixtureMap[7]);
sappend('i',"CH9",DMXFixtureMap[8]);
sappend('i',"CH10",DMXFixtureMap[9]);
sappend('i',"CH11",DMXFixtureMap[10]);
sappend('i',"CH12",DMXFixtureMap[11]);
sappend('i',"CH13",DMXFixtureMap[12]);
sappend('i',"CH14",DMXFixtureMap[13]);
sappend('i',"CH15",DMXFixtureMap[14]);
}
#endif
oappend("}</script>"); oappend("}</script>");
} }

View File

@ -27,8 +27,9 @@ bool isAsterisksOnly(const char* str, byte maxLen)
//called upon POST settings form submit //called upon POST settings form submit
void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) 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 //WIFI SETTINGS
if (subPage == 1) if (subPage == 1)
@ -293,6 +294,29 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
aOtaEnabled = request->hasArg("AO"); 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 != 6 || !doReboot) saveSettingsToEEPROM(); //do not save if factory reset
if (subPage == 2) { if (subPage == 2) {
strip.init(useRGBW,ledCount,skipFirstLed); strip.init(useRGBW,ledCount,skipFirstLed);

View File

@ -83,7 +83,9 @@ void wledInit()
if (strlen(cmDNS) > 0) ArduinoOTA.setHostname(cmDNS); if (strlen(cmDNS) > 0) ArduinoOTA.setHostname(cmDNS);
} }
#endif #endif
#ifdef WLED_ENABLE_DMX
dmx.init(512); // initialize with bus length
#endif
//HTTP server page init //HTTP server page init
initServer(); initServer();
} }

View File

@ -231,7 +231,7 @@ void handleNightlight()
nightlightDelayMs = (int)(nightlightDelayMins*60000); nightlightDelayMs = (int)(nightlightDelayMins*60000);
nightlightActiveOld = true; nightlightActiveOld = true;
briNlT = bri; 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); float nper = (millis() - nightlightStartTime)/((float)nightlightDelayMs);
if (nightlightFade) if (nightlightFade)
@ -239,7 +239,7 @@ void handleNightlight()
bri = briNlT + ((nightlightTargetBri - briNlT)*nper); 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); colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY);
} }

View File

@ -82,6 +82,11 @@ void initServer()
serveMessage(request, 200,"UI settings saved.","Redirecting...",1); 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){ server.on("/settings/sync", HTTP_POST, [](AsyncWebServerRequest *request){
handleSettingsSet(request, 4); handleSettingsSet(request, 4);
serveMessage(request, 200,"Sync settings saved.","Redirecting...",1); serveMessage(request, 200,"Sync settings saved.","Redirecting...",1);
@ -138,6 +143,10 @@ void initServer()
request->send_P(200, "text/html", PAGE_usermod); request->send_P(200, "text/html", PAGE_usermod);
}); });
server.on("/url", HTTP_GET, [](AsyncWebServerRequest *request){
URL_response(request);
});
server.on("/teapot", HTTP_GET, [](AsyncWebServerRequest *request){ server.on("/teapot", HTTP_GET, [](AsyncWebServerRequest *request){
serveMessage(request, 418, "418. I'm a teapot.", "(Tangible Embedded Advanced Project Of Twinkling)", 254); serveMessage(request, 418, "418. I'm a teapot.", "(Tangible Embedded Advanced Project Of Twinkling)", 254);
}); });
@ -201,6 +210,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){ server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
if (captivePortal(request)) return; if (captivePortal(request)) return;
serveIndexOrWelcome(request); serveIndexOrWelcome(request);
@ -301,10 +320,38 @@ String settingsProcessor(const String& var)
getSettingsJS(optionType, buf); getSettingsJS(optionType, buf);
return String(buf); return String(buf);
} }
#ifdef WLED_ENABLE_DMX
if (var == "DMXMENU") {
return String("<form action=/settings/dmx><button type=submit>DMX Output</button></form>");
}
#endif
if (var == "SCSS") return String(FPSTR(PAGE_settingsCss)); if (var == "SCSS") return String(FPSTR(PAGE_settingsCss));
return String(); 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) void serveSettings(AsyncWebServerRequest* request)
{ {
@ -318,6 +365,9 @@ void serveSettings(AsyncWebServerRequest* request)
else if (url.indexOf("sync") > 0) subPage = 4; else if (url.indexOf("sync") > 0) subPage = 4;
else if (url.indexOf("time") > 0) subPage = 5; else if (url.indexOf("time") > 0) subPage = 5;
else if (url.indexOf("sec") > 0) subPage = 6; 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 } else subPage = 255; //welcome page
if (subPage == 1 && wifiLock && otaLock) if (subPage == 1 && wifiLock && otaLock)
@ -339,7 +389,8 @@ void serveSettings(AsyncWebServerRequest* request)
case 4: request->send_P(200, "text/html", PAGE_settings_sync, settingsProcessor); break; 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 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 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; 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);
} }
} }

55
wled00/wled21_dmx.ino Normal file
View File

@ -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