more accurate FPS forESP32
the standard millis() code is very inaccurate in the "high FPS" ranges. This replaces it with the esp32 high resolution timer.
This commit is contained in:
@@ -2809,7 +2809,7 @@ uint16_t mode_bouncing_balls(void) {
|
||||
// number of balls based on intensity setting to max of 7 (cycles colors)
|
||||
// non-chosen color is a random color
|
||||
uint16_t numBalls = (SEGMENT.intensity * (maxNumBalls - 1)) / 255 + 1; // minimum 1 ball
|
||||
const float gravity = -9.81; // standard value of gravity
|
||||
constexpr float gravity = -9.81; // standard value of gravity
|
||||
const bool hasCol2 = SEGCOLOR(2);
|
||||
const unsigned long time = millis();
|
||||
|
||||
|
||||
@@ -689,6 +689,10 @@ class WS2812FX { // 96 bytes
|
||||
_targetFps(WLED_FPS),
|
||||
_frametime(FRAMETIME_FIXED),
|
||||
_cumulativeFps(2),
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
_cumulativeFps500(2*500), // WLEDMM more accurate FPS measurement for ESP32
|
||||
_lastShow500(0),
|
||||
#endif
|
||||
_isServicing(false),
|
||||
_isOffRefreshRequired(false),
|
||||
_hasWhiteChannel(false),
|
||||
@@ -907,6 +911,10 @@ class WS2812FX { // 96 bytes
|
||||
uint8_t _targetFps;
|
||||
uint16_t _frametime;
|
||||
uint16_t _cumulativeFps;
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
uint64_t _cumulativeFps500; // WLEDMM more accurate FPS measurement for ESP32
|
||||
uint64_t _lastShow500;
|
||||
#endif
|
||||
|
||||
// will require only 1 byte
|
||||
struct {
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
#include "wled.h"
|
||||
#include "FX.h"
|
||||
#include "palettes.h"
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#include <esp_timer.h> // WLEDMM to get esp_timer_get_time()
|
||||
#endif
|
||||
|
||||
/*
|
||||
Custom per-LED mapping has moved!
|
||||
@@ -206,7 +209,7 @@ void Segment::setUpLeds() {
|
||||
else if (!leds) {
|
||||
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
|
||||
if (psramFound())
|
||||
leds = (CRGB*)ps_malloc(sizeof(CRGB)*length());
|
||||
leds = (CRGB*)ps_malloc(sizeof(CRGB)*length()); // WLEDMM: stupid - PSRAM is too slow for this !!!
|
||||
else
|
||||
#endif
|
||||
leds = (CRGB*)malloc(sizeof(CRGB)*length());
|
||||
@@ -1631,6 +1634,16 @@ void WS2812FX::show(void) {
|
||||
if (diff > 0) fpsCurr = 1000 / diff;
|
||||
_cumulativeFps = (3 * _cumulativeFps + fpsCurr) >> 2;
|
||||
_lastShow = now;
|
||||
#ifdef ARDUINO_ARCH_ESP32 // WLEDMM more accurate FPS measurement for ESP32
|
||||
uint64_t now500 = esp_timer_get_time() / 2; // native timer; micros /2 -> millis * 500
|
||||
int64_t diff500 = now500 - _lastShow500;
|
||||
if ((diff500 > 300) && (diff500 < 800000)) { // exclude stupid values (timer rollover, major hickups)
|
||||
float fpcCurr500 = 500000.0f / float(diff500);
|
||||
if (fpcCurr500 > 2)
|
||||
_cumulativeFps500 = (3 * _cumulativeFps500 + (500.0 * fpcCurr500)) / 4; // average for some smoothing
|
||||
}
|
||||
_lastShow500 = now500;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1647,7 +1660,11 @@ bool WS2812FX::isUpdating() {
|
||||
*/
|
||||
uint16_t WS2812FX::getFps() {
|
||||
if (millis() - _lastShow > 2000) return 0;
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
return ((_cumulativeFps500 + 250) / 500); // +250 for proper rounding
|
||||
#else
|
||||
return _cumulativeFps +1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void WS2812FX::setTargetFps(uint8_t fps) {
|
||||
|
||||
Reference in New Issue
Block a user