Skip to content

Commit

Permalink
Merge pull request Aircoookie#4250 from DedeHai/FPS_calc_averaging
Browse files Browse the repository at this point in the history
Fixed & improved FPS calculation
  • Loading branch information
DedeHai authored Nov 5, 2024
2 parents 70323b9 + 4634ace commit 271a07a
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
11 changes: 10 additions & 1 deletion wled00/FX.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@
#define FRAMETIME_FIXED (1000/WLED_FPS)
#define FRAMETIME strip.getFrameTime()

// FPS calculation (can be defined as compile flag for debugging)
#ifndef FPS_CALC_AVG
#define FPS_CALC_AVG 7 // average FPS calculation over this many frames (moving average)
#endif
#ifndef FPS_MULTIPLIER
#define FPS_MULTIPLIER 1 // dev option: multiplier to get sub-frame FPS without floats
#endif
#define FPS_CALC_SHIFT 7 // bit shift for fixed point math

/* each segment uses 82 bytes of SRAM memory, so if you're application fails because of
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
#ifdef ESP8266
Expand Down Expand Up @@ -729,7 +738,7 @@ class WS2812FX { // 96 bytes
_transitionDur(750),
_targetFps(WLED_FPS),
_frametime(FRAMETIME_FIXED),
_cumulativeFps(2),
_cumulativeFps(50 << FPS_CALC_SHIFT),
_isServicing(false),
_isOffRefreshRequired(false),
_hasWhiteChannel(false),
Expand Down
12 changes: 7 additions & 5 deletions wled00/FX_fcn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1412,10 +1412,12 @@ void WS2812FX::show() {

unsigned long showNow = millis();
size_t diff = showNow - _lastShow;
size_t fpsCurr = 200;
if (diff > 0) fpsCurr = 1000 / diff;
_cumulativeFps = (3 * _cumulativeFps + fpsCurr +2) >> 2; // "+2" for proper rounding (2/4 = 0.5)
_lastShow = showNow;

if (diff > 0) { // skip calculation if no time has passed
size_t fpsCurr = (1000 << FPS_CALC_SHIFT) / diff; // fixed point math
_cumulativeFps = (FPS_CALC_AVG * _cumulativeFps + fpsCurr + FPS_CALC_AVG / 2) / (FPS_CALC_AVG + 1); // "+FPS_CALC_AVG/2" for proper rounding
_lastShow = showNow;
}
}

/**
Expand All @@ -1432,7 +1434,7 @@ bool WS2812FX::isUpdating() const {
*/
uint16_t WS2812FX::getFps() const {
if (millis() - _lastShow > 2000) return 0;
return _cumulativeFps +1;
return (FPS_MULTIPLIER * _cumulativeFps) >> FPS_CALC_SHIFT; // _cumulativeFps is stored in fixed point
}

void WS2812FX::setTargetFps(uint8_t fps) {
Expand Down

0 comments on commit 271a07a

Please sign in to comment.