From ce6d142d96a1967ef89b89b625d21c1a6300626c Mon Sep 17 00:00:00 2001 From: Adam Macdonald <72780006+twokilohertz@users.noreply.github.com> Date: Fri, 28 Feb 2025 20:30:56 +0000 Subject: [PATCH] Switch to embassy-rs, I2C blocking --- Cargo.lock | 20 +++++++++++++++ Cargo.toml | 6 +++++ src/main.rs | 62 +++++++++++++++++++++++++++++++++++++++++----- src/sensor_task.rs | 0 4 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 src/sensor_task.rs diff --git a/Cargo.lock b/Cargo.lock index ceda4b9..b82816b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -805,6 +805,7 @@ dependencies = [ "embassy-rp", "embassy-time", "rtt-target", + "scd4x", ] [[package]] @@ -1034,6 +1035,16 @@ version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" +[[package]] +name = "scd4x" +version = "0.4.0" +source = "git+https://github.com/twokilohertz/scd4x-rs.git?branch=main#b9b0cb774b78ec7317c3e66f2fae745711101abb" +dependencies = [ + "embedded-hal 1.0.0", + "log", + "sensirion-i2c", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -1055,6 +1066,15 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "sensirion-i2c" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "640a03c95c176226cf159ae2727f7fe3245546022639d61459af46d2878aec06" +dependencies = [ + "embedded-hal 1.0.0", +] + [[package]] name = "sha2-const-stable" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 21d0032..a50d8e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,10 +23,16 @@ embassy-executor = { version = "0.7.0", features = [ ] } embassy-time = "0.4.0" +# System cortex-m-rt = "0.7.5" critical-section = "1.2.0" rtt-target = "0.6.1" +# Peripherals +scd4x = { git = "https://github.com/twokilohertz/scd4x-rs.git", branch = "main", features = [ + "scd41", +] } + [profile.dev] opt-level = "s" diff --git a/src/main.rs b/src/main.rs index b29143c..e06c809 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,19 +1,67 @@ #![no_std] #![no_main] -use core::panic::PanicInfo; - use rtt_target::{rprintln, rtt_init_print}; use embassy_executor::Spawner; use embassy_rp::block::ImageDef; +mod sensor_task; + +embassy_rp::bind_interrupts!(struct Irqs { + I2C0_IRQ => embassy_rp::i2c::InterruptHandler; +}); + +/// Entrypoint #[embassy_executor::main] async fn main(_spawner: Spawner) { + // Initialise RTT logging + rtt_init_print!(); rprintln!("RTT logging initialised"); - let _peripherals = embassy_rp::init(Default::default()); + let peripherals = embassy_rp::init(Default::default()); + + let sda = peripherals.PIN_4; + let scl = peripherals.PIN_5; + let i2c_config = embassy_rp::i2c::Config::default(); + let i2c_bus = embassy_rp::i2c::I2c::new_blocking(peripherals.I2C0, scl, sda, i2c_config); + + embassy_time::Timer::after_millis(30).await; // SCD41 power-up delay + let mut scd41 = scd4x::Scd4x::new(i2c_bus, embassy_time::Delay); + scd41.wake_up(); + scd41.reinit().unwrap(); + + match scd41.serial_number() { + Ok(serial) => rprintln!("[SCD41] Serial number: {}", serial), + Err(error) => rprintln!( + "[SCD41] Error: did not respond to get_serial_number: {:?}", + error + ), + } + + scd41.start_periodic_measurement().unwrap(); + + loop { + embassy_time::Timer::after_secs(5).await; + match scd41.measurement() { + Ok(data) => { + rprintln!( + "[SCD41] CO2: {} ppm, temperature: {} C, humidity: {} RH", + data.co2, + data.temperature, + data.humidity + ); + } + Err(error) => { + rprintln!( + "[SCD41] Error: failed to retrieve measurement data: {:?}", + error + ); + break; + } + } + } loop { unsafe { @@ -22,8 +70,9 @@ async fn main(_spawner: Spawner) { } } +/// Panic handler #[panic_handler] -fn panic(info: &PanicInfo) -> ! { +fn panic(info: &core::panic::PanicInfo) -> ! { rprintln!("Panicked! {}", info); loop { @@ -33,17 +82,18 @@ fn panic(info: &PanicInfo) -> ! { } } +/// Executable type header for the RP2350 bootloader #[link_section = ".start_block"] #[used] static IMAGE_DEF: ImageDef = ImageDef::secure_exe(); -// Program metadata for picotool +/// Program metadata for picotool #[link_section = ".bi_entries"] #[used] pub static PICOTOOL_ENTRIES: [embassy_rp::binary_info::EntryAddr; 4] = [ embassy_rp::binary_info::rp_program_name!(c"Pico Environment Sensor"), embassy_rp::binary_info::rp_program_description!( - c"A CO2, temperature & humidity sensing application for the RPi Pico 2 W" + c"CO2, temperature & humidity sensing application for the RPi Pico 2 W" ), embassy_rp::binary_info::rp_cargo_version!(), embassy_rp::binary_info::rp_program_build_attribute!(), diff --git a/src/sensor_task.rs b/src/sensor_task.rs new file mode 100644 index 0000000..e69de29