diff options
| author | Selene ToyKeeper | 2017-09-09 22:58:26 -0600 |
|---|---|---|
| committer | Selene ToyKeeper | 2017-09-09 22:58:26 -0600 |
| commit | 7315575b2e7506417c2f2e81846e378d09949b5e (patch) | |
| tree | dc903bc915ca0e0bef51725a85dd5fe06e99f794 /spaghetti-monster/fsm-ramping.c | |
| parent | Made "off" mode more vigilant about staying off. (diff) | |
| download | anduril-7315575b2e7506417c2f2e81846e378d09949b5e.tar.gz anduril-7315575b2e7506417c2f2e81846e378d09949b5e.tar.bz2 anduril-7315575b2e7506417c2f2e81846e378d09949b5e.zip | |
Made thermal regulation adjust smoothly (1 PWM step at a time) to make adjustments less noticeable.
Added set_level_gradually() and gradual_tick() to ramping lib.
Not terribly happy with it yet, but it at least works in practice.
Added extra thermal regulation checks because I was running into stupid behavior in edge cases.
Increased lowest thermal stepdown level to MAX_LEVEL/3 because it was going down way too low before.
(is still pretty low, but not quite as bad)
Diffstat (limited to 'spaghetti-monster/fsm-ramping.c')
| -rw-r--r-- | spaghetti-monster/fsm-ramping.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c index ab7bd3c..50b4102 100644 --- a/spaghetti-monster/fsm-ramping.c +++ b/spaghetti-monster/fsm-ramping.c @@ -25,6 +25,9 @@ void set_level(uint8_t level) { actual_level = level; + #ifdef USE_SET_LEVEL_GRADUALLY + gradual_target = level; + #endif //TCCR0A = PHASE; if (level == 0) { #if PWM_CHANNELS >= 1 @@ -56,6 +59,149 @@ void set_level(uint8_t level) { } } +#ifdef USE_SET_LEVEL_GRADUALLY +inline void set_level_gradually(uint8_t lvl) { + gradual_target = lvl; +} + +// FIXME: This sucks +// FIXME: I think this can behave badly in some circumstances: +// - large smooth adjustment in progress +// - from something like (255,10) to (200, 0) +// - ... and a new target gets set while actual_level is ... not quite right +// - ... and it then ends up massively overshooting or even turning off +// (still haven't figured out the exact circumstances to cause it) +// (at the very least, actual_level can suddenly jump when multiple PWM levels are being adjusted) +// (so it's bad to rely on actual_level in the middle of a smooth adjustment) +void gradual_tick() { + int8_t changed = 0; + uint8_t target; + uint8_t gt = gradual_target - 1; + // FIXME: rewrite this completely, probably + // (perhaps go by only one ramp level at a time instead of directly to the target?) + #if PWM_CHANNELS >= 1 + target = pgm_read_byte(pwm1_levels + gt); + if (PWM1_LVL < target) { PWM1_LVL ++; changed = 1; } + else if (PWM1_LVL > target) { PWM1_LVL --; changed = -1; } + #endif + #if PWM_CHANNELS >= 2 + target = pgm_read_byte(pwm2_levels + gt); + if (PWM2_LVL < target) { PWM2_LVL ++; changed = 1; } + else if (PWM2_LVL > target) { PWM2_LVL --; changed = -1; } + #endif + #if PWM_CHANNELS >= 3 + target = pgm_read_byte(pwm3_levels + gt); + if (PWM3_LVL < target) { PWM3_LVL ++; changed = 1; } + else if (PWM3_LVL > target) { PWM3_LVL --; changed = -1; } + #endif + #if PWM_CHANNELS >= 4 + target = pgm_read_byte(pwm4_levels + gt); + if (PWM4_LVL < target) { PWM4_LVL ++; changed = 1; } + else if (PWM4_LVL > target) { PWM4_LVL --; changed = -1; } + #endif + // figure out what actual level is + /* + if (changed < 0) { + #if PWM_CHANNELS >= 4 + if (PWM4_LVL < pgm_read_byte(pwm4_levels + actual_level - 1)) + actual_level --; + else + #endif + #if PWM_CHANNELS >= 3 + if (PWM3_LVL < pgm_read_byte(pwm3_levels + actual_level - 1)) + actual_level --; + else + #endif + #if PWM_CHANNELS >= 2 + if (PWM2_LVL < pgm_read_byte(pwm2_levels + actual_level - 1)) + actual_level --; + else + #endif + if (PWM1_LVL < pgm_read_byte(pwm1_levels + actual_level - 1)) + actual_level --; + } + else if (changed > 0) { + #if PWM_CHANNELS >= 4 + if (PWM4_LVL > pgm_read_byte(pwm4_levels + actual_level - 1)) + actual_level ++; + else + #endif + #if PWM_CHANNELS >= 3 + if (PWM3_LVL > pgm_read_byte(pwm3_levels + actual_level - 1)) + actual_level ++; + else + #endif + #if PWM_CHANNELS >= 2 + if (PWM2_LVL > pgm_read_byte(pwm2_levels + actual_level - 1)) + actual_level ++; + else + #endif + if (PWM1_LVL > pgm_read_byte(pwm1_levels + actual_level - 1)) + actual_level ++; + } + else { + actual_level = gradual_target; + } + */ + /* + if (changed) { + #if PWM_CHANNELS >= 4 + if (PWM4_LVL != pgm_read_byte(pwm4_levels + actual_level - 1)) + actual_level += changed; + else + #endif + #if PWM_CHANNELS >= 3 + if (PWM3_LVL != pgm_read_byte(pwm3_levels + actual_level - 1)) + actual_level += changed; + else + #endif + #if PWM_CHANNELS >= 2 + if (PWM2_LVL != pgm_read_byte(pwm2_levels + actual_level - 1)) + actual_level += changed; + else + #endif + if (PWM1_LVL != pgm_read_byte(pwm1_levels + actual_level - 1)) + actual_level += changed; + } else { + actual_level = gradual_target; + } + */ + //if (! changed) { actual_level = gradual_target; } + if (changed) { + #if PWM_CHANNELS >= 4 + if (PWM4_LVL > 0) { + for (actual_level = 0; + (actual_level < MAX_LEVEL) && + (PWM4_LVL <= pgm_read_byte(pwm4_levels + actual_level - 1)); + actual_level ++) {} + } else + #endif + #if PWM_CHANNELS >= 3 + if (PWM3_LVL > 0) { + for (actual_level = 0; + (actual_level < MAX_LEVEL) && + (PWM3_LVL <= pgm_read_byte(pwm3_levels + actual_level - 1)); + actual_level ++) {} + } else + #endif + #if PWM_CHANNELS >= 2 + if (PWM2_LVL > 0) { + for (actual_level = 0; + (actual_level < MAX_LEVEL) && + (PWM2_LVL <= pgm_read_byte(pwm2_levels + actual_level - 1)); + actual_level ++) {} + } else + #endif + for (actual_level = 0; + (actual_level < MAX_LEVEL) && + (PWM1_LVL <= pgm_read_byte(pwm1_levels + actual_level - 1)); + actual_level ++) {} + } else { + actual_level = gradual_target; + } +} +#endif + // TODO: set_lvl_smooth? #endif // ifdef USE_RAMPING |
