Example code for Oled I2C display gives errors on esp_hal

Hi everyone, I'm trying to develop on Rust on ESP32 microcontrollers, so far everything's all right and I'm liking the language very much. Yesterday I tried to use a crate to drive an I2C OLED display (128x64 pixels, SH1106 driver), I tried using the embedded_graphics (embedded_graphics - Rust) together with the sh1106 crate specific for my display. I tried using the sample code provide on the crate page with the esp_hal i2c implementation, here is the code:

//! I2C Display example
//!
//! This example prints some text on an SSD1306-based
//! display (via I2C)
//!
//! The following wiring is assumed:
//! - SDA => GPIO4
//! - SCL => GPIO5

//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: embedded-hal-02

#![no_std]
#![no_main]

use embedded_graphics::{
    mono_font::{ascii::FONT_6X10, MonoTextStyleBuilder},
    pixelcolor::BinaryColor,
    prelude::*,
    text::{Baseline, Text},
};
use esp_backtrace as _;
use esp_hal::{
    clock::ClockControl, delay::Delay, gpio::Io, i2c::I2C, peripherals::Peripherals, prelude::*,
    system::SystemControl,
};
use esp_println::println;
use sh1106::{prelude::*, Builder};

#[entry]
fn main() -> ! {
    let peripherals = Peripherals::take();
    let system = SystemControl::new(peripherals.SYSTEM);
    let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
    let mut clocks = ClockControl::boot_defaults(system.clock_control).freeze();
    let mut delay = Delay::new(&clocks);
    let mut i2c = I2C::new(
        peripherals.I2C0,
        io.pins.gpio4,
        io.pins.gpio5,
        100.kHz(),
        &clocks,
        None,
    );
    let mut display: GraphicsMode<_> = Builder::new().connect_i2c(i2c).into();

    display.init().unwrap();
    display.flush().unwrap();

    let text_style = MonoTextStyleBuilder::new()
        .font(&FONT_6X10)
        .text_color(BinaryColor::On)
        .build();

    Text::with_baseline("Hello world!", Point::zero(), text_style, Baseline::Top)
        .draw(&mut display)
        .unwrap();

    Text::with_baseline("Hello Rust!", Point::new(0, 16), text_style, Baseline::Top)
        .draw(&mut display)
        .unwrap();

    display.flush().unwrap();

    loop {
        delay.delay_ms(1000 as u32);
    }
}

Using this code I get the following error in the line where I declare "display":

the trait bound I2C<'_, I2C0, Blocking>: embedded_hal::blocking::i2c::Write is not satisfied
the trait embedded_hal::blocking::i2c::Write is implemented for I2cStubrustcClick for full compiler diagnostic

main.rs(45, 55): required by a bound introduced by this call

builder.rs(119, 14): required by a bound in Builder::connect_i2c

Could you help me figure out what I'm doing wrong? Thank you!

OK, I tried to understand more of the problem and if I understood correctly the SH1106 crate uses a call to I2C: hal::blocking::i2c::Write<Error = CommE> that is valid in embedded_hal v0.2, while it is deprecated in v1.0. esp hal uses the 1.0 version of embedded_hal so I get that error. Is there a way to solve this problem? Should I modify the call within the crate to match the new version? Sorry for the inaccurate terms but I'm new to Rust so I'm still getting used to the new environment!

For the record I was suggested the solution by someone in another forum, you just have to turn on the "embedded-hal-02" feature flag on esp-hal.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.