Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved FPS calculation #4250

Merged
merged 3 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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