aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-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;
}