aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster/fsm-ramping.c
diff options
context:
space:
mode:
authorSelene ToyKeeper2017-09-09 22:58:26 -0600
committerSelene ToyKeeper2017-09-09 22:58:26 -0600
commit7315575b2e7506417c2f2e81846e378d09949b5e (patch)
treedc903bc915ca0e0bef51725a85dd5fe06e99f794 /spaghetti-monster/fsm-ramping.c
parentMade "off" mode more vigilant about staying off. (diff)
downloadanduril-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.c146
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