diff options
| author | Selene ToyKeeper | 2019-11-14 19:09:22 -0700 |
|---|---|---|
| committer | Selene ToyKeeper | 2019-11-14 19:09:22 -0700 |
| commit | 221371a13918c745d397fdd9b5c1cb8cb76c62a2 (patch) | |
| tree | 490c1ba31a3274e26420d7e297164e629521d510 /spaghetti-monster | |
| parent | fixed factory reset (wasn't running interrupt logic since it's deferred now) (diff) | |
| download | anduril-221371a13918c745d397fdd9b5c1cb8cb76c62a2.tar.gz anduril-221371a13918c745d397fdd9b5c1cb8cb76c62a2.tar.bz2 anduril-221371a13918c745d397fdd9b5c1cb8cb76c62a2.zip | |
added a lowpass filter for battery voltage measurements
(but only on attiny1634 devices, since it costs a bit of space and isn't strictly necessary)
Diffstat (limited to '')
| -rw-r--r-- | spaghetti-monster/anduril/cfg-emisar-d4s.h | 4 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/cfg-emisar-d4v2.h | 3 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-adc.c | 59 |
3 files changed, 29 insertions, 37 deletions
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4s.h b/spaghetti-monster/anduril/cfg-emisar-d4s.h index 230ac7c..a9ac5f0 100644 --- a/spaghetti-monster/anduril/cfg-emisar-d4s.h +++ b/spaghetti-monster/anduril/cfg-emisar-d4s.h @@ -46,3 +46,7 @@ #define THERMAL_WARNING_SECONDS 3 #define THERMAL_UPDATE_SPEED 2 #define THERM_PREDICTION_STRENGTH 4 + +// attiny1634 has enough space to smooth out voltage readings +#define USE_VOLTAGE_LOWPASS + diff --git a/spaghetti-monster/anduril/cfg-emisar-d4v2.h b/spaghetti-monster/anduril/cfg-emisar-d4v2.h index b83c65c..0db1062 100644 --- a/spaghetti-monster/anduril/cfg-emisar-d4v2.h +++ b/spaghetti-monster/anduril/cfg-emisar-d4v2.h @@ -49,3 +49,6 @@ #define USE_TENCLICK_THERMAL_CONFIG #define THERM_CAL_OFFSET 5 + +// attiny1634 has enough space to smooth out voltage readings +#define USE_VOLTAGE_LOWPASS diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c index d447189..c859539 100644 --- a/spaghetti-monster/fsm-adc.c +++ b/spaghetti-monster/fsm-adc.c @@ -201,11 +201,6 @@ void ADC_inner() { #ifdef USE_LVP static inline void ADC_voltage_handler() { - // LVP declarations - #ifdef USE_LVP_AVG - #define NUM_VOLTAGE_VALUES 4 - static int16_t voltage_values[NUM_VOLTAGE_VALUES]; - #endif 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 @@ -213,40 +208,30 @@ static inline void ADC_voltage_handler() { uint16_t measurement = adc_values[0]; // latest 10-bit ADC reading - #ifdef USE_LVP_AVG - // prime on first execution - if (voltage == 0) { - for(uint8_t i=0; i<NUM_VOLTAGE_VALUES; i++) - voltage_values[i] = measurement; - voltage = 42; // the answer to life, the universe, and the voltage of a full li-ion cell - } else { - uint16_t total = 0; - uint8_t i; - for(i=0; i<NUM_VOLTAGE_VALUES-1; i++) { - voltage_values[i] = voltage_values[i+1]; - total += voltage_values[i]; - } - voltage_values[i] = measurement; - total += measurement; - total = total >> 2; + #ifdef USE_VOLTAGE_LOWPASS + static uint16_t prev_measurement = 0; - #ifdef USE_VOLTAGE_DIVIDER - voltage = calc_voltage_divider(total); - #else - voltage = (uint16_t)(1.1*1024*10)/total + VOLTAGE_FUDGE_FACTOR; - #endif - } - #else // no USE_LVP_AVG - #ifdef USE_VOLTAGE_DIVIDER - voltage = calc_voltage_divider(measurement); - #else - // calculate actual voltage: volts * 10 - // ADC = 1.1 * 1024 / volts - // volts = 1.1 * 1024 / ADC - //voltage = (uint16_t)(1.1*1024*10)/measurement + VOLTAGE_FUDGE_FACTOR; - voltage = ((uint16_t)(2*1.1*1024*10)/measurement + VOLTAGE_FUDGE_FACTOR) >> 1; - #endif + // prime on first execution, or while asleep + if (go_to_standby || (! prev_measurement)) prev_measurement = measurement; + + // only allow raw value to go up or down by 1 per iteration + if (measurement > prev_measurement) measurement = prev_measurement + 1; + else if (measurement < prev_measurement) measurement = prev_measurement - 1; + + // remember for later + prev_measurement = measurement; + #endif // no USE_VOLTAGE_LOWPASS + + #ifdef USE_VOLTAGE_DIVIDER + voltage = calc_voltage_divider(measurement); + #else + // calculate actual voltage: volts * 10 + // ADC = 1.1 * 1024 / volts + // volts = 1.1 * 1024 / ADC + //voltage = (uint16_t)(1.1*1024*10)/measurement + VOLTAGE_FUDGE_FACTOR; + voltage = ((uint16_t)(2*1.1*1024*10)/measurement + VOLTAGE_FUDGE_FACTOR) >> 1; #endif + // if low, callback EV_voltage_low / EV_voltage_critical // (but only if it has been more than N ticks since last call) if (lvp_timer) { |
