I am trying to use multiple sensors on an I2C bus with a pca9548a multiplex. I cannot get the code to compile because of unsatisfied trait bounds. Likely I am not using the proper trait, but I have had no luck with anything. Below is a stripped down example using crate hdc20xx with xca9548a. (I can compile an example using hdc20xx without multiplexing.)
I have the same problem with xca9548a and other sensor crates. I did have xca9548a working with aht10 several months ago, but it seems to have been broken by recent changes in something. Suggestions would be appreciated.
Click to expand compile errors
```
$ cargo build --no-default-features --target thumbv7em-none-eabihf --features stm32f401,stm32f4xx --example test_xca9548a_hdc2080
Compiling testing-example v0.0.1 (~/test_xca9548a_hdc2080)
warning: unused import: `mode::OneShot`
--> examples/test_xca9548a_hdc2080.rs:17:51
|
17 | use hdc20xx::{Hdc20xx, SlaveAddr as HdcSlaveAddr, mode::OneShot};
| ^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: unused imports: `Error as XcaError`, `Error::I2C`, and `I2cSlave`
--> examples/test_xca9548a_hdc2080.rs:18:16
|
18 | ...::{Error::I2C, Error as XcaError, SlaveAddr as XcaSlaveAddr, Xca9548a, I2cSlave};
| ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^
warning: unused import: `core::fmt::Write`
--> examples/test_xca9548a_hdc2080.rs:20:5
|
20 | use core::fmt::Write;
| ^^^^^^^^^^^^^^^^
warning: unused import: `ErrorType`
--> examples/test_xca9548a_hdc2080.rs:24:30
|
24 | use embedded_hal::i2c::{I2c, ErrorType}; //I2c is a trait
| ^^^^^^^^^
error[E0599]: the method `read` exists for struct `Hdc20xx>, I2c>, OneShot>`, but its trait bounds were not satisfied
--> examples/test_xca9548a_hdc2080.rs:93:35
|
93 | let data = block!(sensors1.read()).unwrap(); // does this need block?
| ^^^^ method cannot be called due to unsatisfied trait bounds
|
::: /home/paul/.cargo/git/checkouts/xca9548a-rs-ae9747938cfab30c/3badbc9/src/parts.rs:6:1
|
6 | pub struct I2cSlave<'a, DEV: 'a, I2C>(&'a DEV, u8, PhantomData);
| ------------------------------------- doesn't satisfy `_: _embedded_hal_blocking_i2c_WriteRead` or `_: _embedded_hal_blocking_i2c_Write`
|
= note: the full type name has been written to '~/test_xca9548a_hdc2080/target/thumbv7em-none-eabihf/debug/examples/test_xca9548a_hdc2080-97c138698bf6f627.long-type-2705192295802430818.txt'
= note: consider using `--verbose` to print the full type name to the console
= note: the following trait bounds were not satisfied:
`I2cSlave<'_, Xca9548a>, stm32f4xx_hal::i2c::I2c>: WriteRead`
`I2cSlave<'_, Xca9548a>, stm32f4xx_hal::i2c::I2c>: _embedded_hal_blocking_i2c_Write`
warning: unused import: `I2c`
--> examples/test_xca9548a_hdc2080.rs:24:25
|
24 | use embedded_hal::i2c::{I2c, ErrorType}; //I2c is a trait
| ^^^
warning: unused import: `embedded_hal::delay::DelayNs`
--> examples/test_xca9548a_hdc2080.rs:26:5
|
26 | use embedded_hal::delay::DelayNs;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0599`.
warning: `testing-example` (example "test_xca9548a_hdc2080") generated 6 warnings
error: could not compile `testing-example` (example "test_xca9548a_hdc2080") due to 1 previous error; 6 warnings emitted
```
Click to expand code
```
//! Continuously read temperature from hdc2080s multiplexed on i2c1 using xca9548a.
#![deny(unsafe_code)]
#![no_std]
#![no_main]
#[cfg(debug_assertions)]
use panic_semihosting as _;
#[cfg(not(debug_assertions))]
use panic_halt as _;
use cortex_m_semihosting::hprintln;
use cortex_m_rt::entry;
use nb::block;
use hdc20xx::{Hdc20xx, SlaveAddr as HdcSlaveAddr, mode::OneShot};
use xca9548a::{Error::I2C, Error as XcaError, SlaveAddr as XcaSlaveAddr, Xca9548a, I2cSlave};
use core::fmt::Write;
//use embedded_io::{Read, Write, WriteRead};
//use embedded_hal_async::i2c::{I2c, ErrorType}; //I2c is a trait
use embedded_hal::i2c::{I2c, ErrorType}; //I2c is a trait
use embedded_hal::delay::DelayNs;
use stm32f4xx_hal::{
rcc::{RccExt},
timer::{TimerExt},
pac::{Peripherals, },
gpio::{GpioExt, },
i2c::I2c as I2cType,
prelude::*,
};
///////////////////////////////////////////////////////////////
#[entry]
fn main() -> ! {
let dp = Peripherals::take().unwrap();
let rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.freeze();
let gpiob = dp.GPIOB.split();
let scl = gpiob.pb8.into_alternate_open_drain();
let sda = gpiob.pb9.into_alternate_open_drain();
let i2c1 = I2cType::new(dp.I2C1, (scl, sda), 400.kHz(), &clocks);
let delay = dp.TIM5.delay(&clocks);
let mut switch1 = Xca9548a::new(i2c1, XcaSlaveAddr::default());
let slave_address = 0b010_0000; // example slave address
let write_data = [0b0101_0101, 0b1010_1010]; // some data to be sent
let switch1parts = switch1.split();
let parts = [switch1parts.i2c0, switch1parts.i2c1, switch1parts.i2c2, switch1parts.i2c3,
switch1parts.i2c4, switch1parts.i2c5, switch1parts.i2c6, switch1parts.i2c7];
let mut sensors1 = Hdc20xx::new(parts[0], HdcSlaveAddr::default());
let mut sensors2 = Hdc20xx::new(parts[1], HdcSlaveAddr::default());
hprintln!("entering loop").unwrap();
loop {
let data = block!(sensors1.read()).unwrap(); // does this need block?
hprintln!("Temperature: {:.2}ºC ", data.temperature).unwrap();
hprintln!("Humidity: {:.2}% ", data.humidity.unwrap()).unwrap();
delay.delay_ms(5000);
}
}
```
Click to expand Cargo.toml
```
# build:
# cargo build --no-default-features --target thumbv7em-none-eabihf --features stm32f401,stm32f4xx --example test_xca9548a_hdc2080
[package]
authors = ["Paul Gilbert"]
categories = ["embedded", "no-std"]
description = "testing of example"
keywords = ["driver", "i2c", "example"]
license = "MIT OR Apache-2.0"
name = "testing-example"
version = "0.0.1"
edition = "2021"
[dependencies]
stm32f4xx-hal = { git = "https://github.com/stm32-rs/stm32f4xx-hal", optional = true }
#stm32f4xx-hal = { version = ">=0.20.0", optional = true }
hdc20xx = { git = "https://github.com/eldruin/hdc20xx-rs" }
xca9548a = { git = "https://github.com/eldruin/xca9548a-rs"}
#xca9548a = ">=1.0.0"
#embedded-hal = "1.0"
embedded-hal = { git = "https://github.com/rust-embedded/embedded-hal/" }
nb = ">=1.1.0"
cortex-m = ">=0.7"
cortex-m-rt = ">=0.7.0"
cortex-m-semihosting = { version = "0.3.7" }
panic-semihosting = { version = ">=0.5.2" }
panic-halt = { version = ">=0.2.0" }
[features]
stm32f4xx = ["stm32f4xx-hal", ]
stm32f401 = ["stm32f4xx-hal/stm32f401" ]
stm32f411 = ["stm32f4xx-hal/stm32f411" ]
```
I am trying to use multiple sensors on an I2C bus with a pca9548a multiplex. I cannot get the code to compile because of
unsatisfied trait bounds
. Likely I am not using the proper trait, but I have had no luck with anything. Below is a stripped down example using cratehdc20xx
withxca9548a
. (I can compile an example usinghdc20xx
without multiplexing.)I have the same problem with
xca9548a
and other sensor crates. I did havexca9548a
working withaht10
several months ago, but it seems to have been broken by recent changes in something. Suggestions would be appreciated.Click to expand compile errors
``` $ cargo build --no-default-features --target thumbv7em-none-eabihf --features stm32f401,stm32f4xx --example test_xca9548a_hdc2080 Compiling testing-example v0.0.1 (~/test_xca9548a_hdc2080) warning: unused import: `mode::OneShot` --> examples/test_xca9548a_hdc2080.rs:17:51 | 17 | use hdc20xx::{Hdc20xx, SlaveAddr as HdcSlaveAddr, mode::OneShot}; | ^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default warning: unused imports: `Error as XcaError`, `Error::I2C`, and `I2cSlave` --> examples/test_xca9548a_hdc2080.rs:18:16 | 18 | ...::{Error::I2C, Error as XcaError, SlaveAddr as XcaSlaveAddr, Xca9548a, I2cSlave}; | ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^ warning: unused import: `core::fmt::Write` --> examples/test_xca9548a_hdc2080.rs:20:5 | 20 | use core::fmt::Write; | ^^^^^^^^^^^^^^^^ warning: unused import: `ErrorType` --> examples/test_xca9548a_hdc2080.rs:24:30 | 24 | use embedded_hal::i2c::{I2c, ErrorType}; //I2c is a trait | ^^^^^^^^^ error[E0599]: the method `read` exists for struct `Hdc20xxClick to expand code
``` //! Continuously read temperature from hdc2080s multiplexed on i2c1 using xca9548a. #![deny(unsafe_code)] #![no_std] #![no_main] #[cfg(debug_assertions)] use panic_semihosting as _; #[cfg(not(debug_assertions))] use panic_halt as _; use cortex_m_semihosting::hprintln; use cortex_m_rt::entry; use nb::block; use hdc20xx::{Hdc20xx, SlaveAddr as HdcSlaveAddr, mode::OneShot}; use xca9548a::{Error::I2C, Error as XcaError, SlaveAddr as XcaSlaveAddr, Xca9548a, I2cSlave}; use core::fmt::Write; //use embedded_io::{Read, Write, WriteRead}; //use embedded_hal_async::i2c::{I2c, ErrorType}; //I2c is a trait use embedded_hal::i2c::{I2c, ErrorType}; //I2c is a trait use embedded_hal::delay::DelayNs; use stm32f4xx_hal::{ rcc::{RccExt}, timer::{TimerExt}, pac::{Peripherals, }, gpio::{GpioExt, }, i2c::I2c as I2cType, prelude::*, }; /////////////////////////////////////////////////////////////// #[entry] fn main() -> ! { let dp = Peripherals::take().unwrap(); let rcc = dp.RCC.constrain(); let clocks = rcc.cfgr.freeze(); let gpiob = dp.GPIOB.split(); let scl = gpiob.pb8.into_alternate_open_drain(); let sda = gpiob.pb9.into_alternate_open_drain(); let i2c1 = I2cType::new(dp.I2C1, (scl, sda), 400.kHz(), &clocks); let delay = dp.TIM5.delay(&clocks); let mut switch1 = Xca9548a::new(i2c1, XcaSlaveAddr::default()); let slave_address = 0b010_0000; // example slave address let write_data = [0b0101_0101, 0b1010_1010]; // some data to be sent let switch1parts = switch1.split(); let parts = [switch1parts.i2c0, switch1parts.i2c1, switch1parts.i2c2, switch1parts.i2c3, switch1parts.i2c4, switch1parts.i2c5, switch1parts.i2c6, switch1parts.i2c7]; let mut sensors1 = Hdc20xx::new(parts[0], HdcSlaveAddr::default()); let mut sensors2 = Hdc20xx::new(parts[1], HdcSlaveAddr::default()); hprintln!("entering loop").unwrap(); loop { let data = block!(sensors1.read()).unwrap(); // does this need block? hprintln!("Temperature: {:.2}ºC ", data.temperature).unwrap(); hprintln!("Humidity: {:.2}% ", data.humidity.unwrap()).unwrap(); delay.delay_ms(5000); } } ```Click to expand Cargo.toml
``` # build: # cargo build --no-default-features --target thumbv7em-none-eabihf --features stm32f401,stm32f4xx --example test_xca9548a_hdc2080 [package] authors = ["Paul Gilbert"] categories = ["embedded", "no-std"] description = "testing of example" keywords = ["driver", "i2c", "example"] license = "MIT OR Apache-2.0" name = "testing-example" version = "0.0.1" edition = "2021" [dependencies] stm32f4xx-hal = { git = "https://github.com/stm32-rs/stm32f4xx-hal", optional = true } #stm32f4xx-hal = { version = ">=0.20.0", optional = true } hdc20xx = { git = "https://github.com/eldruin/hdc20xx-rs" } xca9548a = { git = "https://github.com/eldruin/xca9548a-rs"} #xca9548a = ">=1.0.0" #embedded-hal = "1.0" embedded-hal = { git = "https://github.com/rust-embedded/embedded-hal/" } nb = ">=1.1.0" cortex-m = ">=0.7" cortex-m-rt = ">=0.7.0" cortex-m-semihosting = { version = "0.3.7" } panic-semihosting = { version = ">=0.5.2" } panic-halt = { version = ">=0.2.0" } [features] stm32f4xx = ["stm32f4xx-hal", ] stm32f401 = ["stm32f4xx-hal/stm32f401" ] stm32f411 = ["stm32f4xx-hal/stm32f411" ] ```