|
|
@@ -186,12 +186,36 @@ void log_jump(unsigned char is_alt, float meters) {
|
|
|
xprintf(PSTR("%.1fm\r\n"), (double)meters);
|
|
|
}
|
|
|
|
|
|
+/* Voltage->percent breakpoints for a rough Li-ion/LiPo discharge curve,
|
|
|
+ * anchored so VI_LVL (the level that forces an immediate shutdown, see
|
|
|
+ * main.h) reads 0% - not just happens to clamp there. Precision isn't the
|
|
|
+ * goal (a straight line between points is a rough approximation), only
|
|
|
+ * getting the empty end right, since that's exactly when this number matters
|
|
|
+ * most. Voltages are millivolts to keep the table integer. */
|
|
|
+__flash const unsigned int batt_lut_mv[] = { 3100, 3400, 3550, 3700, 3850, 4000, 4100, 4200 };
|
|
|
+__flash const unsigned char batt_lut_pct[] = { 0, 10, 25, 45, 65, 80, 90, 100 };
|
|
|
+#define BATT_LUT_LEN (sizeof(batt_lut_mv)/sizeof(batt_lut_mv[0]))
|
|
|
+
|
|
|
+static unsigned char battery_percent(float bat_volt) {
|
|
|
+ unsigned int mv = (unsigned int)(bat_volt*1000.0 + 0.5);
|
|
|
+ unsigned char i;
|
|
|
+
|
|
|
+ if (mv <= batt_lut_mv[0])
|
|
|
+ return batt_lut_pct[0];
|
|
|
+ if (mv >= batt_lut_mv[BATT_LUT_LEN-1])
|
|
|
+ return batt_lut_pct[BATT_LUT_LEN-1];
|
|
|
+ for (i = 1; i < BATT_LUT_LEN; i++) {
|
|
|
+ if (mv <= batt_lut_mv[i]) {
|
|
|
+ unsigned int span_mv = batt_lut_mv[i] - batt_lut_mv[i-1];
|
|
|
+ unsigned char span_pct = batt_lut_pct[i] - batt_lut_pct[i-1];
|
|
|
+ return batt_lut_pct[i-1] + (unsigned char)((unsigned long int)(mv - batt_lut_mv[i-1]) * span_pct / span_mv);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return batt_lut_pct[BATT_LUT_LEN-1]; /* unreachable */
|
|
|
+}
|
|
|
+
|
|
|
void log_status_line(void) {
|
|
|
- signed int batpct = (signed int)((System.bat_volt - 3.3) / (4.2 - 3.3) * 100.0 + 0.5);
|
|
|
- if (batpct < 0)
|
|
|
- batpct = 0;
|
|
|
- if (batpct > 100)
|
|
|
- batpct = 100;
|
|
|
+ unsigned char batpct = battery_percent(System.bat_volt);
|
|
|
|
|
|
log_reject_flush();
|
|
|
log_prefix();
|