rust-embedded-community / ssd1306

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

Unable to draw circles & lines using embedded graphics crate #188

Open duart38 opened 1 year ago

duart38 commented 1 year ago

Description of the problem/feature request/other

I've been having issues drawing a circle using the embedded graphics crate. This issue is not only limited to the drawing of circles, it also appears when attempting to draw a line. Drawing a rectangle from the same crate works fine.

It would seem like some parts of the code are never reached after calling unwrap (see comments in test case below). I've also tried the same code using the web simulator and that works fine. Drawing pixels individually using the set_pixel also works fine.

I apologise in advanced if this issue is not related to this crate.

Test case (if applicable)

fn main() -> ! {
    let dp = arduino_hal::Peripherals::take().unwrap();
    let pins = arduino_hal::pins!(dp);
    let mut serial = arduino_hal::default_serial!(dp, pins, 57600);

    let i2c = arduino_hal::I2c::new(
        dp.TWI,
        pins.a4.into_pull_up_input(),
        pins.a5.into_pull_up_input(),
        50000,
    );

    let interface = I2CDisplayInterface::new(i2c);
    let mut display = 
        Ssd1306::new(
            interface,
            DisplaySize128x64,
            DisplayRotation::Rotate0
        )
        .into_buffered_graphics_mode();
    display.init().unwrap();
    arduino_hal::delay_ms(1000);

    let line_style = PrimitiveStyleBuilder::new().stroke_width(1).stroke_color(BinaryColor::On).build();

    display.clear(BinaryColor::Off).unwrap();

    Rectangle::new(Point::new(0, 0), Size::new(10, 10))
        .into_styled(line_style)
        .draw(&mut display)
        .unwrap();
    display.flush().unwrap();
    ufmt::uwriteln!(&mut serial, "done with rect\r").void_unwrap(); // this is reached

    Circle::new(Point::new(30, 30), 10)
        .into_styled(line_style)
        .draw(&mut display)
        .unwrap(); // stuck here?
    ufmt::uwriteln!(&mut serial, "done with circle\r").void_unwrap(); // this is never reached

    display.flush().unwrap(); // this is never reached
    ufmt::uwriteln!(&mut serial, "done with flush\r").void_unwrap(); // this is never reached
    loop { }
}

I've also tried matching against an error case for the circle but it does not seem to respond:

    let circ = Circle::new(Point::new(30, 30), 10)
        .into_styled(line_style)
        .draw(&mut display);

    match circ { // this is never reached
        Ok(_) => ufmt::uwriteln!(&mut serial, "circle ok\r").void_unwrap(),
        Err(_) => ufmt::uwriteln!(&mut serial, "circle err\r").void_unwrap(),
    }

The final thing I tried (as a desperate measure) was to create the circle, get the points, loop over every point and set the pixel to the "on" position. This does seem to loop over all the points but it gets stuck when attempting to flush the display (see below):

    Circle::with_center(Point::new(30, 30), 10)
        .points()
        .for_each(|p| {
            ufmt::uwriteln!(&mut serial, "circ point {} {}\r", p.x, p.y).void_unwrap(); // this prints just fine
            display.set_pixel(p.x.try_into().unwrap(), p.y.try_into().unwrap(), true)
        });
    ufmt::uwriteln!(&mut serial, "done with circle\r").void_unwrap(); // this now reached

    display.flush().unwrap(); // now it gets stuck here
    ufmt::uwriteln!(&mut serial, "done with flush\r").void_unwrap(); // this is never reached

For good measure, here's the dependencies of my cargo.toml

[dependencies]
panic-halt = "0.2.0"
ufmt = "0.1.0"
nb = "0.1.2"
embedded-hal = "0.2.5"
embedded-graphics = "0.8.0"
embedded-layout = "0.3.1"
ssd1306 = { git = "https://github.com/jamwaffles/ssd1306.git", branch = "master" }
embedded-storage = "0.2"
display-interface = "0.4.1"