aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster
diff options
context:
space:
mode:
authorSelene ToyKeeper2020-01-30 23:10:25 -0700
committerSelene ToyKeeper2020-01-30 23:10:25 -0700
commitd275f50525ed9a0950c743faa317c7aa4fe9420b (patch)
tree0a288282684a794e4d737289f5adedb0eaf96d02 /spaghetti-monster
parentswitched to a pseudo-rolling-average method to reduce noise, set prescaler ba... (diff)
downloadanduril-d275f50525ed9a0950c743faa317c7aa4fe9420b.tar.gz
anduril-d275f50525ed9a0950c743faa317c7aa4fe9420b.tar.bz2
anduril-d275f50525ed9a0950c743faa317c7aa4fe9420b.zip
saving state of ADC / WDT refactoring before doing more changes... what changed so far:
- removed LVP lowpass and thermal regulation lowpass logic; it's probably redundant now - slowed ADC deferred logic timing to 4X per second instead of 16X, because there doesn't seem to be much reason to do it any faster - reduced thermal event rate-limit to just 1 second, for more responsive regulation - added "EV_temperature_okay" signal, to help stop adjustments at an appropriate time instead of going to far - sped up sleep LVP to one measurement every 8 seconds instead of 16, to help the aux LEDs respond to voltage changes faster (effect on standby time is negligible) - make sure the WDT doesn't set the ADC channel or counter... except in standby mode
Diffstat (limited to 'spaghetti-monster')
-rw-r--r--spaghetti-monster/anduril/anduril.c10
-rw-r--r--spaghetti-monster/fsm-adc.c107
-rw-r--r--spaghetti-monster/fsm-adc.h4
-rw-r--r--spaghetti-monster/fsm-events.h1
-rw-r--r--spaghetti-monster/fsm-wdt.c13
5 files changed, 59 insertions, 76 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index 380e2f9..2b11486 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -1062,6 +1062,16 @@ uint8_t steady_state(Event event, uint16_t arg) {
}
return MISCHIEF_MANAGED;
}
+ #ifdef USE_SET_LEVEL_GRADUALLY
+ // temperature is within target window
+ // (so stop trying to adjust output)
+ else if (event == EV_temperature_okay) {
+ // if we're still adjusting output... stop
+ gradual_target = actual_level;
+ //set_level_gradually(actual_level);
+ return MISCHIEF_MANAGED;
+ }
+ #endif // ifdef USE_SET_LEVEL_GRADUALLY
#endif // ifdef USE_THERMAL_REGULATION
return EVENT_NOT_HANDLED;
}
diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c
index f10114f..6fae262 100644
--- a/spaghetti-monster/fsm-adc.c
+++ b/spaghetti-monster/fsm-adc.c
@@ -119,18 +119,12 @@ static inline uint8_t calc_voltage_divider(uint16_t value) {
}
#endif
-// Each full cycle runs 15.6X per second with just voltage enabled,
-// or 7.8X per second with voltage and temperature.
+// Each full cycle runs ~4X per second with just voltage enabled,
+// or ~2X per second with voltage and temperature.
#if defined(USE_LVP) && defined(USE_THERMAL_REGULATION)
-#define ADC_CYCLES_PER_SECOND 8
+#define ADC_CYCLES_PER_SECOND 2
#else
-#define ADC_CYCLES_PER_SECOND 16
-#endif
-
-#ifdef USE_THERMAL_REGULATION
-#define ADC_STEPS 2
-#else
-#define ADC_STEPS 1
+#define ADC_CYCLES_PER_SECOND 4
#endif
// happens every time the ADC sampler finishes a measurement
@@ -242,10 +236,9 @@ void adc_deferred() {
#ifdef USE_LVP
static inline void ADC_voltage_handler() {
+ // rate-limit low-voltage warnings to a max of 1 per N seconds
static uint8_t lvp_timer = 0;
- static uint8_t lvp_lowpass = 0;
#define LVP_TIMER_START (VOLTAGE_WARNING_SECONDS*ADC_CYCLES_PER_SECOND) // N seconds between LVP warnings
- #define LVP_LOWPASS_STRENGTH ADC_CYCLES_PER_SECOND // lowpass for one second
uint16_t measurement;
@@ -263,23 +256,15 @@ static inline void ADC_voltage_handler() {
#endif
// if low, callback EV_voltage_low / EV_voltage_critical
- // (but only if it has been more than N ticks since last call)
+ // (but only if it has been more than N seconds since last call)
if (lvp_timer) {
lvp_timer --;
} else { // it has been long enough since the last warning
if (voltage < VOLTAGE_LOW) {
- if (lvp_lowpass < LVP_LOWPASS_STRENGTH) {
- lvp_lowpass ++;
- } else {
- // try to send out a warning
- emit(EV_voltage_low, 0);
- // reset counters
- lvp_timer = LVP_TIMER_START;
- lvp_lowpass = 0;
- }
- } else {
- // voltage not low? reset count
- lvp_lowpass = 0;
+ // send out a warning
+ emit(EV_voltage_low, 0);
+ // reset rate-limit counter
+ lvp_timer = LVP_TIMER_START;
}
}
}
@@ -296,11 +281,7 @@ static inline void ADC_temperature_handler() {
static uint8_t history_step = 0; // don't update history as often
static uint16_t temperature_history[NUM_THERMAL_VALUES_HISTORY];
static uint8_t temperature_timer = 0;
- static uint8_t overheat_lowpass = 0;
- static uint8_t underheat_lowpass = 0;
- #define TEMPERATURE_TIMER_START ((THERMAL_WARNING_SECONDS-2)*ADC_CYCLES_PER_SECOND) // N seconds between thermal regulation events
- #define OVERHEAT_LOWPASS_STRENGTH (ADC_CYCLES_PER_SECOND*2) // lowpass for 2 seconds
- #define UNDERHEAT_LOWPASS_STRENGTH (ADC_CYCLES_PER_SECOND*2) // lowpass for 2 seconds
+ #define TEMPERATURE_TIMER_START (THERMAL_WARNING_SECONDS*ADC_CYCLES_PER_SECOND) // N seconds between thermal regulation events
// latest 16-bit ADC reading
uint16_t measurement;
@@ -373,28 +354,17 @@ static inline void ADC_temperature_handler() {
// guess what the temp will be several seconds in the future
// diff = rate of temperature change
- //diff = temperature_history[NUM_THERMAL_VALUES_HISTORY-1] - temperature_history[0];
diff = t - temperature_history[0];
// slight bias toward zero; ignore very small changes (noise)
- // FIXME: this is way too small for left-adjusted values
/*
+ // FIXME: this is way too small for 16-bit values
for (uint8_t z=0; z<3; z++) {
if (diff < 0) diff ++;
if (diff > 0) diff --;
}
*/
// projected_temperature = current temp extended forward by amplified rate of change
- //projected_temperature = temperature_history[NUM_THERMAL_VALUES_HISTORY-1] + (diff<<THERM_PREDICTION_STRENGTH);
pt = projected_temperature = t + (diff<<THERM_PREDICTION_STRENGTH);
- //pt = projected_temperature = temp + (diff<<THERM_PREDICTION_STRENGTH);
- }
-
- // cancel counters if appropriate
- if (pt > THERM_FLOOR) {
- underheat_lowpass = 0; // we're probably not too cold
- }
- if (pt < THERM_CEIL) {
- overheat_lowpass = 0; // we're probably not too hot
}
if (temperature_timer) {
@@ -403,39 +373,38 @@ static inline void ADC_temperature_handler() {
// Too hot?
if (pt > THERM_CEIL) {
- if (overheat_lowpass < OVERHEAT_LOWPASS_STRENGTH) {
- overheat_lowpass ++;
- } else {
- // reset counters
- overheat_lowpass = 0;
- temperature_timer = TEMPERATURE_TIMER_START;
- // how far above the ceiling?
- //int16_t howmuch = (pt - THERM_CEIL) * THERM_RESPONSE_MAGNITUDE / 128;
- int16_t howmuch = pt - THERM_CEIL;
- // try to send out a warning
- emit(EV_temperature_high, howmuch);
- }
+ // reset counters
+ temperature_timer = TEMPERATURE_TIMER_START;
+ // how far above the ceiling?
+ //int16_t howmuch = (pt - THERM_CEIL) * THERM_RESPONSE_MAGNITUDE / 128;
+ int16_t howmuch = (pt - THERM_CEIL) >> 6;
+ // send a warning
+ emit(EV_temperature_high, howmuch);
}
// Too cold?
else if (pt < THERM_FLOOR) {
- if (underheat_lowpass < UNDERHEAT_LOWPASS_STRENGTH) {
- underheat_lowpass ++;
- } else {
- // reset counters
- underheat_lowpass = 0;
- temperature_timer = TEMPERATURE_TIMER_START;
- // how far below the floor?
- //int16_t howmuch = (THERM_FLOOR - pt) * THERM_RESPONSE_MAGNITUDE / 128;
- int16_t howmuch = THERM_FLOOR - pt;
- // try to send out a warning (unless voltage is low)
- // (LVP and underheat warnings fight each other)
- if (voltage > VOLTAGE_LOW)
- emit(EV_temperature_low, howmuch);
- }
+ // reset counters
+ temperature_timer = TEMPERATURE_TIMER_START;
+ // how far below the floor?
+ //int16_t howmuch = (THERM_FLOOR - pt) * THERM_RESPONSE_MAGNITUDE / 128;
+ int16_t howmuch = (THERM_FLOOR - pt) >> 6;
+ // send a notification (unless voltage is low)
+ // (LVP and underheat warnings fight each other)
+ if (voltage > VOLTAGE_LOW)
+ emit(EV_temperature_low, howmuch);
+ }
+
+ // Goldilocks? (temperature is within target window)
+ else {
+ // reset counters
+ temperature_timer = TEMPERATURE_TIMER_START;
+ // send a notification (unless voltage is low)
+ // (LVP and temp-okay events fight each other)
+ if (voltage > VOLTAGE_LOW)
+ emit(EV_temperature_okay, 0);
}
- // TODO: add EV_temperature_okay signal
}
}
#endif
diff --git a/spaghetti-monster/fsm-adc.h b/spaghetti-monster/fsm-adc.h
index f4c1332..6283b2c 100644
--- a/spaghetti-monster/fsm-adc.h
+++ b/spaghetti-monster/fsm-adc.h
@@ -67,9 +67,9 @@ void battcheck();
#ifdef USE_THERMAL_REGULATION
-// default 5 seconds between thermal regulation events
+// default 1 seconds between thermal regulation events
#ifndef THERMAL_WARNING_SECONDS
-#define THERMAL_WARNING_SECONDS 5
+#define THERMAL_WARNING_SECONDS 1
#endif
// try to keep temperature below 45 C
#ifndef DEFAULT_THERM_CEIL
diff --git a/spaghetti-monster/fsm-events.h b/spaghetti-monster/fsm-events.h
index 39ad3aa..6760fdd 100644
--- a/spaghetti-monster/fsm-events.h
+++ b/spaghetti-monster/fsm-events.h
@@ -85,6 +85,7 @@ static volatile uint16_t ticks_since_last_event = 0;
#ifdef USE_THERMAL_REGULATION
#define EV_temperature_high (B_SYSTEM|0b00000101)
#define EV_temperature_low (B_SYSTEM|0b00000110)
+#define EV_temperature_okay (B_SYSTEM|0b00000111)
#endif
// Button press events
diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c
index e9dca3a..459010f 100644
--- a/spaghetti-monster/fsm-wdt.c
+++ b/spaghetti-monster/fsm-wdt.c
@@ -119,7 +119,7 @@ void WDT_inner() {
return; // no sleep LVP needed if nothing drains power while off
#else
// stop here, usually... but proceed often enough for sleep LVP to work
- if (0 != (ticks_since_last & 0x7f)) return;
+ if (0 != (ticks_since_last & 0x3f)) return;
adc_trigger = 255; // make sure a measurement will happen
ADC_on(); // enable ADC voltage measurement functions temporarily
@@ -178,12 +178,15 @@ void WDT_inner() {
#endif
#if defined(USE_LVP) || defined(USE_THERMAL_REGULATION)
- // start a new ADC measurement every 4 ticks
+ // start a new ADC measurement every 16 ticks
adc_trigger ++;
- if (0 == (adc_trigger & 3)) {
- // in case we're in standby mode and auto-retrigger is turned off
+ if (0 == (adc_trigger & 15)) {
+ // in case we're in standby mode and the ADC is turned off
+ if (go_to_standby) {
+ //set_admux_voltage();
+ ADC_on();
+ }
ADC_start_measurement();
- adc_sample_count = 0;
// allow regulation logic to run
adc_deferred_enable = 1;
}
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.