aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fsm/ramping.c5
-rw-r--r--fsm/ramping.h3
-rw-r--r--hw/hank/emisar-d3aa/hwdef.c64
-rw-r--r--hw/hank/emisar-d3aa/hwdef.h9
-rw-r--r--ui/anduril/anduril.c12
5 files changed, 91 insertions, 2 deletions
diff --git a/fsm/ramping.c b/fsm/ramping.c
index adc8acb..63ab399 100644
--- a/fsm/ramping.c
+++ b/fsm/ramping.c
@@ -57,6 +57,11 @@ 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)
+ level = ramp_level_hard_limit;
+ #endif
+
#ifdef USE_JUMP_START
// maybe "jump start" the engine, if it's prone to slow starts
// (pulse the output high for a moment to wake up the power regulator)
diff --git a/fsm/ramping.h b/fsm/ramping.h
index c4b7d48..6fe87fe 100644
--- a/fsm/ramping.h
+++ b/fsm/ramping.h
@@ -10,6 +10,9 @@
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;
+#endif
void set_level(uint8_t level);
//void set_level_smooth(uint8_t level);
diff --git a/hw/hank/emisar-d3aa/hwdef.c b/hw/hank/emisar-d3aa/hwdef.c
index e2fd315..f6cf94e 100644
--- a/hw/hank/emisar-d3aa/hwdef.c
+++ b/hw/hank/emisar-d3aa/hwdef.c
@@ -4,6 +4,8 @@
#pragma once
#include "fsm/chan-rgbaux.c"
+#include "fsm/ramping.h"
+#include "ui/anduril/misc.h"
void set_level_zero();
@@ -110,3 +112,65 @@ uint8_t voltage_raw2cooked(uint16_t measurement) {
}
#endif
+#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;
+}
+
+void detect_weak_battery() {
+ // guess at the cell strength with a load test...
+ // - measure voltage while LEDs off
+ // - measure again with LEDs on
+ // - determine how much to limit power
+ // - blink to indicate weak battery mode, if active
+
+ uint16_t resting, loaded;
+
+ set_level(0);
+ resting = quick_volt_measurement();
+
+ set_level(WEAK_BATTERY_CHECK_LEVEL);
+ loaded = quick_volt_measurement();
+ set_level(0);
+
+ int16_t diff = resting - loaded;
+ uint8_t extra_blinks = 0;
+
+ 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;
+ }
+
+ for (uint8_t i=0; i<extra_blinks; i++) {
+ delay_4ms(300/4);
+ blink_once();
+ }
+
+ voltage = resting;
+ battcheck();
+
+ voltage = loaded;
+ battcheck();
+
+ //if (diff < 0)
+ // blink_num(-diff);
+}
+#endif
+
diff --git a/hw/hank/emisar-d3aa/hwdef.h b/hw/hank/emisar-d3aa/hwdef.h
index 56dd061..1e677b6 100644
--- a/hw/hank/emisar-d3aa/hwdef.h
+++ b/hw/hank/emisar-d3aa/hwdef.h
@@ -114,6 +114,15 @@ enum CHANNEL_MODES {
#define USE_VOLTAGE_VDDIO2
#endif
+// Alkaline AA can't handle the power this light wants,
+// so try to detect it and limit the maximum power
+#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)
+
// average drop across diode on this hardware
#ifndef VOLTAGE_FUDGE_FACTOR
#define VOLTAGE_FUDGE_FACTOR 0 // using a PFET so no appreciable drop
diff --git a/ui/anduril/anduril.c b/ui/anduril/anduril.c
index 1cdb8d0..f50f8d2 100644
--- a/ui/anduril/anduril.c
+++ b/ui/anduril/anduril.c
@@ -225,8 +225,16 @@ void setup() {
// regular e-switch light, no hard clicky power button
- // blink at power-on to let user know power is connected
- blink_once();
+ #ifdef USE_WEAK_BATTERY_PROTECTION
+ // try to measure the battery strength
+ // (must be done *before* factory reset,
+ // because reset tries to use full power,
+ // and a weak battery can't do that)
+ detect_weak_battery();
+ #else
+ // blink at power-on to let user know power is connected
+ blink_once();
+ #endif
#ifdef USE_FACTORY_RESET
if (button_is_pressed())
If you find this content useful please consider a small donation via bitcoin: bitcoin:1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2?amount=0.001&message=Donation Scraping git contents via cgit is very resource intensive. The continued hosting of these git repositories is entirely financed by your bitcoin contributions. For donations of a least 1 mBTC you include your IP address in the message of your bitcoin donation. This will remove this message in the future for requests from your IP, which will significantly reduce token usage. In any case, any contributions to bitcoin address 1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2 are very welcome. Thanks in advance for you contribution to a self-sustaining ecosystem.