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 | |
| 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 '')
| -rw-r--r-- | spaghetti-monster/anduril/anduril.c | 41 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-ramping.c | 146 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-ramping.h | 7 |
3 files changed, 190 insertions, 4 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index 91c7b0b..cf6f7f0 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -26,6 +26,7 @@ #define USE_DELAY_4MS #define USE_DELAY_ZERO #define USE_RAMPING +#define USE_SET_LEVEL_GRADUALLY #define RAMP_LENGTH 150 #define USE_BATTCHECK #define BATTCHECK_VpT @@ -127,6 +128,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) { return MISCHIEF_MANAGED; } // go back to sleep eventually if we got bumped but didn't leave "off" state + // FIXME: can I just use arg instead of ticks_spent_awake? else if (event == EV_tick) { ticks_spent_awake ++; if (ticks_spent_awake > 240) { @@ -310,24 +312,55 @@ uint8_t steady_state(EventPtr event, uint16_t arg) { set_level(memorized_level); return MISCHIEF_MANAGED; } + #ifdef USE_SET_LEVEL_GRADUALLY + else if (event == EV_tick) { + //if (!(arg & 7)) gradual_tick(); + if (!(arg & 3)) gradual_tick(); + //gradual_tick(); + return MISCHIEF_MANAGED; + } + #endif #ifdef USE_THERMAL_REGULATION // TODO: test this on a real light // overheating: drop by an amount proportional to how far we are above the ceiling else if (event == EV_temperature_high) { - if (actual_level > MAX_LEVEL/4) { - uint8_t stepdown = actual_level - arg; - if (stepdown < MAX_LEVEL/4) stepdown = MAX_LEVEL/4; + /* + uint8_t foo = actual_level; + set_level(0); + delay_4ms(2); + set_level(foo); + */ + if (actual_level > MAX_LEVEL/3) { + int16_t stepdown = actual_level - arg; + if (stepdown < MAX_LEVEL/3) stepdown = MAX_LEVEL/3; + else if (stepdown > MAX_LEVEL) stepdown = MAX_LEVEL; + #ifdef USE_SET_LEVEL_GRADUALLY + set_level_gradually(stepdown); + #else set_level(stepdown); + #endif } return MISCHIEF_MANAGED; } // underheating: increase slowly if we're lower than the target // (proportional to how low we are) else if (event == EV_temperature_low) { + /* + uint8_t foo = actual_level; + set_level(0); + delay_4ms(2); + set_level(foo); + */ if (actual_level < target_level) { - uint8_t stepup = actual_level + (arg>>1); + //int16_t stepup = actual_level + (arg>>1); + int16_t stepup = actual_level + arg; if (stepup > target_level) stepup = target_level; + else if (stepup < MAX_LEVEL/3) stepup = MAX_LEVEL/3; + #ifdef USE_SET_LEVEL_GRADUALLY + set_level_gradually(stepup); + #else set_level(stepup); + #endif } return MISCHIEF_MANAGED; } 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 diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h index b4054bf..ac4e58c 100644 --- a/spaghetti-monster/fsm-ramping.h +++ b/spaghetti-monster/fsm-ramping.h @@ -26,6 +26,13 @@ // actual_level: last ramp level set by set_level() volatile uint8_t actual_level = 0; +#ifdef USE_SET_LEVEL_GRADUALLY +// adjust brightness very smoothly +volatile uint8_t gradual_target; +inline void set_level_gradually(uint8_t lvl); +void gradual_tick(); +#endif + // ramp tables #if PWM_CHANNELS == 1 #if RAMP_LENGTH == 50 |
