diff options
| author | Selene ToyKeeper | 2024-03-26 03:41:17 -0600 |
|---|---|---|
| committer | Selene ToyKeeper | 2024-03-26 03:41:17 -0600 |
| commit | 35b5c42f8996167248b7e6d2e4053f6bbef1505c (patch) | |
| tree | 7b852c3965c277e749285ceeaccd043730647210 | |
| parent | dammit, got alkaline detection half working and then my flashing adapter died (diff) | |
| download | anduril-35b5c42f8996167248b7e6d2e4053f6bbef1505c.tar.gz anduril-35b5c42f8996167248b7e6d2e4053f6bbef1505c.tar.bz2 anduril-35b5c42f8996167248b7e6d2e4053f6bbef1505c.zip | |
d3aa: got weak battery detection actually working,
and not letting the magic smoke out of updi adapters any more (probably)
The alkaline detection might be a little too lenient though; it
could potentially fail to activate limits when the cell is completely
full or stronger than an average alkaline. One of my test cells
measured at 72 / 75, so if it was just a little stronger it'd pass...
but most alkalines I tried were in the 40 to 60 range and failed easily.
OTOH, if I make it easier to fail, it's likely to trip on normal li-ion
cells, and I don't want that.
So as a future enhancement idea, maybe it should have a smaller sag
threshold for AA and a larger threshold for li-ion. That would reduce
false negatives for AA, while still preventing false positives for li-ion.
Diffstat (limited to '')
| -rw-r--r-- | fsm/ramping.c | 2 | ||||
| -rw-r--r-- | fsm/ramping.h | 2 | ||||
| -rw-r--r-- | hw/hank/emisar-d3aa/hwdef.c | 84 | ||||
| -rw-r--r-- | hw/hank/emisar-d3aa/hwdef.h | 7 |
4 files changed, 55 insertions, 40 deletions
diff --git a/fsm/ramping.c b/fsm/ramping.c index 63ab399..743e619 100644 --- a/fsm/ramping.c +++ b/fsm/ramping.c @@ -58,7 +58,7 @@ inline void set_level_aux_rgb_leds(uint8_t level) { void set_level(uint8_t level) { #ifdef USE_RAMP_LEVEL_HARD_LIMIT - if (level > ramp_level_hard_limit) + if (ramp_level_hard_limit && (level > ramp_level_hard_limit)) level = ramp_level_hard_limit; #endif diff --git a/fsm/ramping.h b/fsm/ramping.h index 6fe87fe..f542bd2 100644 --- a/fsm/ramping.h +++ b/fsm/ramping.h @@ -11,7 +11,7 @@ uint8_t actual_level = 0; // the level used before actual uint8_t prev_level = 0; #ifdef USE_RAMP_LEVEL_HARD_LIMIT -uint8_t ramp_level_hard_limit = RAMP_SIZE; +uint8_t ramp_level_hard_limit = 0; #endif void set_level(uint8_t level); diff --git a/hw/hank/emisar-d3aa/hwdef.c b/hw/hank/emisar-d3aa/hwdef.c index f6cf94e..d6cb2fd 100644 --- a/hw/hank/emisar-d3aa/hwdef.c +++ b/hw/hank/emisar-d3aa/hwdef.c @@ -114,16 +114,11 @@ uint8_t voltage_raw2cooked(uint16_t measurement) { #ifdef USE_WEAK_BATTERY_PROTECTION uint8_t quick_volt_measurement() { - // take the average of a few samples - // (assumes the ADC is in voltage mode and running continuously) - uint16_t total = 0; - for (uint8_t i=0; i<8; i++) { - uint16_t m = adc_raw[0]; - total += voltage_raw2cooked(m); - delay_zero(); - } - uint8_t v = total / 8; - return v; + // wait for next hardware measurement + irq_adc = 0; + while (! irq_adc) {} + uint16_t m = adc_raw[0]; + return voltage_raw2cooked(m); } void detect_weak_battery() { @@ -133,44 +128,65 @@ void detect_weak_battery() { // - determine how much to limit power // - blink to indicate weak battery mode, if active + ramp_level_hard_limit = 0; + uint16_t resting, loaded; + // baseline unloaded measurement set_level(0); + for (uint8_t i=0; i<32; i++) { delay_zero(); } // wait about 10ms + //resting = voltage_raw2cooked(adc_smooth[0]); // probably not settled yet resting = quick_volt_measurement(); - set_level(WEAK_BATTERY_CHECK_LEVEL); - loaded = quick_volt_measurement(); + // progressively turn up the power until sag threshold is hit, + // or critical voltage, or max testing level is reached + for (uint8_t l=1; l<WEAK_BATTERY_TEST_MAX_LEVEL; l++) { + set_level(l); + loaded = quick_volt_measurement(); + int16_t sag = resting - loaded; + if ( + // AA/NiMH critical voltage + (loaded <= DUAL_VOLTAGE_LOW_LOW) || + // weak battery chemistry, can't handle much power + (sag > WEAK_BATTERY_SAG_THRESHOLD) || + // Li-ion critical voltage + ((resting > VOLTAGE_LOW) && (loaded < VOLTAGE_LOW)) + ) { + ramp_level_hard_limit = l; + break; + } + } set_level(0); - int16_t diff = resting - loaded; - uint8_t extra_blinks = 0; + // TODO? limit NiMH to ~half power, even if it passed the sag test? + // (and if so, blink 2X for NiMH, 3X for alkaline) - if (loaded <= DUAL_VOLTAGE_LOW_LOW) { - // weak or empty AA battery has a low limit - ramp_level_hard_limit = WEAK_BATTERY_LOWEST_LIMIT; - extra_blinks = 2; - } else if (loaded >= VOLTAGE_RED) { - // reasonably strong li-ion battery - ramp_level_hard_limit = WEAK_BATTERY_HIGHEST_LIMIT; - } else if (diff <= (-5 * 4)) { - // marginal battery, dropped a lot under mild load - ramp_level_hard_limit = WEAK_BATTERY_MEDIUM_LIMIT; - extra_blinks = 1; - } + uint8_t extra_blinks = 0; + if (ramp_level_hard_limit) extra_blinks ++; for (uint8_t i=0; i<extra_blinks; i++) { delay_4ms(300/4); blink_once(); } - voltage = resting; - battcheck(); - - voltage = loaded; - battcheck(); + if (ramp_level_hard_limit) { + delay_4ms(255); + // not booted far enough for this to work yet + //blink_num(ramp_level_hard_limit); + uint8_t tens, ones; + tens = ramp_level_hard_limit / 10; + ones = ramp_level_hard_limit % 10; + for (uint8_t i=0; i<tens; i++) { + delay_4ms(300/4); + blink_once(); + } + delay_4ms(600/4); + for (uint8_t i=0; i<ones; i++) { + delay_4ms(300/4); + blink_once(); + } + } - //if (diff < 0) - // blink_num(-diff); } -#endif +#endif // ifdef USE_WEAK_BATTERY_PROTECTION diff --git a/hw/hank/emisar-d3aa/hwdef.h b/hw/hank/emisar-d3aa/hwdef.h index 1e677b6..7cd2849 100644 --- a/hw/hank/emisar-d3aa/hwdef.h +++ b/hw/hank/emisar-d3aa/hwdef.h @@ -116,12 +116,11 @@ enum CHANNEL_MODES { // Alkaline AA can't handle the power this light wants, // so try to detect it and limit the maximum power +// (also helps protect firmware flashing adapters from overload) #define USE_RAMP_LEVEL_HARD_LIMIT #define USE_WEAK_BATTERY_PROTECTION -#define WEAK_BATTERY_HIGHEST_LIMIT RAMP_SIZE -#define WEAK_BATTERY_MEDIUM_LIMIT (RAMP_SIZE*2/3) -#define WEAK_BATTERY_LOWEST_LIMIT (RAMP_SIZE*1/3) -#define WEAK_BATTERY_CHECK_LEVEL (RAMP_SIZE*2/3) +#define WEAK_BATTERY_TEST_MAX_LEVEL 75 // about 300 mA +#define WEAK_BATTERY_SAG_THRESHOLD (5*4) // 0.5 V // average drop across diode on this hardware #ifndef VOLTAGE_FUDGE_FACTOR |
