use core::fmt;
use esp_hal::{
Blocking,
analog::adc::{Adc, AdcCalCurve, AdcConfig, AdcPin, Attenuation},
peripherals::{ADC1, GPIO10},
};
use crate::convert::battery_percent;
#[derive(Debug)]
pub struct BatteryPins {
pub adc: ADC1<'static>,
pub pin: GPIO10<'static>,
}
const BATTERY_SAMPLES: u32 = 16;
pub struct Battery {
adc: Adc<'static, ADC1<'static>, Blocking>,
pin: AdcPin<GPIO10<'static>, ADC1<'static>, AdcCalCurve<ADC1<'static>>>,
}
impl Battery {
pub fn millivolts(&mut self) -> u16 {
let sum: u32 = (0..BATTERY_SAMPLES)
.map(|_| u32::from(self.adc.read_blocking(&mut self.pin)))
.sum();
u16::try_from(sum / BATTERY_SAMPLES * 2).unwrap_or(u16::MAX)
}
pub fn percent(&mut self) -> u8 {
battery_percent(self.millivolts())
}
}
#[must_use]
pub fn battery(pins: BatteryPins) -> Battery {
let mut config = AdcConfig::new();
let pin =
config.enable_pin_with_cal::<_, AdcCalCurve<ADC1<'static>>>(pins.pin, Attenuation::_11dB);
Battery {
adc: Adc::new(pins.adc, config),
pin,
}
}
impl fmt::Debug for Battery {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Battery").finish_non_exhaustive()
}
}