From 734916620251c307b207e5071986053a69e56cc2 Mon Sep 17 00:00:00 2001 From: Timo Date: Fri, 27 Oct 2023 18:03:12 +0200 Subject: [PATCH] Make library no_std compatible (#5) * Use embedded_hal::blocking::delay::DelayMs instead of std::thread::sleep * Make thiserror dependency an optional feature Co-authored-by: Timo --- Cargo.toml | 7 +++---- README.md | 4 ++-- src/error.rs | 21 ++++++++++----------- src/lib.rs | 24 +++++++++++++++--------- src/mode/simple_single_shot.rs | 28 ++++++++++++---------------- 5 files changed, 42 insertions(+), 42 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 99f058f..b770720 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "sht31" description = "A library for the SHT31 temperature and humidity sensor" -version = "0.1.1" +version = "0.2.0" edition = "2021" license = "MIT" repository = "https://github.com/FloppyDisck/SHT31-rs" @@ -11,11 +11,10 @@ categories = ["embedded"] [features] esp32-fix = [] +thiserror = ["dep:thiserror"] [dependencies] -embedded-svc = "0.22.0" embedded-hal = "0.2.7" crc = "3.0.0" -anyhow = "1" -thiserror = "1.0.38" \ No newline at end of file +thiserror = {version= "1.0.38", optional = true} \ No newline at end of file diff --git a/README.md b/README.md index 4bd013c..181cc58 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,8 @@ the current thread until the sensor does a reading. use sht31::prelude::*; fn main() -> Result<()> { - // Requires an 12c connection only - let sht = SHT31::new(i2c); + // Requires an i2c connection + delay (both from embedded_hal::blocking) + let sht = SHT31::new(i2c, delay); loop { let reading = sht.read()?; diff --git a/src/error.rs b/src/error.rs index 02534fb..b383fcd 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,36 +1,35 @@ -use thiserror::Error; +pub type Result = core::result::Result; -pub type Result = std::result::Result; - -#[derive(Error, Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] +#[cfg_attr(feature = "thiserror", derive(thiserror::Error))] +#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] pub enum SHTError { - #[error("Write Read I2C Error")] + #[cfg_attr(feature = "thiserror", error("Write Read I2C Error"))] WriteReadI2CError, - #[error("Write I2C Error")] + #[cfg_attr(feature = "thiserror", error("Write I2C Error")) ] WriteI2CError, - #[error("Humidity bytes [{bytes_start:#x}, {bytes_end:#x}] expected {expected_checksum:#x} but got the checksum {calculated_checksum:#x}")] + #[cfg_attr(feature = "thiserror", error("Humidity bytes [{bytes_start:#x}, {bytes_end:#x}] expected {expected_checksum:#x} but got the checksum {calculated_checksum:#x}"))] InvalidHumidityChecksumError { bytes_start: u8, bytes_end: u8, expected_checksum: u8, calculated_checksum: u8, }, - #[error("Temperature bytes [{bytes_start:#x}, {bytes_end:#x}] expected {expected_checksum:#x} but got the checksum {calculated_checksum:#x}")] + #[cfg_attr(feature = "thiserror", error("Temperature bytes [{bytes_start:#x}, {bytes_end:#x}] expected {expected_checksum:#x} but got the checksum {calculated_checksum:#x}"))] InvalidTemperatureChecksumError { bytes_start: u8, bytes_end: u8, expected_checksum: u8, calculated_checksum: u8, }, - #[error("Status bytes [{bytes_start:#x}, {bytes_end:#x}] expected {expected_checksum:#x} but got the checksum {calculated_checksum:#x}")] + #[cfg_attr(feature = "thiserror", error("Status bytes [{bytes_start:#x}, {bytes_end:#x}] expected {expected_checksum:#x} but got the checksum {calculated_checksum:#x}"))] InvalidStatusChecksumError { bytes_start: u8, bytes_end: u8, expected_checksum: u8, calculated_checksum: u8, }, - #[error("Single shot reading timeout")] + #[cfg_attr(feature = "thiserror", error("Single shot reading timeout"))] ReadingTimeoutError, - #[error("This error should not happen")] + #[cfg_attr(feature = "thiserror", error("This error should not happen"))] PlaceholderError, } diff --git a/src/lib.rs b/src/lib.rs index 2904ce5..1d76177 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,12 @@ +#![no_std] +use core::prelude::v1::*; + pub mod error; pub mod mode; use crate::mode::SimpleSingleShot; use crc::{Algorithm, Crc}; -use embedded_hal::blocking::i2c; +use embedded_hal::blocking::{i2c, delay::DelayMs}; pub use crate::error::{Result, SHTError}; pub mod prelude { @@ -163,15 +166,16 @@ impl SHT31 { } #[allow(dead_code)] -impl SHT31 +impl SHT31, I2C> where I2C: i2c::WriteRead + i2c::Write, + D: DelayMs { /// Create a new sensor /// I2C clock frequency must must be between 0 and 1000 kHz - pub fn new(i2c: I2C) -> Self { + pub fn new(i2c: I2C, delay: D) -> Self { Self { - mode: SimpleSingleShot::new(), + mode: SimpleSingleShot::new(delay), i2c, address: DeviceAddr::default() as u8, unit: TemperatureUnit::default(), @@ -292,6 +296,11 @@ where self.i2c_write(&[0x30, 0x41]) } + /// Consumes the instance and returns the i2c + pub fn destroy(self) -> I2C { + self.i2c + } + fn i2c_write(&mut self, bytes: &[u8]) -> Result<()> { match self.i2c.write(self.address, bytes) { Ok(res) => Ok(res), @@ -366,27 +375,24 @@ mod test { assert_eq!( verify_reading(corrupt_temperature) .err() - .unwrap() - .to_string(), + .unwrap(), SHTError::InvalidTemperatureChecksumError { bytes_start: 98, bytes_end: 153, expected_checksum: 180, calculated_checksum: 188 } - .to_string() ); let corrupt_humidity = [98, 153, 188, 98, 32, 180]; assert_eq!( - verify_reading(corrupt_humidity).err().unwrap().to_string(), + verify_reading(corrupt_humidity).err().unwrap(), SHTError::InvalidHumidityChecksumError { bytes_start: 98, bytes_end: 32, expected_checksum: 180, calculated_checksum: 139 } - .to_string() ); } diff --git a/src/mode/simple_single_shot.rs b/src/mode/simple_single_shot.rs index 56aef6f..89bf199 100644 --- a/src/mode/simple_single_shot.rs +++ b/src/mode/simple_single_shot.rs @@ -3,28 +3,23 @@ use crate::{ mode::{single_shot::single_shot_read, Sht31Reader}, Accuracy, Reading, SHT31, }; -use embedded_hal::blocking::i2c; -use std::{thread::sleep, time::Duration}; +use embedded_hal::blocking::{i2c, delay::DelayMs}; /// A simple reading that blocks until the measurement is obtained #[derive(Copy, Clone, Debug)] -pub struct SimpleSingleShot { +pub struct SimpleSingleShot >{ max_retries: u8, - ms_delay: u64, + ms_delay: u32, + delay: D } -impl Default for SimpleSingleShot { - fn default() -> Self { - Self::new() - } -} - -impl SimpleSingleShot { +impl SimpleSingleShot where D: DelayMs { #[allow(dead_code)] - pub fn new() -> Self { + pub fn new(delay: D) -> Self { Self { max_retries: 8, ms_delay: 100, + delay } } /// Sets the max number of retries to read a sensor before giving up @@ -37,19 +32,20 @@ impl SimpleSingleShot { self } /// Sets the millisecond delay between each try - pub fn set_delay(&mut self, ms_delay: u64) { + pub fn set_delay(&mut self, ms_delay: u32) { self.ms_delay = ms_delay } /// Sets the millisecond delay between each try - pub fn with_delay(mut self, ms_delay: u64) -> Self { + pub fn with_delay(mut self, ms_delay: u32) -> Self { self.set_delay(ms_delay); self } } -impl Sht31Reader for SHT31 +impl Sht31Reader for SHT31, I2C> where I2C: i2c::WriteRead + i2c::Write, + D: DelayMs { /// It will initiate a read and wont stop until its either exhausted its retries or a reading is found fn read(&mut self) -> Result { @@ -69,7 +65,7 @@ where read_attempt = single_shot_read(self); if read_attempt.is_err() { - sleep(Duration::from_millis(self.mode.ms_delay)) + self.mode.delay.delay_ms(self.mode.ms_delay); } else { return read_attempt; }