From 754682577c62a8942643cdcd8f930a3f5c6bc479 Mon Sep 17 00:00:00 2001 From: Christian Schwinne Date: Thu, 30 Dec 2021 01:48:27 +0100 Subject: [PATCH] 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 --- platformio.ini | 4 +++- wled00/FX.cpp | 4 ++-- wled00/FX.h | 9 +++++++-- wled00/FX_fcn.cpp | 27 ++++++++++++++++++--------- wled00/bus_manager.h | 4 ++-- wled00/cfg.cpp | 2 ++ wled00/data/settings_leds.htm | 1 + wled00/html_settings.h | 9 +++++---- wled00/json.cpp | 2 +- wled00/set.cpp | 1 + wled00/xml.cpp | 1 + 11 files changed, 43 insertions(+), 21 deletions(-) diff --git a/platformio.ini b/platformio.ini index faa6f162..f137a6d6 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 cf46bf28..9f756802 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 9a910108..afdf0103 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 1e1bbab2..c7ee98f8 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 ab3156ff..72118383 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 c4fdbde6..a0021337 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 86cdb510..8dd81e44 100644 --- a/wled00/data/settings_leds.htm +++ b/wled00/data/settings_leds.htm @@ -571,6 +571,7 @@ ${i+1}:
+ Target refresh rate: FPS
Config template:

diff --git a/wled00/html_settings.h b/wled00/html_settings.h index 3655872f..4f828fe9 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -156,9 +156,10 @@ CCT additive blending: %%

Advanced

Palette blending:

Config template: None (not recommended)
+Target refresh rate: FPS
Config template:

)====="; @@ -338,7 +339,7 @@ type="submit">Save)====="; // Autogenerated from wled00/data/settings_time.htm, do not edit!! const char PAGE_settings_time[] PROGMEM = R"=====( Time Settings