Skip to main content

scd41_embedded/
lib.rs

1//! no_std driver for the Sensirion SCD41 CO₂ / temperature / humidity sensor.
2//!
3//! `scd41-embedded` is a small, `no_std` driver for the **Sensirion SCD41** (SCD4x family),
4//! built on top of the [`embedded-hal`](https://crates.io/crates/embedded-hal) traits.
5//!
6//! This crate is a clean reimplementation inspired by existing Rust work in this space
7//! (notably `scd4x`: <https://github.com/hauju/scd4x-rs>), while following the same async feature
8//! conventions used by the other drivers in this workspace.
9//!
10//! ## What this crate provides
11//! - A blocking driver: [`Scd41`]
12//! - Basic configuration + measurement methods
13//! - Optional async API behind the `async` feature: [`r#async::Scd41Async`]
14//!
15//! ## Blocking usage
16//!
17//! ```
18//! use scd41_embedded::{Error, Scd41};
19//!
20//! fn example<I2C, D, E>(i2c: I2C, delay: D) -> Result<(), Error<E>>
21//! where
22//!     I2C: embedded_hal::i2c::I2c<Error = E>,
23//!     D: embedded_hal::delay::DelayNs,
24//!     E: embedded_hal::i2c::Error,
25//! {
26//!     let mut scd = Scd41::new(i2c, delay);
27//!     scd.start_periodic_measurement()?;
28//!
29//!     loop {
30//!         if scd.data_ready()? {
31//!             let m = scd.measurement()?;
32//!             // m.co2_ppm
33//!             // m.temperature_c
34//!             // m.relative_humidity_percent
35//!             break;
36//!         }
37//!     }
38//!
39//!     Ok(())
40//! }
41//! ```
42//!
43//! ## Async usage
44//!
45//! Enable the `async` feature to use the async driver API in [`r#async`].
46//! The async API uses [`embedded-hal-async`](https://crates.io/crates/embedded-hal-async) and
47//! requires async implementations of both `I2c` and `DelayNs`.
48//!
49//! ```
50//! # fn main() {}
51//! #
52//! # #[cfg(feature = "async")]
53//! # mod async_example {
54//! use scd41_embedded::{Error};
55//! use scd41_embedded::r#async::Scd41Async;
56//!
57//! pub async fn example<I2C, D, E>(i2c: I2C, delay: D) -> Result<(), Error<E>>
58//! where
59//!     I2C: embedded_hal_async::i2c::I2c<Error = E>,
60//!     D: embedded_hal_async::delay::DelayNs,
61//!     E: embedded_hal::i2c::Error,
62//! {
63//!     let mut scd = Scd41Async::new(i2c, delay);
64//!     scd.start_periodic_measurement().await?;
65//!
66//!     loop {
67//!         if scd.data_ready().await? {
68//!             let _m = scd.measurement().await?;
69//!             break;
70//!         }
71//!     }
72//!     Ok(())
73//! }
74//! # }
75//! ```
76//!
77//! ## Notes
78//! - The SCD41 uses a per-word CRC byte (Sensirion CRC-8). This crate validates CRCs on reads.
79//! - Some commands are not intended to be used while periodic measurement is running.
80
81#![no_std]
82#![deny(unsafe_code)]
83#![deny(missing_docs)]
84
85#[cfg(test)]
86extern crate std;
87
88mod crc;
89mod error;
90pub mod types;
91
92mod scd41;
93pub use scd41::{Scd41, DEFAULT_ADDRESS};
94
95pub use error::Error;
96
97#[cfg(feature = "async")]
98pub mod r#async;