aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster/fsm-adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'spaghetti-monster/fsm-adc.c')
-rw-r--r--spaghetti-monster/fsm-adc.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c
index eef3baf..45a4297 100644
--- a/spaghetti-monster/fsm-adc.c
+++ b/spaghetti-monster/fsm-adc.c
@@ -111,7 +111,7 @@ inline void ADC_off() {
#ifdef USE_VOLTAGE_DIVIDER
static inline uint8_t calc_voltage_divider(uint16_t value) {
- // use fixed-point to get sufficient precision
+ // use 9.7 fixed-point to get sufficient precision
uint16_t adc_per_volt = ((ADC_44<<5) - (ADC_22<<5)) / (44-22);
// shift incoming value into a matching position
uint8_t result = ((value>>1) / adc_per_volt) + VOLTAGE_FUDGE_FACTOR;
@@ -231,6 +231,12 @@ static inline void ADC_voltage_handler() {
static uint8_t lvp_timer = 0;
#define LVP_TIMER_START (VOLTAGE_WARNING_SECONDS*ADC_CYCLES_PER_SECOND) // N seconds between LVP warnings
+ #ifdef NO_LVP_WHILE_BUTTON_PRESSED
+ // don't run if button is currently being held
+ // (because the button causes a reading of zero volts)
+ if (button_last_state) return;
+ #endif
+
uint16_t measurement;
// latest ADC value
@@ -280,21 +286,21 @@ static inline void ADC_voltage_handler() {
static inline void ADC_temperature_handler() {
// coarse adjustment
#ifndef THERM_LOOKAHEAD
- #define THERM_LOOKAHEAD 4 // can be tweaked per build target
+ #define THERM_LOOKAHEAD 4
#endif
// reduce frequency of minor warnings
#ifndef THERM_NEXT_WARNING_THRESHOLD
#define THERM_NEXT_WARNING_THRESHOLD 24
#endif
// fine-grained adjustment
- // how proportional should the adjustments be? (not used yet)
+ // how proportional should the adjustments be?
#ifndef THERM_RESPONSE_MAGNITUDE
- #define THERM_RESPONSE_MAGNITUDE 128
+ #define THERM_RESPONSE_MAGNITUDE 64
#endif
// acceptable temperature window size in C
#define THERM_WINDOW_SIZE 2
- // TODO: make this configurable per build target?
+ // TODO? make this configurable per build target?
// (shorter time for hosts with a lower power-to-mass ratio)
// (because then it'll have smaller responses)
#define NUM_TEMP_HISTORY_STEPS 8 // don't change; it'll break stuff
@@ -356,7 +362,7 @@ static inline void ADC_temperature_handler() {
// (but a diff of 1 C should only send a warning of magnitude 1)
// (this also makes it only respond to small errors at the time the error
// happened, not after the temperature has stabilized)
- for(uint8_t foo=0; foo<5; foo++) {
+ for(uint8_t foo=0; foo<3; foo++) {
if (offset > 0) {
offset --;
} else if (offset < 0) {
@@ -365,17 +371,23 @@ static inline void ADC_temperature_handler() {
}
// Too hot?
- // (if it's too hot and still getting warmer...)
- if ((offset > 0) && (diff > 0)) {
+ // (if it's too hot and not getting cooler...)
+ if ((offset > 0) && (diff > -1)) {
// accumulated error isn't big enough yet to send a warning
if (warning_threshold > 0) {
warning_threshold -= offset;
} else { // error is big enough; send a warning
- warning_threshold = THERM_NEXT_WARNING_THRESHOLD - offset;
-
// how far above the ceiling?
- //int16_t howmuch = offset * THERM_RESPONSE_MAGNITUDE / 128;
- int16_t howmuch = offset;
+ // original method works, but is too slow on some small hosts:
+ // (and typically has a minimum response magnitude of 2 instead of 1)
+ // int16_t howmuch = offset;
+ // ... so increase the amount, except for small values
+ // (for example, 1:1, 2:1, 3:3, 4:5, 6:9, 8:13, 10:17, 40:77)
+ // ... and let us tune the response per build target if desired
+ int16_t howmuch = (offset + offset - 3) * THERM_RESPONSE_MAGNITUDE / 128;
+ if (howmuch < 1) howmuch = 1;
+ warning_threshold = THERM_NEXT_WARNING_THRESHOLD - (uint8_t)howmuch;
+
// send a warning
emit(EV_temperature_high, howmuch);
}