Implemented catching panics and displaying them on the display. Also implemented a deep-sleep based loop
This commit is contained in:
98
src/main.rs
98
src/main.rs
@@ -1,11 +1,11 @@
|
|||||||
|
use core::panic;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use chrono::{format::Fixed, DateTime, Datelike, Days, FixedOffset, NaiveTime};
|
use chrono::{format::Fixed, DateTime, Datelike, Days, FixedOffset, NaiveTime};
|
||||||
use embedded_graphics::{
|
use embedded_graphics::{
|
||||||
mono_font::{MonoTextStyle, MonoTextStyleBuilder},
|
|
||||||
prelude::{Dimensions, Point},
|
prelude::{Dimensions, Point},
|
||||||
text::{Baseline, Text, TextStyleBuilder},
|
text::{Text},
|
||||||
Drawable,
|
Drawable,
|
||||||
};
|
};
|
||||||
use epd_waveshare::{color::Color, epd7in5_v2::Epd7in5, prelude::WaveshareDisplay};
|
use epd_waveshare::{color::Color, epd7in5_v2::Epd7in5, prelude::WaveshareDisplay};
|
||||||
@@ -22,13 +22,20 @@ use esp_idf_svc::{
|
|||||||
nvs::EspDefaultNvsPartition,
|
nvs::EspDefaultNvsPartition,
|
||||||
wifi::Configuration,
|
wifi::Configuration,
|
||||||
};
|
};
|
||||||
|
use esp_idf_sys::esp_deep_sleep;
|
||||||
use u8g2_fonts::U8g2TextStyle;
|
use u8g2_fonts::U8g2TextStyle;
|
||||||
use untis::{Date, Lesson};
|
use untis::{Date, Lesson};
|
||||||
use embedded_layout::{layout::linear::{spacing::DistributeFill, ElementSpacing, FixedMargin, LinearLayout}, prelude::*};
|
use embedded_layout::{layout::linear::{spacing::DistributeFill, FixedMargin, LinearLayout}, prelude::*};
|
||||||
|
|
||||||
type Timetable = [[Option<Lesson>;8]; 5];
|
type Timetable = [[Option<Lesson>;8]; 5];
|
||||||
|
|
||||||
|
|
||||||
|
#[link_section = ".rtc.data"]
|
||||||
|
static mut WAKEUP_COUNTER: u64 = 0;
|
||||||
|
|
||||||
|
#[link_section = ".rtc.data"]
|
||||||
|
static mut ERROR_MSG: Option<[u8; 2048]> = None;
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
// It is necessary to call this function once. Otherwise some patches to the runtime
|
// It is necessary to call this function once. Otherwise some patches to the runtime
|
||||||
// implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
|
// implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
|
||||||
@@ -49,6 +56,32 @@ fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
let dc = PinDriver::output(miso).unwrap();
|
let dc = PinDriver::output(miso).unwrap();
|
||||||
|
|
||||||
|
|
||||||
|
std::panic::set_hook(Box::new(|panic|{
|
||||||
|
let msg: String = format!("{}", panic);/* if let Some(s) = panic.payload().downcast_ref::<&str>() {
|
||||||
|
format!("{s:?}")
|
||||||
|
} else if let Some(s) = panic.payload().downcast_ref::<String>() {
|
||||||
|
format!("{s:?}")
|
||||||
|
} else {
|
||||||
|
format!("Failed to downcast panic msg")
|
||||||
|
}; */
|
||||||
|
let msg_bytes = msg.into_bytes();
|
||||||
|
|
||||||
|
// Copy the string buffer into the array
|
||||||
|
let mut buffer = [0u8; 2048];
|
||||||
|
for i in 0..(buffer.len().min(msg_bytes.len())){
|
||||||
|
buffer[i] = msg_bytes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe{
|
||||||
|
ERROR_MSG = Some(buffer);
|
||||||
|
|
||||||
|
// Sleep for a second
|
||||||
|
esp_deep_sleep(1_000_000)
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
log::info!("Initialized pins");
|
log::info!("Initialized pins");
|
||||||
|
|
||||||
let config = config::Config::new();
|
let config = config::Config::new();
|
||||||
@@ -66,20 +99,53 @@ fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
log::info!("Initialized spi interface");
|
log::info!("Initialized spi interface");
|
||||||
|
|
||||||
|
// Initialize the draw buffer
|
||||||
// Allocating on the stack makes the chip crash. We gotta put it on the heap
|
// Allocating on the stack makes the chip crash. We gotta put it on the heap
|
||||||
let mut display = Box::new(epd_waveshare::epd7in5_v2::Display7in5::default());
|
let mut display = Box::new(epd_waveshare::epd7in5_v2::Display7in5::default());
|
||||||
display.set_rotation(epd_waveshare::prelude::DisplayRotation::Rotate0);
|
display.set_rotation(epd_waveshare::prelude::DisplayRotation::Rotate0);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
WAKEUP_COUNTER += 1;
|
||||||
|
}
|
||||||
|
|
||||||
let mut delay = Ets;
|
let mut delay = Ets;
|
||||||
|
|
||||||
let mut epd7in5 = Epd7in5::new(&mut spi, busy, dc, rst, &mut delay, None).unwrap();
|
unsafe{
|
||||||
|
if let Some(error) = ERROR_MSG{
|
||||||
|
|
||||||
|
// Draw to the display
|
||||||
|
let text_style = U8g2TextStyle::new(u8g2_fonts::fonts::u8g2_font_7x14_mr, Color::White);
|
||||||
|
|
||||||
|
let error_label = Text::new("An error occured:", Point::zero(), &text_style);
|
||||||
|
|
||||||
|
let error_message = String::from_utf8_lossy(&error);
|
||||||
|
let error_message = match &error_message{
|
||||||
|
Cow::Borrowed(c) => *c,
|
||||||
|
Cow::Owned(c) => &c
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
let error_message_label = Text::new(error_message, Point::zero(), &text_style);
|
||||||
|
let mut vg = [error_label, error_message_label];
|
||||||
|
LinearLayout::vertical(Views::new(&mut vg))
|
||||||
|
.arrange()
|
||||||
|
.draw(&mut *display).unwrap();
|
||||||
|
|
||||||
|
let mut epd7in5 = Epd7in5::new(&mut spi, busy, dc, rst, &mut delay, None).unwrap();
|
||||||
|
epd7in5.update_and_display_frame(&mut spi, &*display.buffer(), &mut delay)?;
|
||||||
|
epd7in5.sleep(&mut spi, &mut delay)?;
|
||||||
|
|
||||||
|
// Sleep for 12 hours
|
||||||
|
esp_deep_sleep(12*60*60*60*1000_000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create a file called wifi-creds.txt and write SSID and password into it separated by a line break
|
// Create a file called wifi-creds.txt and write SSID and password into it separated by a line break
|
||||||
let mut creds = include_str!("../wifi-creds.txt").split('\n');
|
let mut creds = include_str!("../wifi-creds.txt").split('\n');
|
||||||
let ssid: heapless::String<32> =
|
let ssid: heapless::String<32> =
|
||||||
heapless::String::<32>::from_str(creds.next().unwrap()).unwrap();
|
heapless::String::<32>::from_str(creds.next().unwrap()).unwrap();
|
||||||
let password: heapless::String<64> =
|
let password: heapless::String<64> =
|
||||||
heapless::String::<64>::from_str(creds.next().unwrap()).unwrap();
|
heapless::String::<64>::from_str(creds.next().unwrap()).unwrap();
|
||||||
|
|
||||||
// Connecting to wifi
|
// Connecting to wifi
|
||||||
let sysloop = EspSystemEventLoop::take().unwrap();
|
let sysloop = EspSystemEventLoop::take().unwrap();
|
||||||
@@ -115,13 +181,26 @@ fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
let (tt, now) = fetch_timetable(httpconnection);
|
let (tt, now) = fetch_timetable(httpconnection);
|
||||||
|
|
||||||
|
|
||||||
|
// Render the layout
|
||||||
draw_layout(&mut display, &tt, now);
|
draw_layout(&mut display, &tt, now);
|
||||||
//draw_text(&mut display, &tt[3][5].clone().unwrap().subjects.first().as_ref().unwrap().name, 5, 5);
|
|
||||||
|
// Actually push changes to the display
|
||||||
|
let mut epd7in5 = Epd7in5::new(&mut spi, busy, dc, rst, &mut delay, None).unwrap();
|
||||||
epd7in5.update_and_display_frame(&mut spi, &*display.buffer(), &mut delay)?;
|
epd7in5.update_and_display_frame(&mut spi, &*display.buffer(), &mut delay)?;
|
||||||
epd7in5.sleep(&mut spi, &mut delay)?;
|
epd7in5.sleep(&mut spi, &mut delay)?;
|
||||||
log::info!("Completed");
|
log::info!("Completed");
|
||||||
|
|
||||||
Ok(())
|
wifi.disconnect().unwrap();
|
||||||
|
wifi.stop().unwrap();
|
||||||
|
|
||||||
|
drop(epd7in5);
|
||||||
|
drop(wifi);
|
||||||
|
drop(spi);
|
||||||
|
|
||||||
|
unsafe{
|
||||||
|
esp_deep_sleep(10 * 60 * 1000_000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_layout(display: &mut epd_waveshare::epd7in5_v2::Display7in5, timetable: &Timetable, now: DateTime<FixedOffset>){
|
fn draw_layout(display: &mut epd_waveshare::epd7in5_v2::Display7in5, timetable: &Timetable, now: DateTime<FixedOffset>){
|
||||||
@@ -166,7 +245,8 @@ fn draw_layout(display: &mut epd_waveshare::epd7in5_v2::Display7in5, timetable:
|
|||||||
|
|
||||||
let columns = Views::new(&mut columns);
|
let columns = Views::new(&mut columns);
|
||||||
|
|
||||||
let time_str = format!("{}", now.format("%Y-%m-%d %H:%M"));
|
// Unsafe is needed to access static mutable variable
|
||||||
|
let time_str = format!("{} ({})", now.format("%Y-%m-%d %H:%M"), unsafe {WAKEUP_COUNTER});
|
||||||
let time_text = Text::new(&time_str, Point::zero(), &text_style_small);
|
let time_text = Text::new(&time_str, Point::zero(), &text_style_small);
|
||||||
|
|
||||||
let time_table_grid = LinearLayout::horizontal(columns)
|
let time_table_grid = LinearLayout::horizontal(columns)
|
||||||
|
|||||||
Reference in New Issue
Block a user