forked from sirhcel/sht4x
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit adds support for the `embedded-hal-async` crate in addition to `embedded-hal`. I've done this by adding a separate `AsyncSht4x` type, based on the assumption that most projects won't need to use both the blocking `embedded-hal` traits and the `embedded-hal-async` traits at the same time, and providing `async fn` methods on a separate type with the same names as the blocking ones seemed a bit nicer than having one type that has both `fn measure` and `async fn measure_async` and so on. Support for `embedded-hal-async` is gated behind the `embedded-hal-async` feature flag, so the dependency is not enabled by default. Note that this branch depends on my PR sirhcel#6, which updates this crate to use `embedded-hal` v1.0, and currently contains the commit from that change as well. Once sirhcel#6 has merged, this branch will need to be rebased onto the main branch. It also depends on my upstream PR adding `embedded-hal-async` support to `sensirion-i2c-rs`, Sensirion/sensirion-i2c-rs#30, which has been [merged], but hasn't been published to crates.io yet. Currently, this branch adds a Cargo `[patch]` to use a Git dep on `sensirion-i2c-rs`. So, this change cannot be released to crates.io until upstream publishes a new release of `sensirion-i2c-rs`. Hopefully they do that soon! :) [merged]: Sensirion/sensirion-i2c-rs@f7b9f3a
- Loading branch information
Showing
6 changed files
with
217 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
use crate::{ | ||
commands::Command, | ||
error::Error, | ||
sht4x::RESPONSE_LEN, | ||
types::{Address, HeatingDuration, HeatingPower, Measurement, Precision, SensorData}, | ||
}; | ||
use core::marker::PhantomData; | ||
use embedded_hal_async::{delay::DelayNs, i2c::I2c}; | ||
use sensirion_i2c::i2c_async; | ||
|
||
/// Async driver for STH4x sensors. | ||
/// | ||
/// This type behaves identically to the [`Sht4x`](crate::Sht4x) type, except | ||
/// that it uses the `embedded-hal-async` [`I2c`] and [`DelayNs`] traits instead | ||
/// of the `embedded-hal` traits, and all of its methods are `async fn`s. | ||
#[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
#[derive(Debug)] | ||
pub struct AsyncSht4x<I, D> { | ||
i2c: I, | ||
address: Address, | ||
// If we want to globally define the delay type for this struct, we have to consume the type | ||
// parameter. | ||
_delay: PhantomData<D>, | ||
} | ||
|
||
impl<I, D> AsyncSht4x<I, D> | ||
where | ||
I: I2c, | ||
D: DelayNs, | ||
{ | ||
/// Creates a new driver instance using the given I2C bus. It configures the default I2C | ||
/// address 0x44 used by most family members. | ||
/// | ||
/// For operating multiple devices on the same bus, | ||
/// [`shared-bus`](https://github.com/Rahix/shared-bus) might come in handy. | ||
pub fn new(i2c: I) -> Self { | ||
Self::new_with_address(i2c, Address::Address0x44) | ||
} | ||
|
||
/// Crates a new driver instance using the given I2C bus and address. This constructor allows | ||
/// to instantiate the driver for the SHT40-BD1B which uses the non-default I2C address 0x45. | ||
/// | ||
/// For operating multiple devices on the same bus, | ||
/// [`shared-bus`](https://github.com/Rahix/shared-bus) might come in handy. | ||
pub fn new_with_address(i2c: I, address: Address) -> Self { | ||
Self { | ||
i2c, | ||
address, | ||
_delay: PhantomData, | ||
} | ||
} | ||
|
||
/// Destroys the driver and returns the used I2C bus. | ||
pub fn destroy(self) -> I { | ||
self.i2c | ||
} | ||
|
||
/// Activates the heater and performs a measurement returning measurands in SI units. | ||
/// | ||
/// **Note:** The heater is designed to be used up to 10 % of the sensor's lifetime. Please | ||
/// check the | ||
/// [datasheet](https://sensirion.com/media/documents/33FD6951/624C4357/Datasheet_SHT4x.pdf), | ||
/// section 4.9 _Heater Operation_ for details. | ||
pub async fn heat_and_measure( | ||
&mut self, | ||
power: HeatingPower, | ||
duration: HeatingDuration, | ||
delay: &mut D, | ||
) -> Result<Measurement, Error<I::Error>> { | ||
let raw = self.heat_and_measure_raw(power, duration, delay).await?; | ||
|
||
Ok(Measurement::from(raw)) | ||
} | ||
|
||
/// Activates the heater and performs a measurement returning raw sensor data. | ||
/// | ||
/// **Note:** The heater is designed to be used up to 10 % of the sensor's lifetime. Please | ||
/// check the | ||
/// [datasheet](https://sensirion.com/media/documents/33FD6951/624C4357/Datasheet_SHT4x.pdf), | ||
/// section 4.9 _Heater Operation_ for details. | ||
pub async fn heat_and_measure_raw( | ||
&mut self, | ||
power: HeatingPower, | ||
duration: HeatingDuration, | ||
delay: &mut D, | ||
) -> Result<SensorData, Error<I::Error>> { | ||
let command = Command::from((power, duration)); | ||
|
||
self.write_command_and_delay_for_execution(command, delay) | ||
.await?; | ||
let response = self.read_response().await?; | ||
let raw = crate::sht4x::sensor_data_from_response(&response); | ||
|
||
Ok(raw) | ||
} | ||
|
||
/// Performs a measurement returning measurands in SI units. | ||
pub async fn measure( | ||
&mut self, | ||
precision: Precision, | ||
delay: &mut D, | ||
) -> Result<Measurement, Error<I::Error>> { | ||
let raw = self.measure_raw(precision, delay).await?; | ||
Ok(Measurement::from(raw)) | ||
} | ||
|
||
/// Performs a measurement returning raw sensor data. | ||
pub async fn measure_raw( | ||
&mut self, | ||
precision: Precision, | ||
delay: &mut D, | ||
) -> Result<SensorData, Error<I::Error>> { | ||
let command = Command::from(precision); | ||
|
||
self.write_command_and_delay_for_execution(command, delay) | ||
.await?; | ||
let response = self.read_response().await?; | ||
let raw = crate::sht4x::sensor_data_from_response(&response); | ||
|
||
Ok(raw) | ||
} | ||
|
||
/// Reads the sensor's serial number. | ||
pub async fn serial_number(&mut self, delay: &mut D) -> Result<u32, Error<I::Error>> { | ||
self.write_command_and_delay_for_execution(Command::SerialNumber, delay) | ||
.await?; | ||
let response = self.read_response().await?; | ||
|
||
Ok(u32::from_be_bytes([ | ||
response[0], | ||
response[1], | ||
response[3], | ||
response[4], | ||
])) | ||
} | ||
|
||
/// Performs a soft reset of the sensor. | ||
pub async fn soft_reset(&mut self, delay: &mut D) -> Result<(), Error<I::Error>> { | ||
self.write_command_and_delay_for_execution(Command::SoftReset, delay) | ||
.await | ||
} | ||
|
||
async fn read_response(&mut self) -> Result<[u8; RESPONSE_LEN], Error<I::Error>> { | ||
let mut response = [0; RESPONSE_LEN]; | ||
|
||
i2c_async::read_words_with_crc(&mut self.i2c, self.address.into(), &mut response).await?; | ||
|
||
Ok(response) | ||
} | ||
|
||
async fn write_command_and_delay_for_execution( | ||
&mut self, | ||
command: Command, | ||
delay: &mut D, | ||
) -> Result<(), Error<I::Error>> { | ||
let code = command.code(); | ||
|
||
i2c_async::write_command_u8(&mut self.i2c, self.address.into(), code) | ||
.await | ||
.map_err(Error::I2c)?; | ||
delay.delay_ms(command.duration_ms()).await; | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,18 @@ | ||
#![deny(unsafe_code)] | ||
#![no_std] | ||
#![doc = include_str!("../README.md")] | ||
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] | ||
|
||
mod commands; | ||
mod error; | ||
mod sht4x; | ||
mod types; | ||
|
||
#[cfg(feature = "embedded-hal-async")] | ||
mod async_sht4x; | ||
#[cfg(feature = "embedded-hal-async")] | ||
pub use self::async_sht4x::AsyncSht4x; | ||
|
||
pub use crate::error::*; | ||
pub use crate::sht4x::*; | ||
pub use crate::types::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters