From aee648bfa5e94e12a9dd8478fc45c4e8db0bb1f9 Mon Sep 17 00:00:00 2001 From: Adam Macdonald <72780006+twokilohertz@users.noreply.github.com> Date: Wed, 5 Mar 2025 18:44:12 +0000 Subject: [PATCH] Add framebuffer to prevent redraw flicker --- Cargo.lock | 20 ++++++++++++++++++++ Cargo.toml | 5 ++++- src/display_task.rs | 27 +++++++++++++++++++-------- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aae1f1a..bc07f82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -424,6 +424,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fc247028eae04174b6635104a35b1ed336aabef4654f5e87a8f32327d231970" +[[package]] +name = "embedded-dma" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446" +dependencies = [ + "stable_deref_trait", +] + [[package]] name = "embedded-graphics" version = "0.8.1" @@ -447,6 +456,16 @@ dependencies = [ "byteorder", ] +[[package]] +name = "embedded-graphics-framebuf" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22354420f68727fa24d1e2741dae1e9a041065e80fb63b35a8d19c647a85be76" +dependencies = [ + "embedded-dma", + "embedded-graphics", +] + [[package]] name = "embedded-hal" version = "0.2.7" @@ -869,6 +888,7 @@ dependencies = [ "embassy-sync", "embassy-time", "embedded-graphics", + "embedded-graphics-framebuf", "heapless", "rtt-target", "scd4x", diff --git a/Cargo.toml b/Cargo.toml index 695e6ad..dd6fd6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,12 +25,15 @@ embassy-time = "0.4.0" embassy-sync = "0.6.2" embassy-embedded-hal = "0.3.0" static_cell = "2.1.0" -embedded-graphics = "0.8.1" # System cortex-m-rt = "0.7.5" rtt-target = "0.6.1" +# embedded-graphics +embedded-graphics = "0.8.1" +embedded-graphics-framebuf = "0.5.0" + # Peripherals scd4x = { git = "https://github.com/twokilohertz/scd4x-rs.git", branch = "conversion-fixes", features = [ "scd41", diff --git a/src/display_task.rs b/src/display_task.rs index 1dcdba0..440bb9a 100644 --- a/src/display_task.rs +++ b/src/display_task.rs @@ -1,6 +1,7 @@ // System use embassy_embedded_hal::shared_bus::blocking::spi::SpiDeviceWithConfig; use embassy_rp::{gpio::Output, spi::Config}; +use embedded_graphics_framebuf::FrameBuf; use rtt_target::rprintln; // Display @@ -13,9 +14,11 @@ use ssd1351::{ // Graphics use embedded_graphics::{ + draw_target::DrawTarget, mono_font::{ascii::FONT_6X10, MonoTextStyle}, pixelcolor::Rgb565, - prelude::{Point, WebColors}, + prelude::{Point, RgbColor, Size, WebColors}, + primitives::Rectangle, text::{Alignment, Text}, Drawable, }; @@ -46,6 +49,10 @@ pub async fn display_output_task( display.reset(rst, &mut embassy_time::Delay).unwrap(); display.init().unwrap(); + // Framebuffer, prevents flickering on redraw + let buf = [Rgb565::BLACK; 128 * 128]; + let mut framebuf = FrameBuf::new(buf, 128, 128); + let co2_text_style = MonoTextStyle::new(&FONT_6X10, Rgb565::CSS_DARK_GREEN); let temp_text_style = MonoTextStyle::new(&FONT_6X10, Rgb565::CSS_ORANGE); let humidity_text_style = MonoTextStyle::new(&FONT_6X10, Rgb565::CSS_AQUA); @@ -55,7 +62,10 @@ pub async fn display_output_task( let mut humidity_text_buf = heapless::String::<16>::new(); loop { - // Clear contents of buffers + // Clear the framebuffer + framebuf.clear(Rgb565::BLACK).unwrap(); + + // Clear contents of text buffers co2_text_buf.clear(); temp_text_buf.clear(); humidity_text_buf.clear(); @@ -66,9 +76,6 @@ pub async fn display_output_task( write!(&mut temp_text_buf, "Temp: {:.1} C", data.temperature).unwrap(); write!(&mut humidity_text_buf, "RH: {:.1} %", data.humidity).unwrap(); - // Clear the display - display.clear(); - // Draw the text to the screen Text::with_alignment( &co2_text_buf, @@ -76,7 +83,7 @@ pub async fn display_output_task( co2_text_style, Alignment::Left, ) - .draw(&mut display) + .draw(&mut framebuf) .unwrap(); Text::with_alignment( @@ -85,7 +92,7 @@ pub async fn display_output_task( temp_text_style, Alignment::Left, ) - .draw(&mut display) + .draw(&mut framebuf) .unwrap(); Text::with_alignment( @@ -94,7 +101,11 @@ pub async fn display_output_task( humidity_text_style, Alignment::Left, ) - .draw(&mut display) + .draw(&mut framebuf) .unwrap(); + + // Draw the entire framebuffer to the display + let area: Rectangle = Rectangle::new(Point::new(0, 0), Size::new(128, 128)); + display.fill_contiguous(&area, framebuf.data).unwrap(); } }