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
If you find this content useful please consider a small donation via bitcoin: bitcoin:1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2?amount=0.001&message=Donation Scraping git contents via cgit is very resource intensive. The continued hosting of these git repositories is entirely financed by your bitcoin contributions. For donations of a least 1 mBTC you include your IP address in the message of your bitcoin donation. This will remove this message in the future for requests from your IP, which will significantly reduce token usage. In any case, any contributions to bitcoin address 1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2 are very welcome. Thanks in advance for you contribution to a self-sustaining ecosystem.