use core::fmt;
use esp_hal::{
Blocking,
analog::adc::{Adc, AdcCalCurve, AdcConfig, AdcPin, Attenuation},
peripherals::{ADC1, GPIO10},
};
use crate::{Millivolts, Percent, 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 voltage(&mut self) -> Millivolts {
let sum: u32 = (0..BATTERY_SAMPLES)
.map(|_| u32::from(self.adc.read_blocking(&mut self.pin)))
.sum();
Millivolts(u16::try_from(sum / BATTERY_SAMPLES * 2).unwrap_or(u16::MAX))
}
pub fn percent(&mut self) -> Percent {
battery_percent(self.voltage())
}
}
#[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()
}
}