diff options
Diffstat (limited to 'spaghetti-monster/fsm-adc.c')
| -rw-r--r-- | spaghetti-monster/fsm-adc.c | 36 |
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); } |
