Add user selectable Gamma
Add panel visualisation (@ewoudwijma, #3090) Bugfix: - PIR onStateChange() ignored until inited - remove matrix orientation - ignore removing ledmap 0 if 2D - _globalLeds size
This commit is contained in:
parent
eee9274098
commit
821f320347
@ -375,6 +375,7 @@ public:
|
|||||||
* onStateChanged() is used to detect WLED state change
|
* onStateChanged() is used to detect WLED state change
|
||||||
*/
|
*/
|
||||||
void onStateChange(uint8_t mode) {
|
void onStateChange(uint8_t mode) {
|
||||||
|
if (!initDone) return;
|
||||||
DEBUG_PRINT(F("PIR: offTimerStart=")); DEBUG_PRINTLN(offTimerStart);
|
DEBUG_PRINT(F("PIR: offTimerStart=")); DEBUG_PRINTLN(offTimerStart);
|
||||||
if (PIRtriggered && offTimerStart) {
|
if (PIRtriggered && offTimerStart) {
|
||||||
// checking PIRtriggered and offTimerStart will prevent cancellation upon On trigger
|
// checking PIRtriggered and offTimerStart will prevent cancellation upon On trigger
|
||||||
|
@ -659,7 +659,6 @@ class WS2812FX { // 96 bytes
|
|||||||
isMatrix(false),
|
isMatrix(false),
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
panels(1),
|
panels(1),
|
||||||
matrix{0,0,0,0},
|
|
||||||
#endif
|
#endif
|
||||||
// semi-private (just obscured) used in effect functions through macros
|
// semi-private (just obscured) used in effect functions through macros
|
||||||
_currentPalette(CRGBPalette16(CRGB::Black)),
|
_currentPalette(CRGBPalette16(CRGB::Black)),
|
||||||
@ -813,13 +812,6 @@ class WS2812FX { // 96 bytes
|
|||||||
uint8_t
|
uint8_t
|
||||||
panels;
|
panels;
|
||||||
|
|
||||||
struct {
|
|
||||||
bool bottomStart : 1;
|
|
||||||
bool rightStart : 1;
|
|
||||||
bool vertical : 1;
|
|
||||||
bool serpentine : 1;
|
|
||||||
} matrix;
|
|
||||||
|
|
||||||
typedef struct panel_t {
|
typedef struct panel_t {
|
||||||
uint16_t xOffset; // x offset relative to the top left of matrix in LEDs
|
uint16_t xOffset; // x offset relative to the top left of matrix in LEDs
|
||||||
uint16_t yOffset; // y offset relative to the top left of matrix in LEDs
|
uint16_t yOffset; // y offset relative to the top left of matrix in LEDs
|
||||||
|
@ -1027,17 +1027,20 @@ void WS2812FX::finalizeInit(void)
|
|||||||
Segment::_globalLeds = nullptr;
|
Segment::_globalLeds = nullptr;
|
||||||
}
|
}
|
||||||
if (useLedsArray) {
|
if (useLedsArray) {
|
||||||
|
size_t arrSize = sizeof(CRGB) * MAX(_length, Segment::maxWidth*Segment::maxHeight);
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
|
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
|
||||||
if (psramFound())
|
if (psramFound())
|
||||||
Segment::_globalLeds = (CRGB*) ps_malloc(sizeof(CRGB) * _length);
|
Segment::_globalLeds = (CRGB*) ps_malloc(arrSize);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
Segment::_globalLeds = (CRGB*) malloc(sizeof(CRGB) * _length);
|
Segment::_globalLeds = (CRGB*) malloc(arrSize);
|
||||||
memset(Segment::_globalLeds, 0, sizeof(CRGB) * _length);
|
memset(Segment::_globalLeds, 0, arrSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
//segments are created in makeAutoSegments();
|
//segments are created in makeAutoSegments();
|
||||||
|
DEBUG_PRINTLN(F("Loading custom palettes"));
|
||||||
loadCustomPalettes(); // (re)load all custom palettes
|
loadCustomPalettes(); // (re)load all custom palettes
|
||||||
|
DEBUG_PRINTLN(F("Loading custom ledmaps"));
|
||||||
deserializeMap(); // (re)load default ledmap
|
deserializeMap(); // (re)load default ledmap
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1595,7 +1598,7 @@ bool WS2812FX::deserializeMap(uint8_t n) {
|
|||||||
|
|
||||||
if (!isFile) {
|
if (!isFile) {
|
||||||
// erase custom mapping if selecting nonexistent ledmap.json (n==0)
|
// erase custom mapping if selecting nonexistent ledmap.json (n==0)
|
||||||
if (!n && customMappingTable != nullptr) {
|
if (!isMatrix && !n && customMappingTable != nullptr) {
|
||||||
customMappingSize = 0;
|
customMappingSize = 0;
|
||||||
delete[] customMappingTable;
|
delete[] customMappingTable;
|
||||||
customMappingTable = nullptr;
|
customMappingTable = nullptr;
|
||||||
|
@ -98,11 +98,6 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
if (!matrix.isNull()) {
|
if (!matrix.isNull()) {
|
||||||
strip.isMatrix = true;
|
strip.isMatrix = true;
|
||||||
CJSON(strip.panels, matrix[F("mpc")]);
|
CJSON(strip.panels, matrix[F("mpc")]);
|
||||||
CJSON(strip.matrix.bottomStart, matrix[F("pb")]);
|
|
||||||
CJSON(strip.matrix.rightStart, matrix[F("pr")]);
|
|
||||||
CJSON(strip.matrix.vertical, matrix[F("pv")]);
|
|
||||||
CJSON(strip.matrix.serpentine, matrix["ps"]);
|
|
||||||
|
|
||||||
strip.panel.clear();
|
strip.panel.clear();
|
||||||
JsonArray panels = matrix[F("panels")];
|
JsonArray panels = matrix[F("panels")];
|
||||||
uint8_t s = 0;
|
uint8_t s = 0;
|
||||||
@ -130,6 +125,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
p.options = 0;
|
p.options = 0;
|
||||||
strip.panel.push_back(p);
|
strip.panel.push_back(p);
|
||||||
}
|
}
|
||||||
|
// cannot call strip.setUpMatrix() here due to already locked JSON buffer
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -331,12 +327,20 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
CJSON(strip.paletteBlend, light[F("pal-mode")]);
|
CJSON(strip.paletteBlend, light[F("pal-mode")]);
|
||||||
CJSON(autoSegments, light[F("aseg")]);
|
CJSON(autoSegments, light[F("aseg")]);
|
||||||
|
|
||||||
|
CJSON(gammaCorrectVal, light["gc"]["val"]); // default 2.8
|
||||||
float light_gc_bri = light["gc"]["bri"];
|
float light_gc_bri = light["gc"]["bri"];
|
||||||
float light_gc_col = light["gc"]["col"]; // 2.8
|
float light_gc_col = light["gc"]["col"];
|
||||||
if (light_gc_bri > 1.5) gammaCorrectBri = true;
|
if (light_gc_bri > 1.0f) gammaCorrectBri = true;
|
||||||
else if (light_gc_bri > 0.5) gammaCorrectBri = false;
|
else gammaCorrectBri = false;
|
||||||
if (light_gc_col > 1.5) gammaCorrectCol = true;
|
if (light_gc_col > 1.0f) gammaCorrectCol = true;
|
||||||
else if (light_gc_col > 0.5) gammaCorrectCol = false;
|
else gammaCorrectCol = false;
|
||||||
|
if (gammaCorrectVal > 1.0f && gammaCorrectVal <= 3) {
|
||||||
|
if (gammaCorrectVal != 2.8f) calcGammaTable(gammaCorrectVal);
|
||||||
|
} else {
|
||||||
|
gammaCorrectVal = 1.0f; // no gamma correction
|
||||||
|
gammaCorrectBri = false;
|
||||||
|
gammaCorrectCol = false;
|
||||||
|
}
|
||||||
|
|
||||||
JsonObject light_tr = light["tr"];
|
JsonObject light_tr = light["tr"];
|
||||||
CJSON(fadeTransition, light_tr["mode"]);
|
CJSON(fadeTransition, light_tr["mode"]);
|
||||||
@ -706,11 +710,6 @@ void serializeConfig() {
|
|||||||
if (strip.isMatrix) {
|
if (strip.isMatrix) {
|
||||||
JsonObject matrix = hw_led.createNestedObject(F("matrix"));
|
JsonObject matrix = hw_led.createNestedObject(F("matrix"));
|
||||||
matrix[F("mpc")] = strip.panels;
|
matrix[F("mpc")] = strip.panels;
|
||||||
matrix[F("pb")] = strip.matrix.bottomStart;
|
|
||||||
matrix[F("pr")] = strip.matrix.rightStart;
|
|
||||||
matrix[F("pv")] = strip.matrix.vertical;
|
|
||||||
matrix["ps"] = strip.matrix.serpentine;
|
|
||||||
|
|
||||||
JsonArray panels = matrix.createNestedArray(F("panels"));
|
JsonArray panels = matrix.createNestedArray(F("panels"));
|
||||||
for (uint8_t i=0; i<strip.panel.size(); i++) {
|
for (uint8_t i=0; i<strip.panel.size(); i++) {
|
||||||
JsonObject pnl = panels.createNestedObject();
|
JsonObject pnl = panels.createNestedObject();
|
||||||
@ -808,8 +807,9 @@ void serializeConfig() {
|
|||||||
light[F("aseg")] = autoSegments;
|
light[F("aseg")] = autoSegments;
|
||||||
|
|
||||||
JsonObject light_gc = light.createNestedObject("gc");
|
JsonObject light_gc = light.createNestedObject("gc");
|
||||||
light_gc["bri"] = (gammaCorrectBri) ? 2.8 : 1.0;
|
light_gc["bri"] = (gammaCorrectBri) ? gammaCorrectVal : 1.0; // keep compatibility
|
||||||
light_gc["col"] = (gammaCorrectCol) ? 2.8 : 1.0;
|
light_gc["col"] = (gammaCorrectCol) ? gammaCorrectVal : 1.0; // keep compatibility
|
||||||
|
light_gc["val"] = gammaCorrectVal;
|
||||||
|
|
||||||
JsonObject light_tr = light.createNestedObject("tr");
|
JsonObject light_tr = light.createNestedObject("tr");
|
||||||
light_tr["mode"] = fadeTransition;
|
light_tr["mode"] = fadeTransition;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
var d=document;
|
var d=document;
|
||||||
var loc = false, locip;
|
var loc = false, locip;
|
||||||
var maxPanels=64;
|
var maxPanels=64;
|
||||||
|
var ctx = null; // WLEDMM
|
||||||
function H(){window.open("https://kno.wled.ge/features/2D");}
|
function H(){window.open("https://kno.wled.ge/features/2D");}
|
||||||
function B(){window.open("/settings","_self");}
|
function B(){window.open("/settings","_self");}
|
||||||
function gId(n){return d.getElementById(n);}
|
function gId(n){return d.getElementById(n);}
|
||||||
@ -52,6 +53,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gId("mpdiv").style.display = "block";
|
gId("mpdiv").style.display = "block";
|
||||||
|
draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
var timeout;
|
var timeout;
|
||||||
@ -90,21 +92,21 @@
|
|||||||
var pw = parseInt(d.Sf.PW.value);
|
var pw = parseInt(d.Sf.PW.value);
|
||||||
var ph = parseInt(d.Sf.PH.value);
|
var ph = parseInt(d.Sf.PH.value);
|
||||||
let b = `<div id="pnl${i}"><hr class="sml">Panel ${i}<br>
|
let b = `<div id="pnl${i}"><hr class="sml">Panel ${i}<br>
|
||||||
1<sup>st</sup> LED: <select name="P${i}B">
|
1<sup>st</sup> LED: <select name="P${i}B" oninput="UI()">
|
||||||
<option value="0">Top</option>
|
<option value="0">Top</option>
|
||||||
<option value="1">Bottom</option>
|
<option value="1">Bottom</option>
|
||||||
</select><select name="P${i}R">
|
</select><select name="P${i}R" oninput="UI()">
|
||||||
<option value="0">Left</option>
|
<option value="0">Left</option>
|
||||||
<option value="1">Right</option>
|
<option value="1">Right</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
Orientation: <select name="P${i}V">
|
Orientation: <select name="P${i}V" oninput="UI()">
|
||||||
<option value="0">Horizontal</option>
|
<option value="0">Horizontal</option>
|
||||||
<option value="1">Vertical</option>
|
<option value="1">Vertical</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
Serpentine: <input type="checkbox" name="P${i}S"><br>
|
Serpentine: <input type="checkbox" name="P${i}S" oninput="UI()"><br>
|
||||||
Dimensions (WxH): <input name="P${i}W" type="number" min="1" max="128" value="${pw}"> x <input name="P${i}H" type="number" min="1" max="128" value="${ph}"><br>
|
Dimensions (WxH): <input name="P${i}W" type="number" min="1" max="255" value="${pw}" oninput="UI()"> x <input name="P${i}H" type="number" min="1" max="255" value="${ph}" oninput="UI()"><br>
|
||||||
Offset X:<input name="P${i}X" type="number" min="0" max="256" value="0">
|
Offset X:<input name="P${i}X" type="number" min="0" max="255" value="0" oninput="UI()">
|
||||||
Y:<input name="P${i}Y" type="number" min="0" max="256" value="0"><br><i>(offset from top-left corner in # LEDs)</i>
|
Y:<input name="P${i}Y" type="number" min="0" max="255" value="0" oninput="UI()"><br><i>(offset from top-left corner in # LEDs)</i>
|
||||||
</div>`;
|
</div>`;
|
||||||
p.insertAdjacentHTML("beforeend", b);
|
p.insertAdjacentHTML("beforeend", b);
|
||||||
}
|
}
|
||||||
@ -161,7 +163,129 @@ Y:<input name="P${i}Y" type="number" min="0" max="256" value="0"><br><i>(offset
|
|||||||
function expand(o,i)
|
function expand(o,i)
|
||||||
{
|
{
|
||||||
i.style.display = i.style.display!=="none" ? "none" : "";
|
i.style.display = i.style.display!=="none" ? "none" : "";
|
||||||
o.innerHTML = i.style.display==="none" ? ">" : "V";
|
o.style.rotate = i.style.display==="none" ? "none" : "90deg";
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
|
||||||
|
if (!ctx) {
|
||||||
|
//WLEDMM: add canvas, initialize and set UI
|
||||||
|
var canvas = gId("canvas");
|
||||||
|
canvas.width = window.innerWidth > 640?640:400; //Mobile gets 400, pc 640
|
||||||
|
canvas.height = canvas.width;
|
||||||
|
ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
// window.requestAnimationFrame(animate);
|
||||||
|
}
|
||||||
|
|
||||||
|
//calc max height and width
|
||||||
|
var maxWidth = 0;
|
||||||
|
var maxHeight = 0;
|
||||||
|
for (let p=0; p<gId("panels").children.length; p++) {
|
||||||
|
var px = parseInt(Sf[`P${p}X`].value); //first led x
|
||||||
|
var py = parseInt(Sf[`P${p}Y`].value); //first led y
|
||||||
|
var pw = parseInt(Sf[`P${p}W`].value); //width
|
||||||
|
var ph = parseInt(Sf[`P${p}H`].value); //height
|
||||||
|
maxWidth = Math.max(maxWidth, px + pw);
|
||||||
|
maxHeight = Math.max(maxHeight, py + ph);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.canvas.height = ctx.canvas.width / maxWidth * maxHeight;
|
||||||
|
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||||
|
var space=0; // space between panels + margin
|
||||||
|
var ppL = (ctx.canvas.width - space * 2) / maxWidth; //pixels per led
|
||||||
|
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
ctx.strokeStyle="yellow";
|
||||||
|
ctx.strokeRect(0, 0, ctx.canvas.width, ctx.canvas.height); // add space between panels
|
||||||
|
|
||||||
|
for (let p=0; p<gId("panels").children.length; p++) {
|
||||||
|
var px = parseInt(Sf[`P${p}X`].value); //first led x
|
||||||
|
var py = parseInt(Sf[`P${p}Y`].value); //first led y
|
||||||
|
var pw = parseInt(Sf[`P${p}W`].value); //width
|
||||||
|
var ph = parseInt(Sf[`P${p}H`].value); //height
|
||||||
|
|
||||||
|
var pb = Sf[`P${p}B`].value == "1"; //bottom
|
||||||
|
var pr = Sf[`P${p}R`].value == "1"; //right
|
||||||
|
var pv = Sf[`P${p}V`].value == "1"; //vertical
|
||||||
|
var ps = Sf[`P${p}S`].checked; //serpentine
|
||||||
|
|
||||||
|
var topLeftX = px*ppL + space; //left margin
|
||||||
|
var topLeftY = py*ppL + space; //top margin
|
||||||
|
|
||||||
|
ctx.lineWidth = 3;
|
||||||
|
ctx.strokeStyle="white";
|
||||||
|
ctx.strokeRect(topLeftX, topLeftY, pw*ppL, ph*ppL); // add space between panels
|
||||||
|
|
||||||
|
var lnX;
|
||||||
|
var lnY;
|
||||||
|
|
||||||
|
//find start led
|
||||||
|
if (pb) //bottom
|
||||||
|
lnY = topLeftY + ph*ppL - ppL/2;
|
||||||
|
else //top
|
||||||
|
lnY = topLeftY + ppL/2;
|
||||||
|
if (pr) //right
|
||||||
|
lnX = topLeftX + pw*ppL - ppL/2;
|
||||||
|
else //left
|
||||||
|
lnX = topLeftX + ppL/2;
|
||||||
|
|
||||||
|
//first led
|
||||||
|
ctx.fillStyle = "green";
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(lnX, lnY, ppL*0.5, 0, 2 * Math.PI);
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
//start line
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(lnX, lnY);
|
||||||
|
|
||||||
|
var longLineLength = (pv?ph:pw)*ppL - ppL;
|
||||||
|
for (let ln=0; ln<(pv?pw:ph); ln++) { //loop over panelwidth (or height of vertical?)
|
||||||
|
|
||||||
|
var serpLine = ps && ln%2!=0; //serp: turn around if even line
|
||||||
|
|
||||||
|
if (pv) //if vertical
|
||||||
|
lnY += (pb?-1:1) * longLineLength * (serpLine?-1:1); //if vertical change the Y
|
||||||
|
else
|
||||||
|
lnX += (pr?-1:1) * longLineLength * (serpLine?-1:1); //if horizontal change the X
|
||||||
|
|
||||||
|
ctx.lineTo(lnX, lnY); //draw the long line
|
||||||
|
|
||||||
|
if (ln<(pv?pw:ph)-1) { //not the last
|
||||||
|
//find the small line end point
|
||||||
|
if (pv) //vertical
|
||||||
|
lnX += (pr?-1:1) * ppL;
|
||||||
|
else //horizontal
|
||||||
|
lnY += (pb?-1:1) * ppL;
|
||||||
|
|
||||||
|
//if serpentine go next else go down
|
||||||
|
if (ps) { //serpentine
|
||||||
|
ctx.lineTo(lnX, lnY); //draw the serpentine line
|
||||||
|
} else {
|
||||||
|
//find the other end of the long line
|
||||||
|
if (pv) //vertical
|
||||||
|
lnY += (pb?1:-1) * longLineLength * (serpLine?-1:1); //min as we go back
|
||||||
|
else //horizontal
|
||||||
|
lnX += (pr?1:-1) * longLineLength * (serpLine?-1:1);
|
||||||
|
ctx.moveTo(lnX, lnY); //move to the start point of the next long line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
//last led
|
||||||
|
ctx.fillStyle = "red";
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(lnX, lnY, ppL*0.5, 0, 2 * Math.PI);
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
ctx.font = '40px Arial';
|
||||||
|
ctx.fillStyle = "orange";
|
||||||
|
ctx.fillText(p, topLeftX + pw/2*ppL - 10, topLeftY + ph/2*ppL + 10);
|
||||||
|
}
|
||||||
|
gId("MD").innerHTML = "Matrix Dimensions (W*H=LC): " + maxWidth + " x " + maxHeight + " = " + maxWidth * maxHeight;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>@import url("style.css");</style>
|
<style>@import url("style.css");</style>
|
||||||
@ -197,8 +321,8 @@ Y:<input name="P${i}Y" type="number" min="0" max="256" value="0"><br><i>(offset
|
|||||||
<option value="1">Vertical</option>
|
<option value="1">Vertical</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
Serpentine: <input type="checkbox" name="PS"><br>
|
Serpentine: <input type="checkbox" name="PS"><br>
|
||||||
<i style="color:#fa0;">Can populate LED panel layout with pre-arranged matrix.<br>Values from above do not affect final layout.<br>
|
<i style="color:#fa0;">Pressing Populate will create LED panel layout with pre-arranged matrix.<br>Values above <i>will not</i> affect final layout.<br>
|
||||||
WARNING: You will need to update each panel parameters after they are generated.</i><br>
|
WARNING: You may need to update each panel parameters after they are generated.</i><br>
|
||||||
<button type="button" onclick="gen();expand(gId('expGen'),gId('mxGen'));">Populate</button>
|
<button type="button" onclick="gen();expand(gId('expGen'),gId('mxGen'));">Populate</button>
|
||||||
</div>
|
</div>
|
||||||
<hr class="sml">
|
<hr class="sml">
|
||||||
@ -210,6 +334,8 @@ Y:<input name="P${i}Y" type="number" min="0" max="256" value="0"><br><i>(offset
|
|||||||
<div id="panels">
|
<div id="panels">
|
||||||
</div>
|
</div>
|
||||||
<hr class="sml">
|
<hr class="sml">
|
||||||
|
<div id="MD"></div>
|
||||||
|
<canvas id="canvas"></canvas>
|
||||||
<div id="json" >Gap file: <input type="file" name="data" accept=".json"><button type="button" class="sml" onclick="uploadFile('/2d-gaps.json')">Upload</button></div>
|
<div id="json" >Gap file: <input type="file" name="data" accept=".json"><button type="button" class="sml" onclick="uploadFile('/2d-gaps.json')">Upload</button></div>
|
||||||
<i>Note: Gap file is a <b>.json</b> file containing an array with number of elements equal to the matrix size.<br>
|
<i>Note: Gap file is a <b>.json</b> file containing an array with number of elements equal to the matrix size.<br>
|
||||||
A value of -1 means that pixel at that position is missing, a value of 0 means never paint that pixel, and 1 means regular pixel.</i>
|
A value of -1 means that pixel at that position is missing, a value of 0 means never paint that pixel, and 1 means regular pixel.</i>
|
||||||
|
@ -641,7 +641,8 @@ Length: <input type="number" name="XC${i}" id="xc${i}" class="l" min="1" max="65
|
|||||||
Apply preset <input name="BP" type="number" class="m" min="0" max="250" required> at boot (0 uses defaults)
|
Apply preset <input name="BP" type="number" class="m" min="0" max="250" required> at boot (0 uses defaults)
|
||||||
<br><br>
|
<br><br>
|
||||||
Use Gamma correction for color: <input type="checkbox" name="GC"> (strongly recommended)<br>
|
Use Gamma correction for color: <input type="checkbox" name="GC"> (strongly recommended)<br>
|
||||||
Use Gamma correction for brightness: <input type="checkbox" name="GB"> (not recommended)<br><br>
|
Use Gamma correction for brightness: <input type="checkbox" name="GB"> (not recommended)<br>
|
||||||
|
Use Gamma value: <input name="GV" type="number" class="m" placeholder="2.8" min="1" max="3" step="0.1" required><br><br>
|
||||||
Brightness factor: <input name="BF" type="number" class="m" min="1" max="255" required> %
|
Brightness factor: <input name="BF" type="number" class="m" min="1" max="255" required> %
|
||||||
<h3>Transitions</h3>
|
<h3>Transitions</h3>
|
||||||
Crossfade: <input type="checkbox" name="TF"><br>
|
Crossfade: <input type="checkbox" name="TF"><br>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -208,6 +208,14 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
if (t <= 250) bootPreset = t;
|
if (t <= 250) bootPreset = t;
|
||||||
gammaCorrectBri = request->hasArg(F("GB"));
|
gammaCorrectBri = request->hasArg(F("GB"));
|
||||||
gammaCorrectCol = request->hasArg(F("GC"));
|
gammaCorrectCol = request->hasArg(F("GC"));
|
||||||
|
gammaCorrectVal = request->arg(F("GV")).toFloat();
|
||||||
|
if (gammaCorrectVal > 1.0f && gammaCorrectVal <= 3)
|
||||||
|
calcGammaTable(gammaCorrectVal);
|
||||||
|
else {
|
||||||
|
gammaCorrectVal = 1.0f; // no gamma correction
|
||||||
|
gammaCorrectBri = false;
|
||||||
|
gammaCorrectCol = false;
|
||||||
|
}
|
||||||
|
|
||||||
fadeTransition = request->hasArg(F("TF"));
|
fadeTransition = request->hasArg(F("TF"));
|
||||||
t = request->arg(F("TD")).toInt();
|
t = request->arg(F("TD")).toInt();
|
||||||
@ -240,6 +248,10 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
}
|
}
|
||||||
simplifiedUI = request->hasArg(F("SU"));
|
simplifiedUI = request->hasArg(F("SU"));
|
||||||
#endif
|
#endif
|
||||||
|
DEBUG_PRINTLN(F("Enumerating ledmaps"));
|
||||||
|
enumerateLedmaps();
|
||||||
|
DEBUG_PRINTLN(F("Loading custom palettes"));
|
||||||
|
strip.loadCustomPalettes(); // (re)load all custom palettes
|
||||||
}
|
}
|
||||||
|
|
||||||
//SYNC
|
//SYNC
|
||||||
@ -648,10 +660,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
strip.panel.clear(); // release memory if allocated
|
strip.panel.clear(); // release memory if allocated
|
||||||
if (strip.isMatrix) {
|
if (strip.isMatrix) {
|
||||||
strip.panels = MAX(1,MIN(WLED_MAX_PANELS,request->arg(F("MPC")).toInt()));
|
strip.panels = MAX(1,MIN(WLED_MAX_PANELS,request->arg(F("MPC")).toInt()));
|
||||||
strip.matrix.bottomStart = request->arg(F("PB")).toInt();
|
|
||||||
strip.matrix.rightStart = request->arg(F("PR")).toInt();
|
|
||||||
strip.matrix.vertical = request->arg(F("PV")).toInt();
|
|
||||||
strip.matrix.serpentine = request->hasArg(F("PS"));
|
|
||||||
strip.panel.reserve(strip.panels); // pre-allocate memory
|
strip.panel.reserve(strip.panels); // pre-allocate memory
|
||||||
for (uint8_t i=0; i<strip.panels; i++) {
|
for (uint8_t i=0; i<strip.panels; i++) {
|
||||||
WS2812FX::Panel p;
|
WS2812FX::Panel p;
|
||||||
@ -673,6 +681,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
}
|
}
|
||||||
strip.setUpMatrix(); // will check limits
|
strip.setUpMatrix(); // will check limits
|
||||||
strip.makeAutoSegments(true);
|
strip.makeAutoSegments(true);
|
||||||
|
strip.deserializeMap();
|
||||||
} else {
|
} else {
|
||||||
Segment::maxWidth = strip.getLengthTotal();
|
Segment::maxWidth = strip.getLengthTotal();
|
||||||
Segment::maxHeight = 1;
|
Segment::maxHeight = 1;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2302080
|
#define VERSION 2302120
|
||||||
|
|
||||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||||
//#define WLED_USE_MY_CONFIG
|
//#define WLED_USE_MY_CONFIG
|
||||||
@ -319,6 +319,7 @@ WLED_GLOBAL bool correctWB _INIT(false); // CCT color correction of RGB co
|
|||||||
WLED_GLOBAL bool cctFromRgb _INIT(false); // CCT is calculated from RGB instead of using seg.cct
|
WLED_GLOBAL bool cctFromRgb _INIT(false); // CCT is calculated from RGB instead of using seg.cct
|
||||||
WLED_GLOBAL bool gammaCorrectCol _INIT(true ); // use gamma correction on colors
|
WLED_GLOBAL bool gammaCorrectCol _INIT(true ); // use gamma correction on colors
|
||||||
WLED_GLOBAL bool gammaCorrectBri _INIT(false); // use gamma correction on brightness
|
WLED_GLOBAL bool gammaCorrectBri _INIT(false); // use gamma correction on brightness
|
||||||
|
WLED_GLOBAL float gammaCorrectVal _INIT(2.8f); // gamma correction value
|
||||||
|
|
||||||
WLED_GLOBAL byte col[] _INIT_N(({ 255, 160, 0, 0 })); // current RGB(W) primary color. col[] should be updated if you want to change the color.
|
WLED_GLOBAL byte col[] _INIT_N(({ 255, 160, 0, 0 })); // current RGB(W) primary color. col[] should be updated if you want to change the color.
|
||||||
WLED_GLOBAL byte colSec[] _INIT_N(({ 0, 0, 0, 0 })); // current RGB(W) secondary color
|
WLED_GLOBAL byte colSec[] _INIT_N(({ 0, 0, 0, 0 })); // current RGB(W) secondary color
|
||||||
|
@ -364,7 +364,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
|
|
||||||
if (subPage == 2)
|
if (subPage == 2)
|
||||||
{
|
{
|
||||||
char nS[8];
|
char nS[32];
|
||||||
|
|
||||||
appendGPIOinfo();
|
appendGPIOinfo();
|
||||||
|
|
||||||
@ -445,6 +445,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
|
|
||||||
sappend('c',SET_F("GB"),gammaCorrectBri);
|
sappend('c',SET_F("GB"),gammaCorrectBri);
|
||||||
sappend('c',SET_F("GC"),gammaCorrectCol);
|
sappend('c',SET_F("GC"),gammaCorrectCol);
|
||||||
|
sprintf_P(nS, PSTR("d.Sf.GV.value='%.1f';"), (float)gammaCorrectVal); oappend(nS);
|
||||||
sappend('c',SET_F("TF"),fadeTransition);
|
sappend('c',SET_F("TF"),fadeTransition);
|
||||||
sappend('v',SET_F("TD"),transitionDelayDefault);
|
sappend('v',SET_F("TD"),transitionDelayDefault);
|
||||||
sappend('c',SET_F("PF"),strip.paletteFade);
|
sappend('c',SET_F("PF"),strip.paletteFade);
|
||||||
@ -738,10 +739,6 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('v',SET_F("PH"),strip.panel[0].height);
|
sappend('v',SET_F("PH"),strip.panel[0].height);
|
||||||
}
|
}
|
||||||
sappend('v',SET_F("MPC"),strip.panels);
|
sappend('v',SET_F("MPC"),strip.panels);
|
||||||
sappend('v',SET_F("PB"),strip.matrix.bottomStart);
|
|
||||||
sappend('v',SET_F("PR"),strip.matrix.rightStart);
|
|
||||||
sappend('v',SET_F("PV"),strip.matrix.vertical);
|
|
||||||
sappend('c',SET_F("PS"),strip.matrix.serpentine);
|
|
||||||
// panels
|
// panels
|
||||||
for (uint8_t i=0; i<strip.panels; i++) {
|
for (uint8_t i=0; i<strip.panels; i++) {
|
||||||
char n[5];
|
char n[5];
|
||||||
|
Loading…
Reference in New Issue
Block a user