feat: change screen to optional. Issue #1.

This commit is contained in:
Ivan Li 2022-06-09 20:07:22 +08:00
parent 696673ba01
commit 5234fe20b5

View File

@ -1,18 +1,19 @@
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result, Ok};
use embedded_graphics::{ use embedded_graphics::{
mono_font::{ascii::FONT_10X20, MonoTextStyle, iso_8859_10::FONT_6X10}, mono_font::{ascii::FONT_10X20, iso_8859_10::FONT_6X10, MonoTextStyle},
pixelcolor::Rgb565, pixelcolor::Rgb565,
prelude::{Dimensions, Drawable, Point, Primitive, RgbColor}, prelude::{Dimensions, Drawable, Point, Primitive, RgbColor},
primitives::{PrimitiveStyleBuilder, Rectangle}, primitives::{PrimitiveStyleBuilder, Rectangle},
text::Text, text::Text,
}; };
use embedded_hal::delay::blocking::DelayUs; use embedded_hal::{delay::blocking::DelayUs, i2c::blocking::{I2c, Operation}};
use esp_idf_hal::{ use esp_idf_hal::{
delay, delay,
gpio::{self}, gpio::{self},
i2c::{self, Master, I2C0}, i2c::{self, Master, I2C0},
prelude::*, prelude::*,
}; };
use log::warn;
use ssd1306::{ use ssd1306::{
mode::{BufferedGraphicsMode, DisplayConfig}, mode::{BufferedGraphicsMode, DisplayConfig},
prelude::I2CInterface, prelude::I2CInterface,
@ -27,7 +28,7 @@ type Display = Ssd1306<
>; >;
pub struct Screen { pub struct Screen {
pub display: Display, pub display: Option<Display>,
} }
impl Screen { impl Screen {
@ -37,13 +38,21 @@ impl Screen {
scl: gpio::Gpio10<gpio::Unknown>, scl: gpio::Gpio10<gpio::Unknown>,
) -> Result<Self> { ) -> Result<Self> {
let config = <i2c::config::MasterConfig as Default>::default().baudrate(400.kHz().into()); let config = <i2c::config::MasterConfig as Default>::default().baudrate(400.kHz().into());
let i2c = i2c::Master::<i2c::I2C0, _, _>::new( let mut i2c = i2c::Master::<i2c::I2C0, _, _>::new(i2c, i2c::MasterPins { sda, scl }, config)?;
i2c,
i2c::MasterPins { sda, scl }, let mut buff = [0u8; 10];
config, if let Err(err) = i2c.transaction(0x3C, &mut [Operation::Read(&mut buff)]) {
)?; warn!("Failed to initialize display: {}", err);
warn!("Failed to initialize display: {}", err);
warn!("Failed to initialize display: {}", err);
warn!("Failed to initialize display: {}", err);
warn!("Failed to initialize display: {}", err);
return Ok(Self { display: None });
}
let di = ssd1306::I2CDisplayInterface::new(i2c); let di = ssd1306::I2CDisplayInterface::new(i2c);
let mut delay = delay::Ets; let mut delay = delay::Ets;
delay.delay_ms(10_u32)?; delay.delay_ms(10_u32)?;
@ -55,22 +64,27 @@ impl Screen {
.into_buffered_graphics_mode(); .into_buffered_graphics_mode();
display display
.init().map_err(|err| anyhow!("Can not init display: {:?}", err))?; .init()
.map_err(|err| anyhow!("Can not init display: {:?}", err))?;
let mut instance = Screen { display }; let mut instance = Screen { display: Some(display) };
instance.draw_boot()?; instance.draw_boot()?;
Ok(instance) Ok(instance)
} }
pub fn draw_boot(&mut self) -> Result<()> pub fn draw_boot(&mut self) -> Result<()> {
{ if self.display.is_none() {
self.display.clear(); return Ok(());
}
let display = self.display.as_mut().unwrap();
display.clear();
Rectangle::new( Rectangle::new(
self.display.bounding_box().top_left, display.bounding_box().top_left,
self.display.bounding_box().size, display.bounding_box().size,
) )
.into_styled( .into_styled(
PrimitiveStyleBuilder::new() PrimitiveStyleBuilder::new()
@ -79,19 +93,21 @@ impl Screen {
.stroke_width(1) .stroke_width(1)
.build(), .build(),
) )
.draw(&mut self.display).expect("Failed to draw rectangle"); .draw(display)
.expect("Failed to draw rectangle");
Text::new( Text::new(
"Ivan's UPS", "Ivan's UPS",
Point::new( Point::new(
12, 12,
(self.display.bounding_box().size.height - 10) as i32 / 2 + 1, (display.bounding_box().size.height - 10) as i32 / 2 + 1,
), ),
MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE.into()), MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE.into()),
) )
.draw(&mut self.display).expect("Failed to draw text"); .draw(display)
.expect("Failed to draw text");
self.display display
.flush() .flush()
.map_err(|e| anyhow::anyhow!("Display error: {:?}", e))?; .map_err(|e| anyhow::anyhow!("Display error: {:?}", e))?;
@ -99,30 +115,27 @@ impl Screen {
} }
pub fn draw_voltage(&mut self, adapter: f32, battery: f32) -> Result<()> { pub fn draw_voltage(&mut self, adapter: f32, battery: f32) -> Result<()> {
self.display.clear(); if let Some(display) = self.display.as_mut() {
display.clear();
Text::new( Text::new(
format!("Adp. {:.2} mV", adapter).as_str(), format!("Adp. {:.2} mV", adapter).as_str(),
Point::new( Point::new(12, 24),
12,
24,
),
MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE.into()), MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE.into()),
) )
.draw(&mut self.display).expect("Failed to draw text"); .draw(display)
.expect("Failed to draw text");
Text::new( Text::new(
format!("Bat. {:.2} mV", battery).as_str(), format!("Bat. {:.2} mV", battery).as_str(),
Point::new( Point::new(12, 36),
12,
36,
),
MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE.into()), MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE.into()),
) )
.draw(&mut self.display).expect("Failed to draw text"); .draw(display)
.expect("Failed to draw text");
self.display display
.flush() .flush()
.map_err(|e| anyhow::anyhow!("Display error: {:?}", e))?; .map_err(|e| anyhow::anyhow!("Display error: {:?}", e))?;
}
Ok(()) Ok(())
} }