diff --git a/platformio.ini b/platformio.ini
index faa6f162a..f137a6d66 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -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
diff --git a/wled00/FX.cpp b/wled00/FX.cpp
index cf46bf28c..9f7568028 100644
--- a/wled00/FX.cpp
+++ b/wled00/FX.cpp
@@ -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()
diff --git a/wled00/FX.h b/wled00/FX.h
index 9a910108d..afdf0103c 100644
--- a/wled00/FX.h
+++ b/wled00/FX.h
@@ -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
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index 1e1bbab2d..c7ee98f86 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -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);
diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h
index ab3156ff4..721183832 100644
--- a/wled00/bus_manager.h
+++ b/wled00/bus_manager.h
@@ -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
diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp
index c4fdbde6d..a00213371 100644
--- a/wled00/cfg.cpp
+++ b/wled00/cfg.cpp
@@ -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");
diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm
index 86cdb510d..8dd81e446 100644
--- a/wled00/data/settings_leds.htm
+++ b/wled00/data/settings_leds.htm
@@ -571,6 +571,7 @@ ${i+1}:
+ Target refresh rate: FPS