Configurable framerate (#2444)
Updated arduino core versions Better performance on esp32 core 3.x due to IRAM_ATTR Fixed analog busses init to full white/on
This commit is contained in:
parent
736053e24e
commit
754682577c
@ -54,13 +54,14 @@ extra_configs =
|
||||
arduino_core_2_6_3 = espressif8266@2.3.3
|
||||
arduino_core_2_7_4 = espressif8266@2.6.2
|
||||
arduino_core_3_0_0 = espressif8266@3.0.0
|
||||
arduino_core_3_0_2 = espressif8266@3.2.0
|
||||
|
||||
# Development platforms
|
||||
arduino_core_develop = https://github.com/platformio/platform-espressif8266#develop
|
||||
arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/stage
|
||||
|
||||
# Platform to use for ESP8266
|
||||
platform_wled_default = ${common.arduino_core_2_7_4}
|
||||
platform_wled_default = ${common.arduino_core_3_0_2}
|
||||
# We use 2.7.4.7 for all, includes PWM flicker fix and Wstring optimization
|
||||
platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
|
||||
platformio/toolchain-xtensa @ ~2.40802.200502
|
||||
@ -105,6 +106,7 @@ build_flags =
|
||||
-DBEARSSL_SSL_BASIC
|
||||
-D CORE_DEBUG_LEVEL=0
|
||||
-D NDEBUG
|
||||
-Dregister=
|
||||
#build_flags for the IRremoteESP8266 library (enabled decoders have to appear here)
|
||||
-D _IR_ENABLE_DEFAULT_=false
|
||||
-D DECODE_HASH=true
|
||||
|
@ -2091,7 +2091,7 @@ uint16_t WS2812FX::mode_colortwinkle()
|
||||
}
|
||||
}
|
||||
}
|
||||
return FRAMETIME;
|
||||
return FRAMETIME_FIXED;
|
||||
}
|
||||
|
||||
|
||||
@ -2876,7 +2876,7 @@ uint16_t WS2812FX::candle(bool multi)
|
||||
}
|
||||
}
|
||||
|
||||
return FRAMETIME;
|
||||
return FRAMETIME_FIXED;
|
||||
}
|
||||
|
||||
uint16_t WS2812FX::mode_candle()
|
||||
|
@ -48,7 +48,8 @@
|
||||
|
||||
/* Not used in all effects yet */
|
||||
#define WLED_FPS 42
|
||||
#define FRAMETIME (1000/WLED_FPS)
|
||||
#define FRAMETIME_FIXED (1000/WLED_FPS)
|
||||
#define FRAMETIME _frametime
|
||||
|
||||
/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of
|
||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||
@ -71,7 +72,7 @@
|
||||
#define FAIR_DATA_PER_SEG (MAX_SEGMENT_DATA / MAX_NUM_SEGMENTS)
|
||||
|
||||
#define LED_SKIP_AMOUNT 1
|
||||
#define MIN_SHOW_DELAY 15
|
||||
#define MIN_SHOW_DELAY (_frametime < 16 ? 8 : 15)
|
||||
|
||||
#define NUM_COLORS 3 /* number of colors per segment */
|
||||
#define SEGMENT _segments[_segment_index]
|
||||
@ -655,6 +656,7 @@ class WS2812FX {
|
||||
setPixelColor(uint16_t n, uint32_t c),
|
||||
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||
show(void),
|
||||
setTargetFps(uint8_t fps),
|
||||
setPixelSegment(uint8_t n),
|
||||
deserializeMap(uint8_t n=0);
|
||||
|
||||
@ -685,6 +687,7 @@ class WS2812FX {
|
||||
getActiveSegmentsNum(void),
|
||||
//getFirstSelectedSegment(void),
|
||||
getMainSegmentId(void),
|
||||
getTargetFps(void),
|
||||
gamma8(uint8_t),
|
||||
gamma8_cal(uint8_t, float),
|
||||
sin_gap(uint16_t),
|
||||
@ -856,6 +859,8 @@ class WS2812FX {
|
||||
uint16_t _usedSegmentData = 0;
|
||||
uint16_t _transitionDur = 750;
|
||||
|
||||
uint8_t _targetFps = 42;
|
||||
uint16_t _frametime = (1000/42);
|
||||
uint16_t _cumulativeFps = 2;
|
||||
|
||||
bool
|
||||
|
@ -165,12 +165,12 @@ void WS2812FX::service() {
|
||||
_triggered = false;
|
||||
}
|
||||
|
||||
void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
|
||||
void IRAM_ATTR WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
|
||||
setPixelColor(n, R(c), G(c), B(c), W(c));
|
||||
}
|
||||
|
||||
//used to map from segment index to physical pixel, taking into account grouping, offsets, reverse and mirroring
|
||||
uint16_t WS2812FX::realPixelIndex(uint16_t i) {
|
||||
uint16_t IRAM_ATTR WS2812FX::realPixelIndex(uint16_t i) {
|
||||
int16_t iGroup = i * SEGMENT.groupLength();
|
||||
|
||||
/* reverse just an individual segment */
|
||||
@ -187,7 +187,7 @@ uint16_t WS2812FX::realPixelIndex(uint16_t i) {
|
||||
return realIndex;
|
||||
}
|
||||
|
||||
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
||||
void IRAM_ATTR WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
||||
{
|
||||
if (SEGLEN) {//from segment
|
||||
uint16_t realIndex = realPixelIndex(i);
|
||||
@ -350,6 +350,15 @@ uint16_t WS2812FX::getFps() {
|
||||
return _cumulativeFps +1;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getTargetFps() {
|
||||
return _targetFps;
|
||||
}
|
||||
|
||||
void WS2812FX::setTargetFps(uint8_t fps) {
|
||||
if (fps > 0 && fps <= 120) _targetFps = fps;
|
||||
_frametime = 1000 / _targetFps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the next frame to be computed on all active segments.
|
||||
*/
|
||||
@ -775,7 +784,7 @@ void WS2812FX::setTransitionMode(bool t)
|
||||
/*
|
||||
* color blend function
|
||||
*/
|
||||
uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16) {
|
||||
uint32_t IRAM_ATTR WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16) {
|
||||
if(blend == 0) return color1;
|
||||
uint16_t blendmax = b16 ? 0xFFFF : 0xFF;
|
||||
if(blend == blendmax) return color2;
|
||||
@ -878,13 +887,13 @@ void WS2812FX::blur(uint8_t blur_amount)
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t WS2812FX::triwave16(uint16_t in)
|
||||
uint16_t IRAM_ATTR WS2812FX::triwave16(uint16_t in)
|
||||
{
|
||||
if (in < 0x8000) return in *2;
|
||||
return 0xFFFF - (in - 0x8000)*2;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::sin_gap(uint16_t in) {
|
||||
uint8_t IRAM_ATTR WS2812FX::sin_gap(uint16_t in) {
|
||||
if (in & 0x100) return 0;
|
||||
//if (in > 255) return 0;
|
||||
return sin8(in + 192); //correct phase shift of sine so that it starts and stops at 0
|
||||
@ -951,13 +960,13 @@ uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) {
|
||||
}
|
||||
|
||||
|
||||
uint32_t WS2812FX::crgb_to_col(CRGB fastled)
|
||||
uint32_t IRAM_ATTR WS2812FX::crgb_to_col(CRGB fastled)
|
||||
{
|
||||
return RGBW32(fastled.red, fastled.green, fastled.blue, 0);
|
||||
}
|
||||
|
||||
|
||||
CRGB WS2812FX::col_to_crgb(uint32_t color)
|
||||
CRGB IRAM_ATTR WS2812FX::col_to_crgb(uint32_t color)
|
||||
{
|
||||
CRGB fastled_col;
|
||||
fastled_col.red = R(color);
|
||||
@ -1080,7 +1089,7 @@ void WS2812FX::handle_palette(void)
|
||||
* @param pbri Value to scale the brightness of the returned color by. Default is 255. (no scaling)
|
||||
* @returns Single color from palette
|
||||
*/
|
||||
uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri)
|
||||
uint32_t IRAM_ATTR WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri)
|
||||
{
|
||||
if (SEGMENT.palette == 0 && mcol < 3) {
|
||||
uint32_t color = SEGCOLOR(mcol);
|
||||
|
@ -288,7 +288,7 @@ class BusPwm : public Bus {
|
||||
if (!pinManager.allocatePin(currentPin, true, PinOwner::BusPwm)) {
|
||||
deallocatePins(); return;
|
||||
}
|
||||
_pins[i] = currentPin; // store only after allocatePin() succeeds
|
||||
_pins[i] = currentPin; //store only after allocatePin() succeeds
|
||||
#ifdef ESP8266
|
||||
pinMode(_pins[i], OUTPUT);
|
||||
#else
|
||||
@ -397,7 +397,7 @@ class BusPwm : public Bus {
|
||||
|
||||
private:
|
||||
uint8_t _pins[5] = {255, 255, 255, 255, 255};
|
||||
uint8_t _data[5] = {255, 255, 255, 255, 255};
|
||||
uint8_t _data[5] = {0};
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
uint8_t _ledcStart = 255;
|
||||
#endif
|
||||
|
@ -85,6 +85,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
CJSON(cctFromRgb, hw_led[F("cr")]);
|
||||
CJSON(strip.cctBlending, hw_led[F("cb")]);
|
||||
Bus::setCCTBlend(strip.cctBlending);
|
||||
strip.setTargetFps(hw_led["fps"]); //NOP if 0, default 42 FPS
|
||||
|
||||
JsonArray ins = hw_led["ins"];
|
||||
|
||||
@ -539,6 +540,7 @@ void serializeConfig() {
|
||||
hw_led["cct"] = correctWB;
|
||||
hw_led[F("cr")] = cctFromRgb;
|
||||
hw_led[F("cb")] = strip.cctBlending;
|
||||
hw_led["fps"] = strip.getTargetFps();
|
||||
hw_led[F("rgbwm")] = Bus::getAutoWhiteMode();
|
||||
|
||||
JsonArray hw_led_ins = hw_led.createNestedArray("ins");
|
||||
|
@ -571,6 +571,7 @@ ${i+1}:
|
||||
<option value="2">Linear (never wrap)</option>
|
||||
<option value="3">None (not recommended)</option>
|
||||
</select><br>
|
||||
Target refresh rate: <input type="number" class="s" min="1" max="120" name="FR" required> FPS
|
||||
<hr style="width:260px">
|
||||
<div id="cfg">Config template: <input type="file" name="data2" accept=".json"> <input type="button" value="Apply" onclick="loadCfg(d.Sf.data2);"><br></div>
|
||||
<hr>
|
||||
|
@ -156,9 +156,10 @@ CCT additive blending: <input type="number" class="s" min="0" max="100"
|
||||
name="CB" required> %%</span><h3>Advanced</h3>Palette blending: <select
|
||||
name="PB"><option value="0">Linear (wrap if moving)</option><option value="1">
|
||||
Linear (always wrap)</option><option value="2">Linear (never wrap)</option>
|
||||
<option value="3">None (not recommended)</option></select><br><hr
|
||||
style="width:260px"><div id="cfg">Config template: <input type="file"
|
||||
name="data2" accept=".json"> <input type="button" value="Apply"
|
||||
<option value="3">None (not recommended)</option></select><br>
|
||||
Target refresh rate: <input type="number" class="s" min="1" max="120" name="FR"
|
||||
required> FPS<hr style="width:260px"><div id="cfg">Config template: <input
|
||||
type="file" name="data2" accept=".json"> <input type="button" value="Apply"
|
||||
onclick="loadCfg(d.Sf.data2)"><br></div><hr><button type="button" onclick="B()">
|
||||
Back</button><button type="submit">Save</button></form></body></html>)=====";
|
||||
|
||||
@ -338,7 +339,7 @@ type="submit">Save</button></form></body></html>)=====";
|
||||
// Autogenerated from wled00/data/settings_time.htm, do not edit!!
|
||||
const char PAGE_settings_time[] PROGMEM = R"=====(<!DOCTYPE html><html lang="en"><head><meta name="viewport" content="width=500">
|
||||
<meta charset="utf-8"><title>Time Settings</title><script>
|
||||
var d=document;function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings")}function B(){window.open("/settings","_self")}function S(){BTa(),GetV(),Cs(),FC()}function gId(e){return d.getElementById(e)}function Cs(){gId("cac").style.display="none",gId("coc").style.display="block",gId("ccc").style.display="none",gId("ca").selected&&(gId("cac").style.display="block"),gId("cc").selected&&(gId("coc").style.display="none",gId("ccc").style.display="block"),gId("cn").selected&&(gId("coc").style.display="none")}function BTa(){var e="<tr><th>Active</th><th>Hour</th><th>Minute</th><th>Preset</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr>";for(i=0;i<8;i++)for(e+='<tr><td><input name="W'+i+'" id="W'+i+'" type="number" style="display:none"><input id="W'+i+'0" type="checkbox"></td><td><input name="H'+i+'" type="number" min="0" max="24"></td><td><input name="N'+i+'" type="number" min="0" max="59"></td><td><input name="T'+i+'" type="number" min="0" max="250"></td>',j=1;j<8;j++)e+='<td><input id="W'+i+j+'" type="checkbox"></td>';for(e+='<tr><td><input name="W8" id="W8" type="number" style="display:none"><input id="W80" type="checkbox"></td><td>Sunrise<input name="H8" value="255" type="hidden"></td><td><input name="N8" type="number" min="-59" max="59"></td><td><input name="T8" type="number" min="0" max="250"></td>',j=1;j<8;j++)e+='<td><input id="W8'+j+'" type="checkbox"></td>';for(e+='<tr><td><input name="W9" id="W9" type="number" style="display:none"><input id="W90" type="checkbox"></td><td>Sunset<input name="H9" value="255" type="hidden"></td><td><input name="N9" type="number" min="-59" max="59"><td><input name="T9" type="number" min="0" max="250"></td>',j=1;j<8;j++)e+='<td><input id="W9'+j+'" type="checkbox"></td>';gId("TMT").innerHTML=e}function FC(){for(j=0;j<8;j++)for(i=0;i<10;i++)gId("W"+i+j).checked=gId("W"+i).value>>j&1}function Wd(){for(a=[0,0,0,0,0,0,0,0,0,0],i=0;i<10;i++){for(m=1,j=0;j<8;j++)a[i]+=gId("W"+i+j).checked*m,m*=2;gId("W"+i).value=a[i]}"S"===d.Sf.LTR.value&&(d.Sf.LT.value=-1*parseFloat(d.Sf.LT.value)),"W"===d.Sf.LNR.value&&(d.Sf.LN.value=-1*parseFloat(d.Sf.LN.value))}function addRow(e,t,n,i){var d=gId("macros"),a=d.rows.length,u=d.insertRow(a),l=String.fromCharCode((e<10?48:55)+e);document.createElement("td");u.insertCell(0).innerHTML=`Button ${e}:`,u.insertCell(1).innerHTML=`<input name="MP${l}" type="number" min="0" max="250" value="${t}" required>`,u.insertCell(2).innerHTML=`<input name="ML${l}" type="number" min="0" max="250" value="${n}" required>`,u.insertCell(3).innerHTML=`<input name="MD${l}" type="number" min="0" max="250" value="${i}" required>`}function updLoc(e){parseFloat(d.Sf.LT.value)<0?(d.Sf.LTR.value="S",d.Sf.LT.value=-1*parseFloat(d.Sf.LT.value)):d.Sf.LTR.value="N",parseFloat(d.Sf.LN.value)<0?(d.Sf.LNR.value="W",d.Sf.LN.value=-1*parseFloat(d.Sf.LN.value)):d.Sf.LNR.value="E"}function GetV() {
|
||||
var d=document;function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings")}function B(){window.open("/settings","_self")}function S(){BTa(),GetV(),updLoc(),Cs(),FC()}function gId(e){return d.getElementById(e)}function Cs(){gId("cac").style.display="none",gId("coc").style.display="block",gId("ccc").style.display="none",gId("ca").selected&&(gId("cac").style.display="block"),gId("cc").selected&&(gId("coc").style.display="none",gId("ccc").style.display="block"),gId("cn").selected&&(gId("coc").style.display="none")}function BTa(){var e="<tr><th>Active</th><th>Hour</th><th>Minute</th><th>Preset</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr>";for(i=0;i<8;i++)for(e+='<tr><td><input name="W'+i+'" id="W'+i+'" type="number" style="display:none"><input id="W'+i+'0" type="checkbox"></td><td><input name="H'+i+'" type="number" min="0" max="24"></td><td><input name="N'+i+'" type="number" min="0" max="59"></td><td><input name="T'+i+'" type="number" min="0" max="250"></td>',j=1;j<8;j++)e+='<td><input id="W'+i+j+'" type="checkbox"></td>';for(e+='<tr><td><input name="W8" id="W8" type="number" style="display:none"><input id="W80" type="checkbox"></td><td>Sunrise<input name="H8" value="255" type="hidden"></td><td><input name="N8" type="number" min="-59" max="59"></td><td><input name="T8" type="number" min="0" max="250"></td>',j=1;j<8;j++)e+='<td><input id="W8'+j+'" type="checkbox"></td>';for(e+='<tr><td><input name="W9" id="W9" type="number" style="display:none"><input id="W90" type="checkbox"></td><td>Sunset<input name="H9" value="255" type="hidden"></td><td><input name="N9" type="number" min="-59" max="59"><td><input name="T9" type="number" min="0" max="250"></td>',j=1;j<8;j++)e+='<td><input id="W9'+j+'" type="checkbox"></td>';gId("TMT").innerHTML=e}function FC(){for(j=0;j<8;j++)for(i=0;i<10;i++)gId("W"+i+j).checked=gId("W"+i).value>>j&1}function Wd(){for(a=[0,0,0,0,0,0,0,0,0,0],i=0;i<10;i++){for(m=1,j=0;j<8;j++)a[i]+=gId("W"+i+j).checked*m,m*=2;gId("W"+i).value=a[i]}"S"===d.Sf.LTR.value&&(d.Sf.LT.value=-1*parseFloat(d.Sf.LT.value)),"W"===d.Sf.LNR.value&&(d.Sf.LN.value=-1*parseFloat(d.Sf.LN.value))}function addRow(e,t,n,i){var d=gId("macros"),a=d.rows.length,u=d.insertRow(a),l=String.fromCharCode((e<10?48:55)+e);document.createElement("td");u.insertCell(0).innerHTML=`Button ${e}:`,u.insertCell(1).innerHTML=`<input name="MP${l}" type="number" min="0" max="250" value="${t}" required>`,u.insertCell(2).innerHTML=`<input name="ML${l}" type="number" min="0" max="250" value="${n}" required>`,u.insertCell(3).innerHTML=`<input name="MD${l}" type="number" min="0" max="250" value="${i}" required>`}function updLoc(e){parseFloat(d.Sf.LT.value)<0?(d.Sf.LTR.value="S",d.Sf.LT.value=-1*parseFloat(d.Sf.LT.value)):d.Sf.LTR.value="N",parseFloat(d.Sf.LN.value)<0?(d.Sf.LNR.value="W",d.Sf.LN.value=-1*parseFloat(d.Sf.LN.value)):d.Sf.LNR.value="E"}function GetV() {
|
||||
%CSS%%SCSS%</head><body onload="S()"><form
|
||||
id="form_s" name="Sf" method="post" onsubmit="Wd()"><div class="helpB"><button
|
||||
type="button" onclick="H()">?</button></div><button type="button" onclick="B()">
|
||||
|
@ -519,7 +519,7 @@ void serializeInfo(JsonObject root)
|
||||
}
|
||||
|
||||
leds[F("pwr")] = strip.currentMilliamps;
|
||||
leds[F("fps")] = strip.getFps();
|
||||
leds["fps"] = strip.getFps();
|
||||
leds[F("maxpwr")] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0;
|
||||
leds[F("maxseg")] = strip.getMaxSegments();
|
||||
//leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config
|
||||
|
@ -100,6 +100,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
strip.cctBlending = request->arg(F("CB")).toInt();
|
||||
Bus::setCCTBlend(strip.cctBlending);
|
||||
Bus::setAutoWhiteMode(request->arg(F("AW")).toInt());
|
||||
strip.setTargetFps(request->arg(F("FR")).toInt());
|
||||
|
||||
for (uint8_t s = 0; s < WLED_MAX_BUSSES; s++) {
|
||||
char lp[4] = "L0"; lp[2] = 48+s; lp[3] = 0; //ascii 0-9 //strip data pin
|
||||
|
@ -382,6 +382,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('c',SET_F("CCT"),correctWB);
|
||||
sappend('c',SET_F("CR"),cctFromRgb);
|
||||
sappend('v',SET_F("CB"),strip.cctBlending);
|
||||
sappend('v',SET_F("FR"),strip.getTargetFps());
|
||||
sappend('v',SET_F("AW"),Bus::getAutoWhiteMode());
|
||||
|
||||
for (uint8_t s=0; s < busses.getNumBusses(); s++) {
|
||||
|
Loading…
Reference in New Issue
Block a user