rust-embedded-community / ssd1306

SSD1306 OLED driver
Apache License 2.0
282 stars 69 forks source link

trait `DrawTarget` is not implemented for ... / esp_idf_hal::i2c::* #200

Open MikeMitterer opened 8 months ago

MikeMitterer commented 8 months ago

Description of the problem/feature request/other

I'm fairly new to Rust! For my experiments, I use a ESP32 DevKit with esp_idf_hal, and it's I2cDriver. I try to stay with esp_idf_hal because of its widly used and tests SW-Stack. However, if I compile the code below I get the following error message.

F... I have no idea how to implement DrawTarget for `esp_idf_hal::i2c::I2cDriver`` Do I miss something or is it really necessary to implement the DrawTarget?

error[E0277]: the trait bound `Ssd1306<I2CInterface<esp_idf_hal::i2c::I2cDriver<'_>>, ssd1306::prelude::DisplaySize128x64, BufferedGraphicsMode<ssd1306::prelude::DisplaySize128x64>>: DrawTarget` is not satisfied
   --> src/main.rs:61:15
    |
61  |         .draw(&mut display)
    |          ---- ^^^^^^^^^^^^ the trait `DrawTarget` is not implemented for `Ssd1306<I2CInterface<esp_idf_hal::i2c::I2cDriver<'_>>, ssd1306::prelude::DisplaySize128x64, BufferedGraphicsMode<ssd1306::prelude::DisplaySize128x64>>`
    |          |
    |          required by a bound introduced by this call
    |
    = help: the following other types implement trait `DrawTarget`:
              mono_font::draw_target::MonoFontDrawTarget<'_, T, mono_font::draw_target::Foreground<<T as DrawTarget>::Color>>
              mono_font::draw_target::MonoFontDrawTarget<'_, T, mono_font::draw_target::Background<<T as DrawTarget>::Color>>
              mono_font::draw_target::MonoFontDrawTarget<'_, T, mono_font::draw_target::Both<<T as DrawTarget>::Color>>
              Clipped<'_, T>
              ColorConverted<'_, T, C>
              Cropped<'_, T>
              embedded_graphics::draw_target::Translated<'_, T>
              Framebuffer<C, RawU1, BO, WIDTH, HEIGHT, N>
            and 10 others
note: required by a bound in `embedded_graphics::Drawable::draw`
   --> /Users/mikemitterer/.cargo/registry/src/index.crates.io-6f17d22bba15001f/embedded-graphics-core-0.4.0/src/drawable.rs:106:12
    |
104 |     fn draw<D>(&self, target: &mut D) -> Result<Self::Output, D::Error>
    |        ---- required by a bound in this associated function
105 |     where
106 |         D: DrawTarget<Color = Self::Color>;
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Drawable::draw`

Test case

I also tried it with: (Similar error)

    let interface = I2CDisplayInterface::new(i2c);
    let mut display = Ssd1306::new(
        interface, DisplaySize128x64, DisplayRotation::Rotate0
    ).into_terminal_mode();
use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported
use log::*;

use esp_idf_hal::delay::{FreeRtos, BLOCK};
use esp_idf_hal::gpio::*;
use esp_idf_hal::i2c::*;
use esp_idf_hal::peripherals::Peripherals;
use esp_idf_hal::prelude::*;
use ssd1306::{mode::BufferedGraphicsMode, prelude::*, I2CDisplayInterface, Ssd1306};
use embedded_graphics::{
    mono_font::{ascii::FONT_6X10, MonoTextStyleBuilder},
    pixelcolor::BinaryColor,
    prelude::*,
    text::{Baseline, Text},
};

const SSD1306_ADDRESS: u8 = 0x3c;

fn main()-> anyhow::Result<()> {
    // It is necessary to call this function once. Otherwise some patches to the runtime
    // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
    esp_idf_sys::link_patches();

    // Bind the log crate to the ESP Logging facilities
    esp_idf_svc::log::EspLogger::initialize_default();

    info!("Hello, world - 3!");

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

    let i2c = peripherals.i2c0;
    let sda = peripherals.pins.gpio21;
    let scl = peripherals.pins.gpio22;

    let config = I2cConfig::new().baudrate(100.kHz().into());
    let mut i2c = I2cDriver::new(i2c, sda, scl, &config)?;

    let interface = I2CDisplayInterface::new(i2c);
    let mut display = Ssd1306::new(
        interface,
        DisplaySize128x64,
        DisplayRotation::Rotate0,
    ).into_buffered_graphics_mode();

    display.init().unwrap();
    // let _ = display.clear();

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

    let mut led = PinDriver::output(peripherals.pins.gpio14)?;

    // Pins 35,34,39,26
    let button = PinDriver::input(peripherals.pins.gpio35)?;

    led.set_low()?;

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

    loop {
        if button.is_high() {
            led.set_high()?;
        } else {
            led.set_low()?;
        }

        // we are sleeping here to make sure the watchdog isn't triggered
        FreeRtos::delay_ms(10);
    }
}