Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shared I2C bus example #385

Closed
timoklingenhoefer opened this issue Feb 29, 2024 · 2 comments
Closed

Shared I2C bus example #385

timoklingenhoefer opened this issue Feb 29, 2024 · 2 comments

Comments

@timoklingenhoefer
Copy link

I am fairly new to embedded rust, and I have been struggling to get more than 1 I2C device working on a bus.

The problem is that any sensor owns the I2cDriver so that it can only be used once. The RefCellDevice from embedded_hal_bus is supposed to be the solution for this, but I can`t get it to compile without trait constraint errors.

Can somebody provide an example as to how to get multiple I2C devices to work on a single bus?

Here is what I tried (abbreviated from my original code):

use std::cell::RefCell;
use esp_idf_hal::{delay, i2c, prelude::Peripherals};
use esp_idf_sys::EspError;

use bme280::i2c::BME280;
use mlx9061x::{Mlx9061x, SlaveAddr};

use embedded_hal_bus::i2c as i2c_bus;

fn main() -> Result<(), EspError> {
    esp_idf_sys::link_patches();

    let mut peripherals = Peripherals::take().unwrap();

    let scl1 = peripherals.pins.gpio15;
    let sda1 = peripherals.pins.gpio2;
    let i2c0 = i2c::I2cDriver::new(
        peripherals.i2c0,
        sda1,
        scl1,
        &i2c::config::Config::new().baudrate(100.kHz().into())
    )?;


    let i2c_ref_cell = RefCell::new(i2c0);

    let mut bme280 = BME280::new_primary(i2c_bus::RefCellDevice::new(&i2c_ref_cell));
    bme280.init(&mut delay::Ets).unwrap();

    let addr = SlaveAddr::default();
    let mut mlx90614 = Mlx9061x::new_mlx90614(i2c_bus::RefCellDevice::new(&i2c_ref_cell), addr, 5).unwrap();

    let amb_temp = bme280.measure(&mut delay::Ets).unwrap();
    let obj_temp = mlx90614.object1_temperature().unwrap();
}

This fails to compile with

error[E0277]: the trait bound `embedded_hal_bus::i2c::RefCellDevice<'_, I2cDriver<'_>>: embedded_hal::blocking::i2c::WriteRead` is not satisfied

at Mlx9061x::new_mlx90614(....)

My dependecies are:

esp-idf-hal = "0.43.0"
esp-idf-sys = "0.34.0"
bme280 = "0.5.0"
mlx9061x = "0.2.1"
embedded-hal-bus = "0.1.0"
embedded-hal = "1.0.0"
@Vollbrecht
Copy link
Collaborator

Vollbrecht commented Feb 29, 2024

The problem is your mlx9061x driver crate you are using. You are currently using the embedded-hal-bus version that is using embedded-hal v1.0.0. The bme280 crate is also using embedded-hal v1.0 but the mix9061 crate still uses embedded-hal 0.2 and thats why you got that conflict. While in esp-idf-hal we supports both e-hal 0.2 and e-hal 1.0, on any instance you need to use either one or the othere in your drivers that share a bus. You cant mix them on one embedded-hal-bus implementation.

@Vollbrecht
Copy link
Collaborator

Closing as advice was given. For deeper information the embedded-hal repository also offers some information. We fully support embedded-hal but its concrete usage is not specific to esp-idf-hal

@github-project-automation github-project-automation bot moved this from Todo to Done in esp-rs Jun 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

2 participants