diff --git a/Cargo.toml b/Cargo.toml index 550a976..b167f53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/main.rs b/src/main.rs index 168500a..dbccfc4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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)); } diff --git a/src/manager.rs b/src/manager.rs new file mode 100644 index 0000000..cce5dbb --- /dev/null +++ b/src/manager.rs @@ -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>; +type BatteryGpio = Gpio2>; + +pub struct Manager +where + C: OutputPin, +{ + dc_out_controller: DcOutController, + screen: Screen, + adc: PoweredAdc, + adapter_pin: AdapterGpio, + battery_pin: BatteryGpio, +} + +impl Manager +where + C: OutputPin, +{ + pub fn new( + dc_out_controller: DcOutController, + screen: Screen, + adc1: ADC1, + adapter_pin: AdapterGpio, + battery_pin: BatteryGpio, + ) -> Result { + 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 { + 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 { + 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({}) + } +} diff --git a/src/screen.rs b/src/screen.rs index f4c203e..ca78bbf 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -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(()) + } }