aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster
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
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')
-rw-r--r--spaghetti-monster/anduril/anduril.c41
-rw-r--r--spaghetti-monster/fsm-ramping.c146
-rw-r--r--spaghetti-monster/fsm-ramping.h7
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