Skip to content

Commit

Permalink
abstract scd4x CO2 sensor
Browse files Browse the repository at this point in the history
  • Loading branch information
BrendanBall committed Nov 3, 2023
1 parent b682b00 commit 6b56aae
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 52 deletions.
16 changes: 12 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ members = [
"airquamon_domain",
"display_themes",
"esp32c3_nostd",
"epd_display"
"epd_display",
"sensor"
]

resolver = "2"
Expand Down
2 changes: 1 addition & 1 deletion esp32c3_nostd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ edition = "2021"
airquamon_domain = { path = "../airquamon_domain" }
display_themes = { path = "../display_themes" }
epd_display = { path = "../epd_display" }
sensor = { path = "../sensor" }
esp32c3-hal = { git = "https://github.com/esp-rs/esp-hal.git", rev = "33bfe80d958911f4d0b43adb89cca34b5dce1676", features = ["eh1"] }
esp-hal-common = { git = "https://github.com/esp-rs/esp-hal.git", rev = "33bfe80d958911f4d0b43adb89cca34b5dce1676", features = ["esp32c3", "eh1"] }
esp-backtrace = { version = "0.8.0", features = ["esp32c3", "panic-handler", "exception-handler", "print-uart"] }
esp-println = { version = "0.6.0", features = ["esp32c3","log"] }
log = { version = "0.4.18" }
scd4x = "0.2.1"
epd-waveshare = { path = "/home/brendan/dev/projects/epd-waveshare" }
embedded-graphics = "0.8.1"
embedded-hal = "1.0.0-rc.1"
Expand Down
51 changes: 5 additions & 46 deletions esp32c3_nostd/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@ use esp32c3_hal::{
prelude::*,
Delay,
};
use embedded_hal::delay::DelayUs;
use scd4x::scd4x::Scd4x;
use epd_waveshare::{epd2in9b_v3::{Display2in9b, Epd2in9b}, graphics::DisplayRotation};
use log::info;
use airquamon_domain::Data;
use display_themes::Theme2;
use epd_display::{Display, DisplayTheme};
use sensor::{Sensor, Scd4xSensor};

#[entry]
fn main() -> ! {
Expand Down Expand Up @@ -49,7 +47,7 @@ fn main() -> ! {
);

info!("Connecting to sensor");
let mut sensor = Scd4x::new(i2c, delay);
let mut sensor = Scd4xSensor::new(i2c, delay);

let mosi = io.pins.gpio4;
let sck = io.pins.gpio5;
Expand Down Expand Up @@ -90,57 +88,18 @@ fn main() -> ! {
Theme2::new()
);

sensor.wake_up();
// sensor.set_automatic_self_calibration(true).expect("failed enabling sensor automatic self calibration");
sensor.stop_periodic_measurement().unwrap();
sensor.reinit().unwrap();

let serial = sensor.serial_number().unwrap();
info!("Serial: {:#04x}", serial);

loop {
// sensor.wake_up();
info!("Starting periodic measurement");
sensor.start_periodic_measurement().unwrap();
DelayUs::delay_ms(&mut delay, 5000);

info!("Waiting for data ready");
loop {
match sensor.data_ready_status() {
Ok(true) => break,
Ok(false) => DelayUs::delay_ms(&mut delay, 100),
Err(e) => {
panic!("Failed to poll for data ready: {:?}", e);
},
}
}

info!("Reading sensor data");
let data = match sensor.measurement() {
Ok(v) => v,
Err(e) => {
panic!("Failed to read measurement: {:?}", e);
},
};
let data = sensor.measure().expect("failed reading sensor");

info!(
"CO2: {0}, Temperature: {1:#.2} °C, Humidity: {2:#.2} RH",
data.co2, data.temperature, data.humidity
);

info!("Stop sensor periodic measurement");
// sensor.power_down().expect("failed powering down sensor");
sensor.stop_periodic_measurement().expect("failed to stop sensor periodic measurement");


info!("updating display");
display.draw(&Data {
co2: data.co2,
temperature: data.temperature,
humidity: data.humidity,
}).expect("draw failed");
display.draw(&data).expect("draw failed");

info!("Sleeping");
DelayUs::delay_ms(&mut delay, 60000);
delay.delay_ms(60000u32);
}
}
15 changes: 15 additions & 0 deletions sensor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "sensor"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
airquamon_domain = { path = "../airquamon_domain" }
embedded-hal = "1.0.0-rc.1"

[dependencies.scd4x]
version = "0.2.1"
path = "../../../scd4x-rs"
default-features = false
12 changes: 12 additions & 0 deletions sensor/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![no_std]

use airquamon_domain::Data;

mod scd4x_sensor;
pub use scd4x_sensor::Scd4xSensor;

pub trait Sensor {
type Error;

fn measure(&mut self) -> Result<Data, Self::Error>;
}
55 changes: 55 additions & 0 deletions sensor/src/scd4x_sensor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use airquamon_domain::Data;
use embedded_hal::{i2c::I2c, delay::DelayUs};
use scd4x::{Scd4x, Error};
use crate::Sensor;

pub struct Scd4xSensor<I2C, DELAY> {
scd4x: Scd4x<I2C, DELAY>,
delay: DELAY,
}

impl<I2C, DELAY> Scd4xSensor<I2C, DELAY>
where
I2C: I2c,
DELAY: DelayUs + Copy,
{
pub fn new(i2c: I2C, delay: DELAY) -> Self {
Self {
scd4x: Scd4x::new(i2c, delay),
delay,
}
}
}

impl<I2C, DELAY> Sensor for Scd4xSensor<I2C, DELAY>
where
I2C: I2c,
DELAY: DelayUs,
{

type Error = Error<I2C::Error>;

fn measure(&mut self) -> Result<Data, Self::Error> {
self.scd4x.wake_up();
self.scd4x.reinit()?;
self.scd4x.start_periodic_measurement()?;
self.delay.delay_ms(5000);
loop {
match self.scd4x.data_ready_status() {
Ok(true) => break,
Ok(false) => {
self.delay.delay_ms(100);
Ok(())
},
Err(e) => Err(e),
}?;
}
let data = self.scd4x.measurement()?;
self.scd4x.stop_periodic_measurement()?;
Ok(Data {
co2: data.co2,
temperature: data.temperature,
humidity: data.humidity
})
}
}

0 comments on commit 6b56aae

Please sign in to comment.