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;