From 56ac102a9becdf0df6a2aa3b2422d09c6197d247 Mon Sep 17 00:00:00 2001 From: Frederik Menke Date: Sat, 20 Jul 2024 21:13:54 +0200 Subject: [PATCH] Read co2 sensor data --- Cargo.lock | 1 + Cargo.toml | 2 ++ src/main.rs | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f2993b..6f24a4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -152,6 +152,7 @@ dependencies = [ "embedded-storage", "fixed", "fixed-macro", + "futures", "heapless 0.8.0", "log", "panic-probe", diff --git a/Cargo.toml b/Cargo.toml index e61a61e..ee3d0cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,8 @@ version = "0.1.0" edition = "2021" [dependencies] +futures = { version = "0.3", default-features = false } + embassy-embedded-hal = { version = "0.1.0", features = ["defmt"] } embassy-sync = { version = "0.6.0", features = ["defmt"] } embassy-executor = { version = "0.5.0", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } diff --git a/src/main.rs b/src/main.rs index 895ee74..5647c0c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,8 @@ #![no_std] #![no_main] +use core::future::ready; + use byteorder::ByteOrder; use defmt::*; use embassy_embedded_hal::SetConfig; @@ -17,7 +19,9 @@ use embassy_rp::{gpio, spi}; use embedded_hal_bus::spi::ExclusiveDevice; use embedded_sdmmc::sdcard::{DummyCsPin, SdCard}; use embedded_sdmmc::{Block, BlockDevice, BlockIdx, VolumeIdx}; +use futures::{FutureExt, TryFutureExt}; use gpio::{Level, Output}; +use usbd_hid::descriptor::MouseReport; use {defmt_rtt as _, panic_probe as _}; use embassy_rp::i2c::{self, Config}; @@ -31,8 +35,14 @@ struct DummyTimesource(); /// I2C Address of the co2 sensor const CCS811_I2C_ADDRESS: u16 = 0x5A; -/// I2C Register addresses of the co2 sensor +/// Application I2C Register addresses of the co2 sensor const CCS811_REGISTER_STATUS: u8 = 0x00; +const CCS811_REGISTER_MEAS_MODE: u8 = 0x01; +const CCS811_REGISTER_ALG_RESULT_DATA: u8 = 0x02; + +/// Bootloader I2C Register addresses of the co2 sensor +const CCS811_REGISTER_BOOTLOADER_APP_START: u8 = 0xF4; +const CCS811_REGISTER_BOOTLOADER_STATUS: u8 = CCS811_REGISTER_STATUS; impl embedded_sdmmc::TimeSource for DummyTimesource { fn get_timestamp(&self) -> embedded_sdmmc::Timestamp { @@ -69,7 +79,7 @@ async fn main(spawner: Spawner) { Timer::after(Duration::from_secs(1)).await; debug!("Writing to I2C"); - let mut status = [42]; + let mut status = [42u8]; i2c.write_async(CCS811_I2C_ADDRESS, [CCS811_REGISTER_STATUS]) .await .unwrap(); @@ -77,10 +87,71 @@ async fn main(spawner: Spawner) { i2c.read_async(CCS811_I2C_ADDRESS, &mut status) .await .unwrap(); + let status = status[0]; info!("Reported status: {}", status); + match status { + 16u8 => {} + 144u8 => { + warn!("Sensor already in APP mode! Configuration may come from previous boot."); + } + unexpected => { + warn!( + "Sensor reported unexpected state after boot: {}", + unexpected + ); + } + } - debug!("TASK ENDED: Main") + // APP_START does not require to write data + i2c.write_async(CCS811_I2C_ADDRESS, [CCS811_REGISTER_BOOTLOADER_APP_START]) + .await + .unwrap(); + + // After APP_START, we have to wait 1 ms (according to datasheet) + Timer::after(Duration::from_millis(1000)).await; + + // Mode 1 is 1 measurement per second + i2c.write_async(CCS811_I2C_ADDRESS, [CCS811_REGISTER_MEAS_MODE, 16]) + .await + .unwrap(); + + loop { + let mut status = [42u8]; + i2c.write_async(CCS811_I2C_ADDRESS, [CCS811_REGISTER_STATUS]) + .await; + // .unwrap(); + i2c.read_async(CCS811_I2C_ADDRESS, &mut status).await; + // .unwrap(); + let status = status[0]; + + let mut measured_value_buffer = [42u8; 2]; + let address_written = i2c + .write_async(CCS811_I2C_ADDRESS, [CCS811_REGISTER_ALG_RESULT_DATA]) + .await + .ok(); + + let data_written = if let Some(()) = address_written { + i2c.read_async(CCS811_I2C_ADDRESS, &mut measured_value_buffer) + .await + .ok() + } else { + None + }; + + let measured_value = if let Some(()) = data_written { + Some(u16::from_be_bytes(measured_value_buffer)) + } else { + None + }; + + info!( + "Reported status: {}\tMeasured value: {}", + status, measured_value + ); + + Timer::after(Duration::from_secs(2)).await; + } } #[embassy_executor::task]