5 #define BATTERY_ADC_SHIFT 6
6 #define RESISTOR_HI 1500 // kOhm
7 #define RESISTOR_LO 100 // kOhm
9 static volatile uint16_t battery_adcval;
10 volatile unsigned char battery_critical;
18 void battery_adc(uint16_t adcval)
20 if (battery_adcval == 0) {
21 battery_adcval = adcval << BATTERY_ADC_SHIFT;
22 } else { // running average
23 battery_adcval += (adcval
24 - (battery_adcval >> BATTERY_ADC_SHIFT));
28 unsigned char battery_100mv()
31 * This is tricky: we need to maintain precision, so we first
32 * multiply adcval by as big number as possible to fit uint16_t,
33 * then divide to get the final value,
34 * and finally type-cast it to unsigned char.
35 * We don't do running average, as the required precision
38 return (unsigned char)
40 (battery_adcval >> BATTERY_ADC_SHIFT)
42 * (RESISTOR_HI+RESISTOR_LO)/RESISTOR_LO // resistor ratio
43 / 4)) >> 8); // divide by 1024
46 /* convert value in mV to value of ADC shifted by BATTERY_ADC_SHIFT */
47 #define MV_TO_ADC(x) \
48 ((uint16_t)(((uint32_t)(x) * 1024 * (1 << BATTERY_ADC_SHIFT)) \
50 * ((RESISTOR_HI+RESISTOR_LO)/RESISTOR_LO))))
52 /* convert value in mV to upper 8 bits of ADC value << BATTERY_ADC_SHIFT */
53 #define MV_TO_ADC8(x) ((unsigned char)(MV_TO_ADC(x) >> 8))
56 * Returns number from 1 to 10 (1 = battery almost empty, 10 = full)
57 * Lithium cells have voltage from about 2.9V to 4.1V. We consider battery
58 * above 4V full, and under 3.2V critically low. We guess whether
59 * the battery has two or three cells - voltages above 8.6V are considered
60 * from three-cell battery.
62 unsigned char battery_gauge()
64 unsigned char b8 = battery_adcval >> 8;
67 if (b8 < MV_TO_ADC8(2 * 3200)) {
69 } else if (b8 < MV_TO_ADC8(2 * 3475)) {
71 } else if (b8 < MV_TO_ADC8(2 * 3577)) {
73 } else if (b8 < MV_TO_ADC8(2 * 3620)) {
75 } else if (b8 < MV_TO_ADC8(2 * 3741)) {
77 } else if (b8 < MV_TO_ADC8(2 * 3775)) {
79 } else if (b8 < MV_TO_ADC8(2 * 3844)) {
81 } else if (b8 < MV_TO_ADC8(2 * 3930)) {
83 } else if (b8 < MV_TO_ADC8(2 * 4000)) {
85 } else if (b8 < MV_TO_ADC8(2 * 4300)) {
87 } else if (b8 < MV_TO_ADC8(3 * 3200)) { // three-cell battery
89 } else if (b8 < MV_TO_ADC8(3 * 3475)) {
91 } else if (b8 < MV_TO_ADC8(3 * 3577)) {
93 } else if (b8 < MV_TO_ADC8(3 * 3620)) {
95 } else if (b8 < MV_TO_ADC8(3 * 3741)) {
97 } else if (b8 < MV_TO_ADC8(3 * 3775)) {
99 } else if (b8 < MV_TO_ADC8(3 * 3844)) {
101 } else if (b8 < MV_TO_ADC8(3 * 3930)) {
103 } else if (b8 < MV_TO_ADC8(3 * 4000)) {
110 battery_critical = 1;