-
-
Notifications
You must be signed in to change notification settings - Fork 19.5k
Soft pwm enhancement #6015
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
Soft pwm enhancement #6015
Conversation
A 128 step PWM has 127 intervals (0/127 ... 127/127 duty). Currently, a PWM setting of 1/127 is active for 2/128, i.e. double the expected time, or, in general n+1/128 instead of n/127. Fixes issue#6003. Signed-off-by: Stefan Brüns <[email protected]>
90d12ba
to
676ab2c
Compare
Does the dithering add any performance overhead? |
The performance overhead is very low - AFAICT it adds one machine instruction per PWM channel on each timer interrupt (1kHz). |
Small correction, it is three instructions, but of course only run once every PWM cycle, i.e. 16 times a second for SCALE 1. |
Device: atmega1284p, TinyBoy2 (using U8glib) FW size without SR applied:
With SR:
|
Marlin/temperature.cpp
Outdated
const uint8_t pwm_mask = _BV(SOFT_PWM_SCALE) - 1; | ||
#else | ||
const uint8_t pwm_mask = 0; | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The const
lines should be indented. This is also good:
const uint8_t pwm_mask = 0
#if ENABLED(SOFT_PWM_DITHER)
+ _BV(SOFT_PWM_SCALE) - 1
#endif
;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indented the declaration, fixed the commit subject (s/is/if)
309d737
to
cf6812f
Compare
If dithering is enabled, the remainder of the soft_pwm_X duty value at turnoff time is added to the next cycle. If e.g. the duty is set to 9 and SCALE is set to 2, the PWM will be active for 8 counts for 3 cycles and 12 counts on each fourth cycle, i.e. the average is 9 cycles. This compensates the resolution loss at higher scales and allows running fans with SOFT_PWM with significantly reduced noise. Signed-off-by: Stefan Brüns <[email protected]>
The compiler is not able to reuse the value of pwm_count, but reloads it on every evaluation, if is stored in a static variable, as it cannot prove it will be unchanged. A variable with local scope may not be modified from the outside, so its value can be reused. Doing so reduces text size and instruction count. Signed-off-by: Stefan Brüns <[email protected]>
After wraparound, pwm_count <= pwm_mask holds, thus soft_pwm_X <= pwm_count guarantees soft_pwm_X < pwm_mask is true, and the heater will be switched off in the first branch. Do not evaluate the pwm conditions a second time, this reduces the instruction count (4 instructions per PWM) and text size (6 byte). Signed-off-by: Stefan Brüns <[email protected]>
cf6812f
to
6b0bac3
Compare
Superseded by #6100 |
Includes fix for #6003: For low duty cyles, the actual duty cycle is larger than wanted
Supersedes #5997
Dithering allows to mitigate the resolution loss caused by the scaling.