Multi button implementation.
This commit is contained in:
parent
a5a25f02e3
commit
95df91a03b
@ -6,20 +6,20 @@
|
||||
|
||||
#define WLED_DEBOUNCE_THRESHOLD 50 //only consider button input of at least 50ms as valid (debouncing)
|
||||
|
||||
void shortPressAction()
|
||||
void shortPressAction(uint8_t b)
|
||||
{
|
||||
if (!macroButton)
|
||||
if (!macroButton[b])
|
||||
{
|
||||
toggleOnOff();
|
||||
colorUpdated(NOTIFIER_CALL_MODE_BUTTON);
|
||||
} else {
|
||||
applyPreset(macroButton);
|
||||
applyPreset(macroButton[b]);
|
||||
}
|
||||
}
|
||||
|
||||
bool isButtonPressed()
|
||||
bool isButtonPressed(uint8_t i)
|
||||
{
|
||||
if (btnPin>=0 && digitalRead(btnPin) == LOW) return true;
|
||||
if (btnPin[i]>=0 && digitalRead(btnPin[i]) == LOW) return true;
|
||||
#ifdef TOUCHPIN
|
||||
if (touchRead(TOUCHPIN) <= TOUCH_THRESHOLD) return true;
|
||||
#endif
|
||||
@ -27,84 +27,86 @@ bool isButtonPressed()
|
||||
}
|
||||
|
||||
|
||||
void handleSwitch()
|
||||
void handleSwitch(uint8_t b)
|
||||
{
|
||||
if (buttonPressedBefore != isButtonPressed()) {
|
||||
buttonPressedTime = millis();
|
||||
buttonPressedBefore = !buttonPressedBefore;
|
||||
if (buttonPressedBefore[b] != isButtonPressed(b)) {
|
||||
buttonPressedTime[b] = millis();
|
||||
buttonPressedBefore[b] = !buttonPressedBefore[b];
|
||||
}
|
||||
|
||||
if (buttonLongPressed == buttonPressedBefore) return;
|
||||
if (buttonLongPressed[b] == buttonPressedBefore[b]) return;
|
||||
|
||||
if (millis() - buttonPressedTime > WLED_DEBOUNCE_THRESHOLD) { //fire edge event only after 50ms without change (debounce)
|
||||
if (buttonPressedBefore) { //LOW, falling edge, switch closed
|
||||
if (macroButton) applyPreset(macroButton);
|
||||
if (millis() - buttonPressedTime[b] > WLED_DEBOUNCE_THRESHOLD) { //fire edge event only after 50ms without change (debounce)
|
||||
if (buttonPressedBefore[b]) { //LOW, falling edge, switch closed
|
||||
if (macroButton[b]) applyPreset(macroButton[b]);
|
||||
else { //turn on
|
||||
if (!bri) {toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);}
|
||||
}
|
||||
} else { //HIGH, rising edge, switch opened
|
||||
if (macroLongPress) applyPreset(macroLongPress);
|
||||
if (macroLongPress[b]) applyPreset(macroLongPress[b]);
|
||||
else { //turn off
|
||||
if (bri) {toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);}
|
||||
}
|
||||
}
|
||||
buttonLongPressed = buttonPressedBefore; //save the last "long term" switch state
|
||||
buttonLongPressed[b] = buttonPressedBefore[b]; //save the last "long term" switch state
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void handleButton()
|
||||
{
|
||||
if (btnPin<0 || buttonType < BTN_TYPE_PUSH) return;
|
||||
for (uint8_t b=0; b<WLED_MAX_BUTTONS; b++) {
|
||||
if (btnPin[b]<0 || !(buttonType[b] > BTN_TYPE_NONE)) continue;
|
||||
|
||||
|
||||
if (buttonType == BTN_TYPE_SWITCH) { //button is not momentary, but switch. This is only suitable on pins whose on-boot state does not matter (NO gpio0)
|
||||
handleSwitch(); return;
|
||||
}
|
||||
if (buttonType[b] == BTN_TYPE_SWITCH) { //button is not momentary, but switch. This is only suitable on pins whose on-boot state does not matter (NOT gpio0)
|
||||
handleSwitch(b); continue;
|
||||
}
|
||||
|
||||
//momentary button logic
|
||||
if (isButtonPressed()) //pressed
|
||||
{
|
||||
if (!buttonPressedBefore) buttonPressedTime = millis();
|
||||
buttonPressedBefore = true;
|
||||
|
||||
if (millis() - buttonPressedTime > 600) //long press
|
||||
//momentary button logic
|
||||
if (isButtonPressed(b)) //pressed
|
||||
{
|
||||
if (!buttonLongPressed)
|
||||
{
|
||||
if (macroLongPress) {applyPreset(macroLongPress);}
|
||||
else _setRandomColor(false,true);
|
||||
if (!buttonPressedBefore[b]) buttonPressedTime[b] = millis();
|
||||
buttonPressedBefore[b] = true;
|
||||
|
||||
buttonLongPressed = true;
|
||||
if (millis() - buttonPressedTime[b] > 600) //long press
|
||||
{
|
||||
if (!buttonLongPressed[b])
|
||||
{
|
||||
if (macroLongPress[b]) {applyPreset(macroLongPress[b]);}
|
||||
else _setRandomColor(false,true);
|
||||
|
||||
buttonLongPressed[b] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!isButtonPressed() && buttonPressedBefore) //released
|
||||
{
|
||||
long dur = millis() - buttonPressedTime;
|
||||
if (dur < WLED_DEBOUNCE_THRESHOLD) {buttonPressedBefore = false; return;} //too short "press", debounce
|
||||
bool doublePress = buttonWaitTime;
|
||||
buttonWaitTime = 0;
|
||||
|
||||
if (dur > 6000) //long press
|
||||
else if (!isButtonPressed(b) && buttonPressedBefore[b]) //released
|
||||
{
|
||||
WLED::instance().initAP(true);
|
||||
}
|
||||
else if (!buttonLongPressed) { //short press
|
||||
if (macroDoublePress)
|
||||
{
|
||||
if (doublePress) applyPreset(macroDoublePress);
|
||||
else buttonWaitTime = millis();
|
||||
} else shortPressAction();
|
||||
}
|
||||
buttonPressedBefore = false;
|
||||
buttonLongPressed = false;
|
||||
}
|
||||
long dur = millis() - buttonPressedTime[b];
|
||||
if (dur < WLED_DEBOUNCE_THRESHOLD) {buttonPressedBefore[b] = false; continue;} //too short "press", debounce
|
||||
bool doublePress = buttonWaitTime[b];
|
||||
buttonWaitTime[b] = 0;
|
||||
|
||||
if (buttonWaitTime && millis() - buttonWaitTime > 450 && !buttonPressedBefore)
|
||||
{
|
||||
buttonWaitTime = 0;
|
||||
shortPressAction();
|
||||
if (dur > 6000 && b==0) //long press on button 0
|
||||
{
|
||||
WLED::instance().initAP(true);
|
||||
}
|
||||
else if (!buttonLongPressed[b]) { //short press
|
||||
if (macroDoublePress[b])
|
||||
{
|
||||
if (doublePress) applyPreset(macroDoublePress[b]);
|
||||
else buttonWaitTime[b] = millis();
|
||||
} else shortPressAction(b);
|
||||
}
|
||||
buttonPressedBefore[b] = false;
|
||||
buttonLongPressed[b] = false;
|
||||
}
|
||||
|
||||
if (buttonWaitTime[b] && millis() - buttonWaitTime[b] > 450 && !buttonPressedBefore[b])
|
||||
{
|
||||
buttonWaitTime[b] = 0;
|
||||
shortPressAction(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,10 +131,41 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
if (lC > ledCount) ledCount = lC; // fix incorrect total length (honour analog setup)
|
||||
DEBUG_PRINTLN(F(" Done LEDs."));
|
||||
|
||||
// read multiple button configuration
|
||||
JsonArray hw_btn_ins = hw[F("btn")][F("ins")];
|
||||
if (!hw_btn_ins.isNull()) {
|
||||
uint8_t s = 0;
|
||||
for (JsonObject btn : hw_btn_ins) {
|
||||
CJSON(buttonType[s], btn["type"]);
|
||||
int8_t pin = btn[F("pin")][0] | -1;
|
||||
if (pin > -1) {
|
||||
if (pinManager.allocatePin(pin,false)) {
|
||||
btnPin[s] = pin;
|
||||
pinMode(btnPin[s], INPUT_PULLUP);
|
||||
} else {
|
||||
btnPin[s] = -1;
|
||||
}
|
||||
}
|
||||
JsonArray hw_btn_ins_0_macros = btn[F("macros")];
|
||||
CJSON(macroButton[s], hw_btn_ins_0_macros[0]);
|
||||
CJSON(macroLongPress[s],hw_btn_ins_0_macros[1]);
|
||||
CJSON(macroDoublePress[s], hw_btn_ins_0_macros[2]);
|
||||
if (++s >= WLED_MAX_BUTTONS) break; // max buttons reached
|
||||
}
|
||||
// clear remaining buttons
|
||||
for (; s<WLED_MAX_BUTTONS; s++) {
|
||||
btnPin[s] = -1;
|
||||
buttonType[s] = BTN_TYPE_NONE;
|
||||
macroButton[s] = 0;
|
||||
macroLongPress[s] = 0;
|
||||
macroDoublePress[s] = 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
JsonObject hw_btn_ins_0 = hw[F("btn")][F("ins")][0];
|
||||
CJSON(buttonType, hw_btn_ins_0["type"]);
|
||||
int hw_btn_pin = hw_btn_ins_0[F("pin")][0] | -2; //-2 = not present in doc, keep current. -1 = disable
|
||||
if (hw_btn_pin > -2) {
|
||||
if (hw_btn_pin > -1) {
|
||||
if (pinManager.allocatePin(hw_btn_pin,false)) {
|
||||
btnPin = hw_btn_pin;
|
||||
pinMode(btnPin, INPUT_PULLUP);
|
||||
@ -147,7 +178,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
CJSON(macroButton, hw_btn_ins_0_macros[0]);
|
||||
CJSON(macroLongPress,hw_btn_ins_0_macros[1]);
|
||||
CJSON(macroDoublePress, hw_btn_ins_0_macros[2]);
|
||||
|
||||
*/
|
||||
#ifndef WLED_DISABLE_INFRARED
|
||||
int hw_ir_pin = hw["ir"]["pin"] | -2; // 4
|
||||
if (hw_ir_pin > -2) {
|
||||
@ -509,21 +540,28 @@ void serializeConfig() {
|
||||
ins[F("rgbw")] = bus->isRgbw();
|
||||
}
|
||||
|
||||
// button(s)
|
||||
JsonObject hw_btn = hw.createNestedObject("btn");
|
||||
|
||||
JsonArray hw_btn_ins = hw_btn.createNestedArray("ins");
|
||||
|
||||
// button BTNPIN
|
||||
JsonObject hw_btn_ins_0 = hw_btn_ins.createNestedObject();
|
||||
hw_btn_ins_0["type"] = buttonType;
|
||||
|
||||
hw_btn_ins_0["type"] = buttonType[0];
|
||||
JsonArray hw_btn_ins_0_pin = hw_btn_ins_0.createNestedArray("pin");
|
||||
hw_btn_ins_0_pin.add(btnPin);
|
||||
hw_btn_ins_0_pin.add(btnPin[0]);
|
||||
|
||||
JsonArray hw_btn_ins_0_macros = hw_btn_ins_0.createNestedArray("macros");
|
||||
hw_btn_ins_0_macros.add(macroButton);
|
||||
hw_btn_ins_0_macros.add(macroLongPress);
|
||||
hw_btn_ins_0_macros.add(macroDoublePress);
|
||||
// additional buttons
|
||||
for (uint8_t i=1; i<WLED_MAX_BUTTONS; i++) {
|
||||
if (btnPin[i]<0) continue;
|
||||
JsonObject hw_btn_ins_0 = hw_btn_ins.createNestedObject();
|
||||
hw_btn_ins_0["type"] = buttonType[i];
|
||||
JsonArray hw_btn_ins_0_pin = hw_btn_ins_0.createNestedArray("pin");
|
||||
hw_btn_ins_0_pin.add(btnPin[i]);
|
||||
|
||||
JsonArray hw_btn_ins_0_macros = hw_btn_ins_0.createNestedArray("macros");
|
||||
hw_btn_ins_0_macros.add(macroButton[i]);
|
||||
hw_btn_ins_0_macros.add(macroLongPress[i]);
|
||||
hw_btn_ins_0_macros.add(macroDoublePress[i]);
|
||||
}
|
||||
|
||||
JsonObject hw_ir = hw.createNestedObject("ir");
|
||||
hw_ir["pin"] = irPin;
|
||||
|
@ -31,6 +31,14 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef WLED_MAX_BUTTONS
|
||||
#ifdef ESP8266
|
||||
#define WLED_MAX_BUTTONS 2
|
||||
#else
|
||||
#define WLED_MAX_BUTTONS 4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//Usermod IDs
|
||||
#define USERMOD_ID_RESERVED 0 //Unused. Might indicate no usermod present
|
||||
#define USERMOD_ID_UNSPECIFIED 1 //Default value for a general user mod that does not specify a custom ID
|
||||
|
@ -14,6 +14,7 @@
|
||||
{
|
||||
window.open("/settings","_self");
|
||||
}
|
||||
function gId(n){return d.getElementById(n);}
|
||||
function off(n){
|
||||
d.getElementsByName(n)[0].value = -1;
|
||||
}
|
||||
@ -48,32 +49,32 @@
|
||||
function S(){GetV();setABL();}
|
||||
function enABL()
|
||||
{
|
||||
var en = d.getElementById('able').checked;
|
||||
var en = gId('able').checked;
|
||||
d.Sf.LA.value = (en) ? laprev:0;
|
||||
d.getElementById('abl').style.display = (en) ? 'inline':'none';
|
||||
d.getElementById('psu2').style.display = (en) ? 'inline':'none';
|
||||
gId('abl').style.display = (en) ? 'inline':'none';
|
||||
gId('psu2').style.display = (en) ? 'inline':'none';
|
||||
if (d.Sf.LA.value > 0) setABL();
|
||||
}
|
||||
function enLA()
|
||||
{
|
||||
var val = d.Sf.LAsel.value;
|
||||
d.Sf.LA.value = val;
|
||||
d.getElementById('LAdis').style.display = (val == 50) ? 'inline':'none';
|
||||
gId('LAdis').style.display = (val == 50) ? 'inline':'none';
|
||||
UI();
|
||||
}
|
||||
function setABL()
|
||||
{
|
||||
d.getElementById('able').checked = true;
|
||||
gId('able').checked = true;
|
||||
d.Sf.LAsel.value = 50;
|
||||
switch (parseInt(d.Sf.LA.value)) {
|
||||
case 0: d.getElementById('able').checked = false; enABL(); break;
|
||||
case 0: gId('able').checked = false; enABL(); break;
|
||||
case 30: d.Sf.LAsel.value = 30; break;
|
||||
case 35: d.Sf.LAsel.value = 35; break;
|
||||
case 55: d.Sf.LAsel.value = 55; break;
|
||||
case 255: d.Sf.LAsel.value = 255; break;
|
||||
default: d.getElementById('LAdis').style.display = 'inline';
|
||||
default: gId('LAdis').style.display = 'inline';
|
||||
}
|
||||
d.getElementById('m1').innerHTML = maxM;
|
||||
gId('m1').innerHTML = maxM;
|
||||
d.getElementsByName("Sf")[0].addEventListener("submit", trySubmit);
|
||||
UI();
|
||||
}
|
||||
@ -100,7 +101,7 @@
|
||||
{
|
||||
var isRGBW = false, memu = 0;
|
||||
|
||||
d.getElementById('ampwarning').style.display = (d.Sf.MA.value > 7200) ? 'inline':'none';
|
||||
gId('ampwarning').style.display = (d.Sf.MA.value > 7200) ? 'inline':'none';
|
||||
|
||||
if (d.Sf.LA.value == 255) laprev = 12;
|
||||
else if (d.Sf.LA.value > 0) laprev = d.Sf.LA.value;
|
||||
@ -110,8 +111,8 @@
|
||||
if (s[i].name.substring(0,2)=="LT") {
|
||||
n=s[i].name.substring(2);
|
||||
var type = parseInt(s[i].value,10);
|
||||
d.getElementById("p0d"+n).innerHTML = (type > 49) ? "Data:" : (type >41) ? "Pins:" : "Pin:";
|
||||
d.getElementById("p1d"+n).innerHTML = (type > 49) ? "Clk:" : "";
|
||||
gId("p0d"+n).innerHTML = (type > 49) ? "Data:" : (type >41) ? "Pins:" : "Pin:";
|
||||
gId("p1d"+n).innerHTML = (type > 49) ? "Clk:" : "";
|
||||
var LK = d.getElementsByName("L1"+n)[0];
|
||||
|
||||
memu += getMem(type, d.getElementsByName("LC"+n)[0].value, d.getElementsByName("L0"+n)[0].value);
|
||||
@ -129,17 +130,17 @@
|
||||
LK.value="";
|
||||
}
|
||||
}
|
||||
d.getElementById("ls"+n).readOnly = !(type > 31 && type < 48); // not analog
|
||||
d.getElementById("LC").readOnly = !(type > 31 && type < 48); // not analog
|
||||
gId("ls"+n).readOnly = !(type > 31 && type < 48); // not analog
|
||||
gId("LC").readOnly = !(type > 31 && type < 48); // not analog
|
||||
if (change) {
|
||||
// d.getElementById("ew"+n).checked = (type == 30 || type == 31 || type == 44 || type == 45); // RGBW checkbox, TYPE_xxxx values from const.h
|
||||
d.getElementById("ls"+n).value = n+1;
|
||||
// gId("ew"+n).checked = (type == 30 || type == 31 || type == 44 || type == 45); // RGBW checkbox, TYPE_xxxx values from const.h
|
||||
gId("ls"+n).value = n+1;
|
||||
}
|
||||
// d.getElementById("ew"+n).onclick = (type > 31 && type < 48) ? (function(){return false}) : (function(){}); // prevent change for analog
|
||||
// isRGBW |= d.getElementById("ew"+n).checked;
|
||||
// gId("ew"+n).onclick = (type > 31 && type < 48) ? (function(){return false}) : (function(){}); // prevent change for analog
|
||||
// isRGBW |= gId("ew"+n).checked;
|
||||
isRGBW |= (type == 30 || type == 31 || type == 44 || type == 45); // RGBW checkbox, TYPE_xxxx values from const.h
|
||||
d.getElementById("dig"+n).style.display = (type > 31 && type < 48) ? "none":"inline";
|
||||
d.getElementById("psd"+n).innerHTML = (type > 31 && type < 48) ? "Index:":"Start:";
|
||||
gId("dig"+n).style.display = (type > 31 && type < 48) ? "none":"inline";
|
||||
gId("psd"+n).innerHTML = (type > 31 && type < 48) ? "Index:":"Start:";
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,7 +157,7 @@
|
||||
if (nm=="LC" && LCs[i].name !== "LC") {
|
||||
var n=LCs[i].name.substring(2);
|
||||
var c=parseInt(LCs[i].value,10);
|
||||
if(d.getElementById("ls"+n).readOnly) d.getElementById("ls"+n).value=sLC;
|
||||
if(gId("ls"+n).readOnly) gId("ls"+n).value=sLC;
|
||||
if(c){sLC+=c;if(c>maxLC)maxLC=c;}
|
||||
continue;
|
||||
}
|
||||
@ -178,18 +179,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (d.getElementById("LC").readOnly) d.getElementsByName("LC")[0].value = sLC;
|
||||
if (gId("LC").readOnly) d.getElementsByName("LC")[0].value = sLC;
|
||||
if (d.activeElement == d.getElementsByName("LC")[0]) {
|
||||
var o = d.getElementsByClassName("iST");
|
||||
var i = o.length;
|
||||
if (i == 1) d.getElementsByName("LC0")[0].value = d.getElementsByName("LC")[0].value;
|
||||
}
|
||||
d.getElementById('m0').innerHTML = memu;
|
||||
gId('m0').innerHTML = memu;
|
||||
bquot = memu / maxM * 100;
|
||||
d.getElementById('dbar').style.background = `linear-gradient(90deg, ${bquot > 60 ? (bquot > 90 ? "red":"orange"):"#ccc"} 0 ${bquot}%%, #444 ${bquot}%% 100%%)`;
|
||||
d.getElementById('ledwarning').style.display = (sLC > maxPB || maxLC > 800 || bquot > 80) ? 'inline':'none';
|
||||
d.getElementById('ledwarning').style.color = (sLC > maxPB || maxLC > maxPB || bquot > 100) ? 'red':'orange';
|
||||
d.getElementById('wreason').innerHTML = (bquot > 80) ? "80% of max. LED memory" +(bquot>100 ? ` (<b>WARNING: Using over ${maxM}B!</b>)` : "") : "800 LEDs per pin";
|
||||
gId('dbar').style.background = `linear-gradient(90deg, ${bquot > 60 ? (bquot > 90 ? "red":"orange"):"#ccc"} 0 ${bquot}%%, #444 ${bquot}%% 100%%)`;
|
||||
gId('ledwarning').style.display = (sLC > maxPB || maxLC > 800 || bquot > 80) ? 'inline':'none';
|
||||
gId('ledwarning').style.color = (sLC > maxPB || maxLC > maxPB || bquot > 100) ? 'red':'orange';
|
||||
gId('wreason').innerHTML = (bquot > 80) ? "80% of max. LED memory" +(bquot>100 ? ` (<b>WARNING: Using over ${maxM}B!</b>)` : "") : "800 LEDs per pin";
|
||||
|
||||
var val = Math.ceil((100 + sLC * laprev)/500)/2;
|
||||
val = (val > 5) ? Math.ceil(val) : val;
|
||||
@ -210,8 +211,8 @@
|
||||
var s2 = "(for most effects, ~";
|
||||
s2 += val2;
|
||||
s2 += "A is enough)<br>";
|
||||
d.getElementById('psu').innerHTML = s;
|
||||
d.getElementById('psu2').innerHTML = isWS2815 ? "" : s2;
|
||||
gId('psu').innerHTML = s;
|
||||
gId('psu2').innerHTML = isWS2815 ? "" : s2;
|
||||
}
|
||||
function lastEnd(i) {
|
||||
if (i<1) return 0;
|
||||
@ -221,14 +222,14 @@
|
||||
}
|
||||
function addLEDs(n)
|
||||
{
|
||||
if (n>1) {maxB=n; d.getElementById("+").style.display="inline"; return;}
|
||||
if (n>1) {maxB=n; gId("+").style.display="inline"; return;}
|
||||
|
||||
var o = d.getElementsByClassName("iST");
|
||||
var i = o.length;
|
||||
|
||||
if ((n==1 && i>=maxB) || (n==-1 && i==0)) return;
|
||||
|
||||
var f = d.getElementById("mLC");
|
||||
var f = gId("mLC");
|
||||
if (n==1) {
|
||||
// npm run build has trouble minimizing spaces inside string
|
||||
var cn = `<div class="iST">
|
||||
@ -277,15 +278,28 @@ Reverse (rotated 180°): <input type="checkbox" name="CV${i}">
|
||||
o[--i].remove();--i;
|
||||
}
|
||||
|
||||
d.getElementById("+").style.display = (i<maxB-1) ? "inline":"none";
|
||||
d.getElementById("-").style.display = (i>0) ? "inline":"none";
|
||||
gId("+").style.display = (i<maxB-1) ? "inline":"none";
|
||||
gId("-").style.display = (i>0) ? "inline":"none";
|
||||
|
||||
UI();
|
||||
}
|
||||
function addBtn(i,p,t) {
|
||||
var c = gId("btns").innerHTML;
|
||||
var bt = "BT" + i;
|
||||
var be = "BE" + i;
|
||||
c += `Button ${i} pin: <input type="number" min="-1" max="40" name="${bt}" onchange="UI()" value="${p}">`;
|
||||
c += `<select name="${bt}">`
|
||||
c += `<option name="${be}" value="0" ${t==0?"selected":""}>Disabled</option>`;
|
||||
c += `<option name="${be}" value="2" ${t==2?"selected":""}>Pushbutton</option>`;
|
||||
c += `<option name="${be}" value="4" ${t==4?"selected":""}>Switch</option>`;
|
||||
c += `</select>`;
|
||||
c += `<span style="cursor: pointer;" onclick="off('${bt}')"> ×</span><br>`;
|
||||
gId("btns").innerHTML = c;
|
||||
}
|
||||
function GetV()
|
||||
{
|
||||
//values injected by server while sending HTML
|
||||
//maxM=5000;maxPB=1536;d.um_p=[1,6,7,8,9,10,11];addLEDs(3);d.Sf.LC.value=250;addLEDs(1);d.Sf.L00.value=2;d.Sf.L10.value=0;d.Sf.LC0.value=250;d.Sf.LT0.value=22;d.Sf.CO0.value=0;d.Sf.LS0.value=0;d.Sf.LS0.checked=0;d.Sf.MA.value=5400;d.Sf.LA.value=55;d.getElementsByClassName("pow")[0].innerHTML="350mA";d.Sf.CA.value=40;d.Sf.AW.value=3;d.Sf.BO.checked=0;d.Sf.BP.value=3;d.Sf.GB.checked=0;d.Sf.GC.checked=1;d.Sf.TF.checked=1;d.Sf.TD.value=700;d.Sf.PF.checked=0;d.Sf.BF.value=64;d.Sf.TB.value=0;d.Sf.TL.value=60;d.Sf.TW.value=1;d.Sf.PB.selectedIndex=0;d.Sf.SL.checked=0;d.Sf.RL.value=12;d.Sf.RM.checked=0;d.Sf.BT.value=-1;d.Sf.IR.value=-1;d.Sf.AX.value=-1;
|
||||
//maxM=5000;maxPB=1536;d.um_p=[1,6,7,8,9,10,11];addLEDs(3);d.Sf.LC.value=250;addLEDs(1);d.Sf.L00.value=2;d.Sf.L10.value=0;d.Sf.LC0.value=250;d.Sf.LT0.value=22;d.Sf.CO0.value=0;d.Sf.LS0.value=0;d.Sf.LS0.checked=0;d.Sf.MA.value=5400;d.Sf.LA.value=55;d.getElementsByClassName("pow")[0].innerHTML="350mA";d.Sf.CA.value=40;d.Sf.AW.value=3;d.Sf.BO.checked=0;d.Sf.BP.value=3;d.Sf.GB.checked=0;d.Sf.GC.checked=1;d.Sf.TF.checked=1;d.Sf.TD.value=700;d.Sf.PF.checked=0;d.Sf.BF.value=64;d.Sf.TB.value=0;d.Sf.TL.value=60;d.Sf.TW.value=1;d.Sf.PB.selectedIndex=0;d.Sf.RL.value=12;d.Sf.RM.checked=0;addBtn(0,0,2);addBtn(1,3,4);addBtn(2,-1,0);d.Sf.IR.value=-1;
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@ -338,10 +352,20 @@ Reverse (rotated 180°): <input type="checkbox" name="CV${i}">
|
||||
⚠ You might run into stability or lag issues.<br>
|
||||
Use less than <span id="wreason">800 LEDs per pin</span> for the best experience!<br>
|
||||
</div><hr style="width:260px">
|
||||
Button pin: <input type="number" min="-1" max="40" name="BT" onchange="UI()"><span style="cursor: pointer;" onclick="off('BT')"> ×</span><br>
|
||||
IR pin: <input type="number" min="-1" max="40" name="IR" onchange="UI()"><span style="cursor: pointer;" onclick="off('IR')"> ×</span><br>
|
||||
Relay pin: <input type="number" min="-1" max="40" name="RL" onchange="UI()"><span style="cursor: pointer;" onclick="off('RL')"> ×</span><br>
|
||||
Active high <input type="checkbox" name="RM">
|
||||
<div id="btns"></div>
|
||||
IR pin: <input type="number" min="-1" max="40" name="IR" onchange="UI()"><select name="IT">
|
||||
<option value="0">Remote disabled</option>
|
||||
<option value="1">24-key RGB</option>
|
||||
<option value="2">24-key with CT</option>
|
||||
<option value="3">40-key blue</option>
|
||||
<option value="4">44-key RGB</option>
|
||||
<option value="5">21-key RGB</option>
|
||||
<option value="6">6-key black</option>
|
||||
<option value="7">9-key red</option>
|
||||
<option value="8">JSON remote</option>
|
||||
</select><span style="cursor: pointer;" onclick="off('IR')"> ×</span><br>
|
||||
<a href="https://github.com/Aircoookie/WLED/wiki/Infrared-Control" target="_blank">IR info</a><br>
|
||||
Relay pin: <input type="number" min="-1" max="40" name="RL" onchange="UI()"> invert <input type="checkbox" name="RM"><span style="cursor: pointer;" onclick="off('RL')"> ×</span><br>
|
||||
<hr style="width:260px">
|
||||
<h3>Defaults</h3>
|
||||
Turn LEDs on after power up/reset: <input type="checkbox" name="BO"><br>
|
||||
@ -374,7 +398,6 @@ Reverse (rotated 180°): <input type="checkbox" name="CV${i}">
|
||||
<option value="2">Linear (never wrap)</option>
|
||||
<option value="3">None (not recommended)</option>
|
||||
</select><br>
|
||||
<!--Skip first LED: <input type="checkbox" name="SL"><br-->
|
||||
<span class="wc">
|
||||
Auto-calculate white channel from RGB:<br>
|
||||
<select name="AW">
|
||||
|
@ -17,6 +17,7 @@ function GetV(){var d=document;}
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||
</div>
|
||||
<h2>Sync setup</h2>
|
||||
<!--
|
||||
<h3>Button setup</h3>
|
||||
Button type:
|
||||
<select name=BT>
|
||||
@ -37,6 +38,7 @@ Infrared remote:
|
||||
<option value=8>JSON remote</option>
|
||||
</select><br>
|
||||
<a href="https://github.com/Aircoookie/WLED/wiki/Infrared-Control" target="_blank">IR info</a>
|
||||
-->
|
||||
<h3>WLED Broadcast</h3>
|
||||
UDP Port: <input name="UP" type="number" min="1" max="65535" class="d5" required><br>
|
||||
2nd Port: <input name="U2" type="number" min="1" max="65535" class="d5" required><br>
|
||||
|
@ -75,9 +75,25 @@
|
||||
gId("W"+i).value=a[i];
|
||||
}
|
||||
}
|
||||
function addRow(i,p,l,d) {
|
||||
var t = gId("macros"); // table
|
||||
var rCnt = t.rows.length; // get the number of rows.
|
||||
var tr = t.insertRow(rCnt); // table row.
|
||||
|
||||
var td = document.createElement('td'); // TABLE DEFINITION.
|
||||
td = tr.insertCell(0);
|
||||
td.innerHTML = `Button ${i}:`;
|
||||
td = tr.insertCell(1);
|
||||
td.innerHTML = `<input name="MP${i}" type="number" min="0" max="250" value="${p}" required>`;
|
||||
td = tr.insertCell(2);
|
||||
td.innerHTML = `<input name="ML${i}" type="number" min="0" max="250" value="${l}" required>`;
|
||||
td = tr.insertCell(3);
|
||||
td.innerHTML = `<input name="MD${i}" type="number" min="0" max="250" value="${d}" required>`;
|
||||
}
|
||||
function GetV()
|
||||
{
|
||||
//values injected by server while sending HTML
|
||||
addRow(0,23,4,0);
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@ -109,12 +125,12 @@
|
||||
<option value="10">JST(KST)</option>
|
||||
<option value="11">AEST/AEDT</option>
|
||||
<option value="12">NZST/NZDT</option>
|
||||
<option value="13">North Korea</option>
|
||||
<option value="14">IST (India)</option>
|
||||
<option value="15">CA-Saskatchewan</option>
|
||||
<option value="16">ACST</option>
|
||||
<option value="17">ACST/ACDT</option>
|
||||
<option value="18">HST (Hawaii)</option>
|
||||
<option value="13">North Korea</option>
|
||||
<option value="14">IST (India)</option>
|
||||
<option value="15">CA-Saskatchewan</option>
|
||||
<option value="16">ACST</option>
|
||||
<option value="17">ACST/ACDT</option>
|
||||
<option value="18">HST (Hawaii)</option>
|
||||
</select><br>
|
||||
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
|
||||
Current local time is <span class="times">unknown</span>.<br>
|
||||
@ -145,15 +161,26 @@
|
||||
Year: 20 <input name="CY" class="small" type="number" min="0" max="99" required> Month: <input name="CI" class="small" type="number" min="1" max="12" required> Day: <input name="CD" class="small" type="number" min="1" max="31" required><br>
|
||||
Hour: <input name="CH" class="small" type="number" min="0" max="23" required> Minute: <input name="CM" class="small" type="number" min="0" max="59" required> Second: <input name="CS" class="small" type="number" min="0" max="59" required><br>
|
||||
<h3>Macro presets</h3>
|
||||
<b>Macros have moved!</b><br>
|
||||
<i>Presets now also can be used as macros to save both JSON and HTTP API commands.<br>
|
||||
Just enter the preset id below!</i>
|
||||
<b>Macros have moved!</b><br>
|
||||
<i>Presets now also can be used as macros to save both JSON and HTTP API commands.<br>
|
||||
Just enter the preset id below!</i>
|
||||
<i>Use 0 for the default action instead of a preset</i><br>
|
||||
Alexa On/Off Preset: <input name="A0" type="number" min="0" max="250" required> <input name="A1" type="number" min="0" max="250" required><br>
|
||||
Button short press Preset: <input name="MP" type="number" min="0" max="250" required><br>
|
||||
Long Press: <input name="ML" type="number" min="0" max="250" required> Double press: <input name="MD" type="number" min="0" max="250" required><br>
|
||||
Countdown-Over Preset: <input name="MC" type="number" min="0" max="250" required><br>
|
||||
Timed-Light-Over Presets: <input name="MN" type="number" min="0" max="250" required><br>
|
||||
<h3>Button actions</h3>
|
||||
<table style="margin: 0 auto;" id="macros">
|
||||
<thead>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>short<br>on->off</td>
|
||||
<td>long<br>off->on</td>
|
||||
<td>double</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>Time-controlled presets</h3>
|
||||
<div style="display: inline-block">
|
||||
<table id="TMT">
|
||||
|
@ -20,8 +20,8 @@ void handleBlynk();
|
||||
void updateBlynk();
|
||||
|
||||
//button.cpp
|
||||
void shortPressAction();
|
||||
bool isButtonPressed();
|
||||
void shortPressAction(uint8_t b=0);
|
||||
bool isButtonPressed(uint8_t b=0);
|
||||
void handleButton();
|
||||
void handleIO();
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -81,7 +81,9 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
#ifndef WLED_DISABLE_INFRARED
|
||||
if (irPin>=0 && pinManager.isPinAllocated(irPin)) pinManager.deallocatePin(irPin);
|
||||
#endif
|
||||
if (btnPin>=0 && pinManager.isPinAllocated(btnPin)) pinManager.deallocatePin(btnPin);
|
||||
for (uint8_t s=0; s<WLED_MAX_BUTTONS; s++)
|
||||
if (btnPin[s]>=0 && pinManager.isPinAllocated(btnPin[s]))
|
||||
pinManager.deallocatePin(btnPin[s]);
|
||||
|
||||
strip.isRgbw = false;
|
||||
uint8_t colorOrder, type, skip;
|
||||
@ -135,6 +137,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
} else {
|
||||
irPin = -1;
|
||||
}
|
||||
irEnabled = request->arg(F("IT")).toInt();
|
||||
#endif
|
||||
|
||||
int hw_rly_pin = request->arg(F("RL")).toInt();
|
||||
@ -145,12 +148,20 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
}
|
||||
rlyMde = (bool)request->hasArg(F("RM"));
|
||||
|
||||
int hw_btn_pin = request->arg(F("BT")).toInt();
|
||||
if (pinManager.allocatePin(hw_btn_pin,false)) {
|
||||
btnPin = hw_btn_pin;
|
||||
pinMode(btnPin, INPUT_PULLUP);
|
||||
} else {
|
||||
btnPin = -1;
|
||||
for (uint8_t i=0; i<WLED_MAX_BUTTONS; i++) {
|
||||
char bt[4] = "BT"; bt[2] = 48+i; bt[3] = 0; // button pin
|
||||
char be[4] = "BE"; be[2] = 48+i; be[3] = 0; // button type
|
||||
//if (request->hasArg(bt)) {
|
||||
int hw_btn_pin = request->arg(bt).toInt();
|
||||
if (pinManager.allocatePin(hw_btn_pin,false)) {
|
||||
btnPin[i] = hw_btn_pin;
|
||||
pinMode(btnPin[i], INPUT_PULLUP);
|
||||
buttonType[i] = request->arg(be).toInt();
|
||||
} else {
|
||||
btnPin[i] = -1;
|
||||
buttonType[i] = BTN_TYPE_NONE;
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
strip.ablMilliampsMax = request->arg(F("MA")).toInt();
|
||||
@ -195,8 +206,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
//SYNC
|
||||
if (subPage == 4)
|
||||
{
|
||||
buttonType = request->arg(F("BT")).toInt();
|
||||
irEnabled = request->arg(F("IR")).toInt();
|
||||
//buttonType = request->arg(F("BT")).toInt();
|
||||
//irEnabled = request->arg(F("IR")).toInt();
|
||||
int t = request->arg(F("UP")).toInt();
|
||||
if (t > 0) udpPort = t;
|
||||
t = request->arg(F("U2")).toInt();
|
||||
@ -324,11 +335,16 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
|
||||
macroAlexaOn = request->arg(F("A0")).toInt();
|
||||
macroAlexaOff = request->arg(F("A1")).toInt();
|
||||
macroButton = request->arg(F("MP")).toInt();
|
||||
macroLongPress = request->arg(F("ML")).toInt();
|
||||
macroCountdown = request->arg(F("MC")).toInt();
|
||||
macroNl = request->arg(F("MN")).toInt();
|
||||
macroDoublePress = request->arg(F("MD")).toInt();
|
||||
for (uint8_t i=0; i<WLED_MAX_BUTTONS; i++) {
|
||||
char mp[4] = "MP"; mp[2] = 48+i; mp[3] = 0; // short
|
||||
char ml[4] = "ML"; ml[2] = 48+i; ml[3] = 0; // long
|
||||
char md[4] = "MD"; md[2] = 48+i; md[3] = 0; // double
|
||||
macroButton[i] = request->arg(mp).toInt();
|
||||
macroLongPress[i] = request->arg(ml).toInt();
|
||||
macroDoublePress[i] = request->arg(md).toInt();
|
||||
}
|
||||
|
||||
char k[3]; k[2] = 0;
|
||||
for (int i = 0; i<10; i++)
|
||||
|
1502
wled00/wled.cpp
1502
wled00/wled.cpp
File diff suppressed because it is too large
Load Diff
1326
wled00/wled.h
1326
wled00/wled.h
File diff suppressed because it is too large
Load Diff
@ -93,7 +93,7 @@ void loadSettingsFromEEPROM()
|
||||
|
||||
notifyButton = EEPROM.read(230);
|
||||
notifyTwice = EEPROM.read(231);
|
||||
buttonType = EEPROM.read(232) ? BTN_TYPE_PUSH : BTN_TYPE_NONE;
|
||||
buttonType[0] = EEPROM.read(232) ? BTN_TYPE_PUSH : BTN_TYPE_NONE;
|
||||
|
||||
staticIP[0] = EEPROM.read(234);
|
||||
staticIP[1] = EEPROM.read(235);
|
||||
@ -198,12 +198,12 @@ void loadSettingsFromEEPROM()
|
||||
//macroBoot = EEPROM.read(2175);
|
||||
macroAlexaOn = EEPROM.read(2176);
|
||||
macroAlexaOff = EEPROM.read(2177);
|
||||
macroButton = EEPROM.read(2178);
|
||||
macroLongPress = EEPROM.read(2179);
|
||||
macroButton[0] = EEPROM.read(2178);
|
||||
macroLongPress[0] = EEPROM.read(2179);
|
||||
macroCountdown = EEPROM.read(2180);
|
||||
macroNl = EEPROM.read(2181);
|
||||
macroDoublePress = EEPROM.read(2182);
|
||||
if (macroDoublePress > 16) macroDoublePress = 0;
|
||||
macroDoublePress[0] = EEPROM.read(2182);
|
||||
if (macroDoublePress[0] > 16) macroDoublePress[0] = 0;
|
||||
}
|
||||
|
||||
if (lastEEPROMversion > 6)
|
||||
|
@ -392,8 +392,15 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('i',SET_F("PB"),strip.paletteBlend);
|
||||
sappend('v',SET_F("RL"),rlyPin);
|
||||
sappend('c',SET_F("RM"),rlyMde);
|
||||
sappend('v',SET_F("BT"),btnPin);
|
||||
for (uint8_t i=0; i<WLED_MAX_BUTTONS; i++) {
|
||||
oappend(SET_F("addBtn("));
|
||||
oappend(itoa(i,nS,10)); oappend(",");
|
||||
oappend(itoa(btnPin[i],nS,10)); oappend(",");
|
||||
oappend(itoa(buttonType[i],nS,10));
|
||||
oappend(SET_F(");"));
|
||||
}
|
||||
sappend('v',SET_F("IR"),irPin);
|
||||
sappend('v',SET_F("IT"),irEnabled);
|
||||
}
|
||||
|
||||
if (subPage == 3)
|
||||
@ -404,8 +411,8 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
|
||||
if (subPage == 4)
|
||||
{
|
||||
sappend('v',SET_F("BT"),buttonType);
|
||||
sappend('v',SET_F("IR"),irEnabled);
|
||||
//sappend('v',SET_F("BT"),buttonType);
|
||||
//sappend('v',SET_F("IR"),irEnabled);
|
||||
sappend('v',SET_F("UP"),udpPort);
|
||||
sappend('v',SET_F("U2"),udpPort2);
|
||||
sappend('c',SET_F("RB"),receiveNotificationBrightness);
|
||||
@ -521,11 +528,19 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
|
||||
sappend('v',SET_F("A0"),macroAlexaOn);
|
||||
sappend('v',SET_F("A1"),macroAlexaOff);
|
||||
sappend('v',SET_F("MP"),macroButton);
|
||||
sappend('v',SET_F("ML"),macroLongPress);
|
||||
sappend('v',SET_F("MC"),macroCountdown);
|
||||
sappend('v',SET_F("MN"),macroNl);
|
||||
sappend('v',SET_F("MD"),macroDoublePress);
|
||||
//sappend('v',SET_F("MP"),macroButton);
|
||||
//sappend('v',SET_F("ML"),macroLongPress);
|
||||
//sappend('v',SET_F("MD"),macroDoublePress);
|
||||
for (uint8_t i=0; i<WLED_MAX_BUTTONS; i++) {
|
||||
oappend(SET_F("addRow("));
|
||||
oappend(itoa(i,tm,10)); oappend(",");
|
||||
oappend(itoa(macroButton[i],tm,10)); oappend(",");
|
||||
oappend(itoa(macroLongPress[i],tm,10)); oappend(",");
|
||||
oappend(itoa(macroDoublePress[i],tm,10));
|
||||
oappend(SET_F(");"));
|
||||
}
|
||||
|
||||
char k[4];
|
||||
k[2] = 0; //Time macros
|
||||
|
Loading…
Reference in New Issue
Block a user