From fded66b44346dd18cdf2ea703cd5b8153dbfd686 Mon Sep 17 00:00:00 2001 From: trivernis Date: Fri, 12 May 2023 16:13:22 +0200 Subject: [PATCH] Decouple analog read from display refresh and add moving average --- src/main.rs | 66 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3e32623..2d47bc6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ use panic_halt as _; use fugit::RateExtU32; -use cortex_m::prelude::{_embedded_hal_watchdog_Watchdog, _embedded_hal_watchdog_WatchdogEnable}; +use cortex_m::prelude::_embedded_hal_watchdog_Watchdog; use embedded_hal::adc::OneShot; use hal::i2c; pub use sparkfun_pro_micro_rp2040::hal; @@ -23,16 +23,17 @@ use fugit::MicrosDurationU32; use hal::gpio::bank0::{Gpio14, Gpio15}; use hal::gpio::Pin; use hal::pac::I2C1; -use hal::timer::Alarm; -use hal::timer::Alarm0; +use hal::timer::{Alarm, Alarm0, Alarm1}; use hal::Adc; const XTAL_FREQ_HZ: u32 = 12_000_000u32; +const MVG_AVG_COUNT: u16 = 20; #[rtic::app(device = sparkfun_pro_micro_rp2040::hal::pac, peripherals = true)] mod app { - const CHANGE_FREQUENCY_TICKS: u32 = 500_000; + const DISPLAY_UPDATE_INT_TICKS: u32 = 500_000; + const SENSOR_READ_INT_TICKS: u32 = 50_000; use super::*; type Display = Ssd1306< @@ -51,7 +52,9 @@ mod app { #[shared] struct Shared { - alarm: Alarm0, + alarm0: Alarm0, + alarm1: Alarm1, + sensor_value: u16, } #[local] @@ -87,9 +90,13 @@ mod app { &mut resets, ); let mut timer = hal::Timer::new(c.device.TIMER, &mut resets); - let mut alarm = timer.alarm_0().unwrap(); - let _ = alarm.schedule(MicrosDurationU32::from_ticks(CHANGE_FREQUENCY_TICKS)); - alarm.enable_interrupt(); + let mut alarm0 = timer.alarm_0().unwrap(); + let _ = alarm0.schedule(MicrosDurationU32::from_ticks(DISPLAY_UPDATE_INT_TICKS)); + alarm0.enable_interrupt(); + + let mut alarm1 = timer.alarm_1().unwrap(); + let _ = alarm1.schedule(MicrosDurationU32::from_ticks(SENSOR_READ_INT_TICKS)); + alarm1.enable_interrupt(); let scl = pins.gpio15.into_mode(); let sda = pins.gpio14.into_mode(); @@ -120,7 +127,11 @@ mod app { let adc_pin = pins.gpio29.into_floating_input(); ( - Shared { alarm }, + Shared { + alarm0, + alarm1, + sensor_value: 0, + }, Local { display, adc, @@ -131,19 +142,17 @@ mod app { ) } - #[task(binds = TIMER_IRQ_0, priority = 1, shared = [alarm], local = [display, adc, adc_pin, watchdog])] - fn tick(mut c: tick::Context) { - use numtoa::NumToA; - let display = c.local.display; - display.clear(); + #[task(binds = TIMER_IRQ_0, priority = 1, shared = [alarm0, sensor_value], local = [display])] + fn update_display(mut c: update_display::Context) { let mut buf = [0u8; 20]; - let result: Result = c.local.adc.read(c.local.adc_pin); - let text = match result { - Ok(reading_raw) => reading_raw.numtoa_str(10, &mut buf), - Err(_) => "Error", - }; + let text = c.shared.sensor_value.lock(|val| { + use numtoa::NumToA; + val.numtoa_str(10, &mut buf) + }); + let display = c.local.display; + display.clear(); Text::with_alignment( text, display.bounding_box().center(), @@ -153,11 +162,24 @@ mod app { .draw(display) .unwrap(); display.flush().unwrap(); - c.local.watchdog.feed(); - c.shared.alarm.lock(|a| { + c.shared.alarm0.lock(|a| { + a.clear_interrupt(); + let _ = a.schedule(MicrosDurationU32::from_ticks(DISPLAY_UPDATE_INT_TICKS)); + }); + } + + #[task(binds = TIMER_IRQ_1, priority = 2, shared = [alarm1, sensor_value], local = [adc, adc_pin, watchdog])] + fn read_sensor(mut c: read_sensor::Context) { + let sensor_value: u16 = c.local.adc.read(c.local.adc_pin).unwrap(); + c.shared + .sensor_value + .lock(|v| *v = (*v * (MVG_AVG_COUNT - 1) + sensor_value) / MVG_AVG_COUNT); + + c.local.watchdog.feed(); + c.shared.alarm1.lock(|a| { a.clear_interrupt(); - let _ = a.schedule(MicrosDurationU32::from_ticks(CHANGE_FREQUENCY_TICKS)); + let _ = a.schedule(MicrosDurationU32::from_ticks(DISPLAY_UPDATE_INT_TICKS)); }); }