feat: 电压检测与控制。

This commit is contained in:
Ivan Li 2022-05-04 10:34:39 +08:00
parent d944fc1de3
commit 3eb680f1ce
4 changed files with 149 additions and 19 deletions

View File

@ -19,6 +19,7 @@ pio = ["esp-idf-sys/pio"]
anyhow = {version = "1.0.57", features = ["backtrace"]}
embedded-graphics = "0.7.1"
embedded-hal = "1.0.0-alpha.8"
embedded-hal-0-2 = { package = "embedded-hal", version = "0.2.7", features = ["unproven"] }
esp-idf-hal = "0.37.3"
esp-idf-sys = {version = "0.31.5", features = ["binstart"]}
ssd1306 = "0.7.0"

View File

@ -4,6 +4,7 @@ use std::{thread, time::Duration};
mod beep;
mod blink;
mod dc_out_controller;
mod manager;
mod screen;
fn main() {
// Temporary. Will disappear once ESP-IDF 4.4 is released, but for now it is necessary to call this function once,
@ -16,13 +17,17 @@ fn main() {
let gpio6 = peripherals.pins.gpio6;
let ledc_timer0 = peripherals.ledc.timer0;
let ledc_channel0 = peripherals.ledc.channel0;
let dc_out_ctl_pin = peripherals.pins.gpio2;
let dc_out_ctl_pin = peripherals.pins.gpio3;
let i2c0 = peripherals.i2c0;
let gpio9 = peripherals.pins.gpio9;
let gpio10 = peripherals.pins.gpio10;
let adc1 = peripherals.adc1;
let adapter_pin = peripherals.pins.gpio1;
let battery_pin = peripherals.pins.gpio2;
println!("Starting screen");
screen::Screen::new(i2c0, gpio9, gpio10).expect("Failed to create screen");
let display = screen::Screen::new(i2c0, gpio9, gpio10).expect("Failed to create screen");
thread::spawn(move || {
let mut blink =
@ -44,22 +49,35 @@ fn main() {
beep.play();
});
thread::spawn(move || {
let mut dc_out_ctl = dc_out_controller::DcOutController::new(
dc_out_ctl_pin
.into_output()
.expect("Failed to set GPIO2 as output"),
);
loop {
if dc_out_ctl.state {
dc_out_ctl.off().expect("Failed to turn DC_OUT_CTL off");
} else {
dc_out_ctl.on().expect("Failed to turn DC_OUT_CTL on");
}
thread::sleep(Duration::from_millis(500));
}
});
// thread::spawn(move || {
// let mut dc_out_ctl = dc_out_controller::DcOutController::new(
// dc_out_ctl_pin
// .into_output()
// .expect("Failed to set GPIO2 as output"),
// );
// loop {
// if dc_out_ctl.state {
// dc_out_ctl.off().expect("Failed to turn DC_OUT_CTL off");
// } else {
// dc_out_ctl.on().expect("Failed to turn DC_OUT_CTL on");
// }
// thread::sleep(Duration::from_millis(500));
// }
// });
let mut dc_out_ctl = dc_out_controller::DcOutController::new(
dc_out_ctl_pin
.into_output()
.expect("Failed to set GPIO3 as output"),
);
let mut manager = manager::Manager::new(
dc_out_ctl,
display,
adc1,
adapter_pin.into_analog_atten_11db().expect("Failed to set GPIO1 as analog input"),
battery_pin.into_analog_atten_11db().expect("Failed to set GPIO2 as analog input"),
).expect("Failed to create manager");
loop {
manager.handling_once().expect("Failed to handle once");
println!("Hello, world!");
thread::sleep(Duration::from_millis(2000));
}

81
src/manager.rs Normal file
View File

@ -0,0 +1,81 @@
use embedded_hal::digital::blocking::OutputPin;
use embedded_hal_0_2::{adc::OneShot, digital::v2::InputPin};
use esp_idf_hal::{
adc::{Adc, Atten11dB, PoweredAdc, ADC1},
gpio::{Gpio1, Gpio2},
};
use esp_idf_sys::EspError;
use crate::{dc_out_controller::DcOutController, screen::Screen};
type AdapterGpio = Gpio1<Atten11dB<ADC1>>;
type BatteryGpio = Gpio2<Atten11dB<ADC1>>;
pub struct Manager<C>
where
C: OutputPin,
{
dc_out_controller: DcOutController<C>,
screen: Screen,
adc: PoweredAdc<ADC1>,
adapter_pin: AdapterGpio,
battery_pin: BatteryGpio,
}
impl<C> Manager<C>
where
C: OutputPin,
{
pub fn new(
dc_out_controller: DcOutController<C>,
screen: Screen,
adc1: ADC1,
adapter_pin: AdapterGpio,
battery_pin: BatteryGpio,
) -> Result<Self, EspError> {
let adc = PoweredAdc::new(
adc1,
esp_idf_hal::adc::config::Config::new().calibration(true),
)?;
return Ok(Manager {
dc_out_controller,
screen,
adc,
adapter_pin,
battery_pin,
});
}
pub fn get_adapter_voltage(&mut self) -> Result<f32, EspError> {
let mut voltage = 0.0;
for _ in 0..10 {
voltage += self.adc.read(&mut self.adapter_pin).unwrap() as f32;
}
voltage /= 10.0;
return Ok(voltage);
}
pub fn get_battery_voltage(&mut self) -> Result<f32, EspError> {
let mut voltage = 0.0;
for _ in 0..10 {
voltage += self.adc.read(&mut self.battery_pin).unwrap() as f32;
}
voltage /= 10.0;
return Ok(voltage);
}
pub fn handling_once(&mut self) -> Result<(), EspError> {
let adapter = self.get_adapter_voltage()?;
let battery = self.get_battery_voltage()?;
if adapter < 1000.0 {
self.dc_out_controller.off().expect("Can not turn off Out");
} else {
self.dc_out_controller.on().expect("Can not turn on Out");
}
self.screen
.draw_voltage(adapter, battery)
.expect("Failed to draw voltage");
Ok({})
}
}

View File

@ -1,6 +1,6 @@
use anyhow::{Result};
use embedded_graphics::{
mono_font::{ascii::FONT_10X20, MonoTextStyle},
mono_font::{ascii::FONT_10X20, MonoTextStyle, iso_8859_10::FONT_6X10},
pixelcolor::Rgb565,
prelude::{Dimensions, Drawable, Point, Primitive, RgbColor},
primitives::{PrimitiveStyleBuilder, Rectangle},
@ -70,7 +70,6 @@ impl Screen {
pub fn draw_boot(&mut self) -> Result<()>
{
println!("LED rendering done");
self.display.clear();
Rectangle::new(
@ -104,4 +103,35 @@ impl Screen {
Ok(())
}
pub fn draw_voltage(&mut self, adapter: f32, battery: f32) -> Result<()> {
self.display.clear();
Text::new(
format!("Adp. {:.2} mV", adapter).as_str(),
Point::new(
12,
24,
),
MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE.into()),
)
.draw(&mut self.display).expect("Failed to draw text");
Text::new(
format!("Bat. {:.2} mV", battery).as_str(),
Point::new(
12,
36,
),
MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE.into()),
)
.draw(&mut self.display).expect("Failed to draw text");
println!("LED rendering done");
self.display
.flush()
.map_err(|e| anyhow::anyhow!("Display error: {:?}", e))?;
Ok(())
}
}