Skip to content

Commit

Permalink
Update to embedded_hal 1.0 (#8)
Browse files Browse the repository at this point in the history
* Support embedded-hal 1.0.0

* Improve rust-analyzer coverage in vscode

* Fix test error by cloning mock to allow explicit done() call

* Fix compilation issues in doctests

* Fix syntax error in doctests

* Fix compilation errors in doctests

* Avoid embedded-hal 0.2 dependency

Co-authored-by: Diego Barrios Romero <[email protected]>

* Convert write delay back to u8

Co-authored-by: Diego Barrios Romero <[email protected]>

* Convert write delay back to u8

Co-authored-by: Diego Barrios Romero <[email protected]>

* Convert write delay back to u8

Co-authored-by: Diego Barrios Romero <[email protected]>

* Convert write delay back to u8

Co-authored-by: Diego Barrios Romero <[email protected]>

* Complete converting write delay back to u8 revert

* Split wrong_address_raises_error into two tests

* Update version to 0.3.0 and updated changelog

* Complete updating to v0.3.0

* Restore format of Cargo.toml to eliminate actions build failure

* Add defmt-03 feature, enabling defmt formatting of public types

* defmt-03 adds include defmt of error messages from embedded-hal

* Modify changelog similar to changes in eeprom24x-rs

---------

Co-authored-by: Phil Markgraf <[email protected]>
Co-authored-by: Diego Barrios Romero <[email protected]>
  • Loading branch information
3 people authored May 23, 2024
1 parent 48c19a2 commit 596c5ad
Show file tree
Hide file tree
Showing 14 changed files with 141 additions and 66 deletions.
11 changes: 11 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"rust-analyzer.check.command": "clippy",
"rust-analyzer.check.allTargets": true,
"rust-analyzer.check.extraArgs": [
"--target",
"x86_64-unknown-linux-musl"
],
"rust-analyzer.cargo.noDefaultFeatures": true,
"rust-analyzer.imports.preferNoStd": true,
"rust-analyzer.showUnlinkedFileNotification": false,
}
17 changes: 14 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,29 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

## [0.3.0] - 2024-05-21

### Changed

- [breaking-change] Transitioned `embedded-hal` to version 1.0
- Add feature `defmt-03` to derive "`defmt::Format`" from `defmt = "0.3"` for public types.

## [0.2.1] - 2023-06-02

### Added
- Methods for reading tempature as a integer (`u16`).

- Methods for reading temperature as a integer (`u16`).
Users are advised to ONLY use these methods if running into to trouble using
the standard tempature reading methods returning `f32` values as it's a more accurate read.
the standard temperature reading methods returning `f32` values as it's a more accurate read.

## [0.2.0] - 2021-05-22

### Added

- Add support for device sleep and wake.

### Changed

- Removed delays after final EEPROM writes before exiting a method.
Users are advised to wait enough time before interacting with the device again.
Thanks to @David-OConnor for the suggestion.
Expand All @@ -28,7 +38,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

Initial release to crates.io.

[Unreleased]: https://github.com/eldruin/mlx9061x-rs/compare/v0.2.1...HEAD
[Unreleased]: https://github.com/eldruin/mlx9061x-rs/compare/v0.3.0...HEAD
[0.3.0]: https://github.com/eldruin/mlx9061x-rs/compare/v0.2.1...v0.3.0
[0.2.1]: https://github.com/eldruin/mlx9061x-rs/compare/v0.2.0...v0.2.1
[0.2.0]: https://github.com/eldruin/mlx9061x-rs/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/eldruin/mlx9061x-rs/releases/tag/v0.1.0
22 changes: 16 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
[package]
name = "mlx9061x"
version = "0.2.1"
version = "0.3.0"
authors = ["Diego Barrios Romero <[email protected]>"]
repository = "https://github.com/eldruin/mlx9061x-rs"
license = "MIT OR Apache-2.0"
description = "Platform-agnostic Rust driver for the MLX90614 and MLX90615 non-contact infrared thermometers."
readme = "README.md"
keywords = ["infrared", "thermometer", "temperature", "sensor", "embedded-hal-driver"]
keywords = [
"infrared",
"thermometer",
"temperature",
"sensor",
"embedded-hal-driver",
]
categories = ["embedded", "hardware-support", "no-std"]
homepage = "https://github.com/eldruin/mlx9061x-rs"
documentation = "https://docs.rs/mlx9061x"
Expand All @@ -18,15 +24,19 @@ include = [
"/LICENSE-MIT",
"/LICENSE-APACHE",
]
edition = "2018"
edition = "2021"

[features]
defmt-03 = ["dep:defmt", "embedded-hal/defmt-03"]

[dependencies]
embedded-hal = "0.2.5"
embedded-hal = "1.0.0"
smbus-pec = "1"
defmt = { version = "0.3.6", optional = true }

[dev-dependencies]
linux-embedded-hal = "0.3"
embedded-hal-mock = "0.9"
linux-embedded-hal = "0.4"
embedded-hal-mock = { version = "0.10", default-features = false, features = ["eh1"] }

[profile.release]
lto = true
44 changes: 40 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This is a platform agnostic Rust driver for the MLX90614/MLX90615 infrared
thermometers using the [`embedded-hal`] traits.

This driver allows you to:

- Read the last object temperature measurement. See: `object1_temperature()`.
- Read the last ambient temperature measurement. See: `ambient_temperature()`.
- Read the last raw IR measurement. See: `raw_ir_channel1()`.
Expand Down Expand Up @@ -37,6 +38,7 @@ The readout resolution is 0.01°C (MLX90614) / 0.02°C (MLX90615).
This driver uses the SMBus interface.

Documentation:

- Datasheets: [MLX90614](https://www.melexis.com/-/media/files/documents/datasheets/mlx90614-datasheet-melexis.pdf), [MLX90615](https://www.melexis.com/-/media/files/documents/datasheets/mlx90615-datasheet-melexis.pdf)
- [SMBus communication with MLX90614](https://www.melexis.com/-/media/files/documents/application-notes/mlx90614-smbus-communication-application-note-melexis.pdf)

Expand Down Expand Up @@ -64,6 +66,40 @@ fn main() {
}
```

## Features

### defmt-03

defmt ("de format", short for "deferred formatting") is a highly efficient logging framework that targets resource-constrained devices, like microcontrollers. Learn more about defmt at [https://defmt.ferrous-systems.com].

When feature "defmt-03" is enabled for the mlx9061x-rs dependency, defmt::Format is derived for most public struct and enum definitions. This allows (deferred-)formatting of data for logging and other reporting using the defmt crate. Data from the mlx9061x crate can then be logged alongside any other defmt-supported data using the normal defmt statements.

To enable defmt support, when specifying a dependency on mlx9061x, add the feature "defmt-03"

```toml
[dependencies]
mlx9061x = { version = "0.3.0", features = ["defmt-03"] }
```

#### defmt-03 usage

```rust
use linux_embedded_hal::I2cdev;
use mlx9061x::{Mlx9061x, SlaveAddr};

fn main() {
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let addr = SlaveAddr::default();
let mut sensor = Mlx9061x::new_mlx90614(dev, addr, 5).unwrap();
loop {
match sensor.object1_temperature() {
Ok(obj_temp) => defmt::info!("Object temperature: {=f32}ºC", obj_temp),
Err(err) => defmt::error!("mlx9061x error {:?}", err),
}
}
}
```

## Support

For questions, issues, feature requests, and other changes, please file an
Expand All @@ -73,10 +109,10 @@ For questions, issues, feature requests, and other changes, please file an

Licensed under either of

* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
http://opensource.org/licenses/MIT)
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
<http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or
<http://opensource.org/licenses/MIT>)

at your option.

Expand Down
6 changes: 3 additions & 3 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
register_access::{mlx90614, mlx90615},
Error, Mlx9061x, SlaveAddr,
};
use embedded_hal::blocking::{delay::DelayMs, i2c};
use embedded_hal::{delay::DelayNs, i2c::I2c};

impl<I2C, IC> Mlx9061x<I2C, IC> {
/// Destroy driver instance, return I²C bus.
Expand All @@ -16,14 +16,14 @@ macro_rules! common {
($ic_marker:ident, $ic_reg:ident) => {
impl<E, I2C> Mlx9061x<I2C, ic::$ic_marker>
where
I2C: i2c::WriteRead<Error = E> + i2c::Write<Error = E>,
I2C: I2c<Error = E>,
{
/// Change the device address
///
/// The address will be stored in the EEPROM.
/// The address will be first cleared, before the new one is written.
/// After each write the configured delay will be waited except the last time.
pub fn set_address<D: DelayMs<u8>>(
pub fn set_address<D: DelayNs>(
&mut self,
address: SlaveAddr,
delay_ms: &mut D,
Expand Down
34 changes: 21 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,26 +137,32 @@
//! Note that the I2C pin construction/deconstruction depends on the HAL implementation.
//!
//! ```no_run
//! # use embedded_hal::blocking::{delay::DelayMs, i2c};
//! # use embedded_hal::digital::v2::OutputPin;
//! # use embedded_hal::{delay::DelayNs, i2c::{self, I2c}};
//! # use embedded_hal::digital::{self, OutputPin};
//! # use core::convert::Infallible;
//! # struct IoPin;
//! # impl OutputPin for IoPin {
//! # type Error = ();
//! # fn set_high(&mut self) -> Result<(), ()> { Ok(()) }
//! # fn set_low(&mut self) -> Result<(), ()> { Ok(()) }
//! # fn set_high(&mut self) -> Result<(), Infallible> { Ok(()) }
//! # fn set_low(&mut self) -> Result<(), Infallible> { Ok(()) }
//! # }
//! #
//! # impl digital::ErrorType for IoPin {
//! # type Error = Infallible;
//! # }
//! #
//! # struct I2c1 {
//! # scl: IoPin,
//! # sda: IoPin
//! # }
//! # impl i2c::Write for I2c1 {
//! # type Error = ();
//! # fn write(&mut self, addr: u8, data: &[u8]) -> Result<(), ()> { Ok(()) }
//! # impl I2c for I2c1 {
//! # fn read(&mut self, _: u8, _: &mut [u8]) -> Result<(), Infallible> { Ok(()) }
//! # fn write(&mut self, _: u8, _: &[u8]) -> Result<(), Infallible> { Ok(()) }
//! # fn write_read(&mut self, _: u8, _: &[u8], _: &mut[u8]) -> Result<(), Infallible> { Ok(()) }
//! # fn transaction(&mut self, _: u8, _: &mut [i2c::Operation<'_>]) -> Result<(), Infallible> { Ok(()) }
//! # }
//! # impl i2c::WriteRead for I2c1 {
//! # type Error = ();
//! # fn write_read(&mut self, addr: u8, data: &[u8], buf: &mut[u8]) -> Result<(), ()> { Ok(()) }
//! #
//! # impl i2c::ErrorType for I2c1 {
//! # type Error = Infallible;
//! # }
//! #
//! # impl I2c1 {
Expand All @@ -171,8 +177,10 @@
//! # }
//! #
//! # struct Delay;
//! # impl DelayMs<u8> for Delay {
//! # fn delay_ms(&mut self, _: u8) {}
//! # impl DelayNs for Delay {
//! # fn delay_ns(&mut self, _: u32) {}
//! # fn delay_us(&mut self, _: u32) {}
//! # fn delay_ms(&mut self, _: u32) {}
//! # }
//! # let sda = IoPin;
//! # let scl = IoPin;
Expand Down
18 changes: 5 additions & 13 deletions src/mlx90614.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,11 @@ use crate::{
Error, Mlx9061x, SlaveAddr,
};
use core::marker::PhantomData;
use embedded_hal::{
blocking::{delay::DelayMs, i2c},
digital::v2::OutputPin,
};
use embedded_hal::{delay::DelayNs, digital::OutputPin, i2c::I2c};

impl<E, I2C> Mlx9061x<I2C, ic::Mlx90614>
where
I2C: i2c::WriteRead<Error = E> + i2c::Write<Error = E>,
I2C: I2c<Error = E>,
{
/// Create new instance of the MLX90614 device.
///
Expand Down Expand Up @@ -112,7 +109,7 @@ where
/// Set emissivity epsilon [0.1-1.0]
///
/// Wrong values will return `Error::InvalidInputData`.
pub fn set_emissivity<D: DelayMs<u8>>(
pub fn set_emissivity<D: DelayNs>(
&mut self,
epsilon: f32,
delay: &mut D,
Expand Down Expand Up @@ -142,18 +139,13 @@ where
/// Wake device from sleep mode.
///
/// Note that this includes a 33ms delay.
pub fn wake_mlx90614<
E,
SclPin: OutputPin<Error = E>,
SdaPin: OutputPin<Error = E>,
D: DelayMs<u8>,
>(
pub fn wake_mlx90614<E, SclPin: OutputPin<Error = E>, SdaPin: OutputPin<Error = E>, D: DelayNs>(
scl: &mut SclPin,
sda: &mut SdaPin,
delay: &mut D,
) -> Result<(), E> {
scl.set_high()?;
sda.set_low()?;
delay.delay_ms(mlx90614::WAKE_DELAY_MS);
delay.delay_ms(mlx90614::WAKE_DELAY_MS as u32);
sda.set_high()
}
15 changes: 6 additions & 9 deletions src/mlx90615.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@ use crate::{
Error, Mlx9061x, SlaveAddr,
};
use core::marker::PhantomData;
use embedded_hal::{
blocking::{delay::DelayMs, i2c},
digital::v2::OutputPin,
};
use embedded_hal::{delay::DelayNs, digital::OutputPin, i2c::I2c};

impl<E, I2C> Mlx9061x<I2C, ic::Mlx90615>
where
I2C: i2c::WriteRead<Error = E> + i2c::Write<Error = E>,
I2C: I2c<Error = E>,
{
/// Create new instance of the MLX90615 device.
///
Expand Down Expand Up @@ -39,7 +36,7 @@ where

impl<E, I2C> Mlx9061x<I2C, ic::Mlx90615>
where
I2C: i2c::WriteRead<Error = E> + i2c::Write<Error = E>,
I2C: I2c<Error = E>,
{
/// Read the ambient temperature in celsius degrees
pub fn ambient_temperature(&mut self) -> Result<f32, Error<E>> {
Expand Down Expand Up @@ -89,7 +86,7 @@ where
/// Set emissivity epsilon [0.0-1.0]
///
/// Wrong values will return `Error::InvalidInputData`.
pub fn set_emissivity<D: DelayMs<u8>>(
pub fn set_emissivity<D: DelayNs>(
&mut self,
epsilon: f32,
delay: &mut D,
Expand All @@ -112,11 +109,11 @@ where
/// Wake device from sleep mode.
///
/// Note that this includes a 39ms delay.
pub fn wake_mlx90615<E, P: OutputPin<Error = E>, D: DelayMs<u8>>(
pub fn wake_mlx90615<E, P: OutputPin<Error = E>, D: DelayNs>(
scl: &mut P,
delay: &mut D,
) -> Result<(), E> {
scl.set_low()?;
delay.delay_ms(mlx90615::WAKE_DELAY_MS);
delay.delay_ms(mlx90615::WAKE_DELAY_MS as u32);
scl.set_high()
}
10 changes: 5 additions & 5 deletions src/register_access.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{Error, Mlx9061x, SlaveAddr};
use embedded_hal::blocking::{delay, i2c};
use embedded_hal::{delay::DelayNs, i2c::I2c};
use smbus_pec::pec;

pub mod mlx90614 {
Expand Down Expand Up @@ -39,7 +39,7 @@ pub mod mlx90615 {

impl<E, I2C, IC> Mlx9061x<I2C, IC>
where
I2C: i2c::WriteRead<Error = E> + i2c::Write<Error = E>,
I2C: I2c<Error = E>,
{
pub(crate) fn read_u16(&mut self, register: u8) -> Result<u16, Error<E>> {
let mut data = [0; 3];
Expand Down Expand Up @@ -76,14 +76,14 @@ where
.map_err(Error::I2C)
}

pub(crate) fn write_u16_eeprom<D: delay::DelayMs<u8>>(
pub(crate) fn write_u16_eeprom<D: DelayNs>(
&mut self,
command: u8,
data: u16,
delay: &mut D,
) -> Result<(), Error<E>> {
self.write_u16(command, 0)?;
delay.delay_ms(self.eeprom_write_delay_ms);
delay.delay_ms(self.eeprom_write_delay_ms as u32);
self.write_u16(command, data)
}

Expand All @@ -98,7 +98,7 @@ where
pub(crate) fn get_address(address: SlaveAddr, default: u8) -> Result<u8, Error<E>> {
match address {
SlaveAddr::Default => Ok(default),
SlaveAddr::Alternative(a) if a == 0 => Err(Error::InvalidInputData),
SlaveAddr::Alternative(0) => Err(Error::InvalidInputData),
SlaveAddr::Alternative(a) if a > 127 => Err(Error::InvalidInputData),
SlaveAddr::Alternative(a) => Ok(a),
}
Expand Down
Loading

0 comments on commit 596c5ad

Please sign in to comment.