esp32c3 运行 Rust(八)

426 阅读2分钟

esp32c3 运行 Rust(八)

上篇已经完成了 SSD1306 基本操作已经封装完成,将使用 embedded_graphics crate 在 SSD1306 上显示文字和图案。

环境

  • OS: Ubuntu 20.04.4 LTS

  • Rust: rustc 1.62.0-nightly

  • IDE: VsCode

  • ESP32C3: ESP-C3-13-Kit 开发板

    esp32c3.png

  • SSD1306: 0.96 寸 OLED 模块

    ssd1306

使用到的 GPIO

GPIOtitle
GPIO4SDA
GPIO5SCL

embedded_graphics

embedded_graphics 是一个嵌入式 2D 图形库,embedded_graphics 的核心目标是在不使用任何缓冲区的情况下绘制图形。该库无需动态内存分配器即可工作,并且无需预先分配大块内存。为了实现这一点,它采用了一种基于方法,其中像素颜色和位置是动态计算的,并且保存状态最小。这允许使用的应用程序使用更少的 RAM,而性能几乎不会受到影响。

创建项目

使用上篇创建的项目工程。

  1. ssd1306 实现 DrawTarget trait

    embedded_graphics crate 不包含驱动程序,因此需要为 ssd1306 实现 DrawTarget trait

    • 安装 embedded_graphics

      # ...
      [dependencies]
      # ...
      embedded-graphics = "0.7.1"
      
    • 实现 DrawTarget trait

      use embedded_graphics::{
          draw_target::DrawTarget,
          pixelcolor::BinaryColor,
          geometry::{Size, OriginDimensions, Dimensions},
          Pixel,
      };
      
      
      impl<Adapter, SIZE> OriginDimensions for SSD1306<Adapter, SIZE, FrameBuffer<SIZE>>
      where
          Adapter: I2CInterface,
          SIZE: DisplaySize
      {
          fn size(&self) -> Size {
              let (w, h) = self.dimensions();
              Size::new(w.into(), h.into())
          }
      }
      
      impl<Adapter, SIZE> DrawTarget for SSD1306<Adapter, SIZE, FrameBuffer<SIZE>>
      where
          Adapter: I2CInterface,
          SIZE: DisplaySize,
      {
          type Color = BinaryColor;
          type Error = SSD1306Error;
      
          fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
          where
              I: IntoIterator<Item = Pixel<Self::Color>>
          {
              let box_ = self.bounding_box();
              pixels
                  .into_iter()
                  .filter(|Pixel(pos, _color)| box_.contains(*pos))
                  .for_each(|Pixel(pos, color)| self.set_pixel(pos.x as u32, pos.y as u32, color.is_on()));
      
              Ok(())
          }
      }
      
  2. 显示文字

    • 引入相关依赖

      use embedded_graphics::{
          mono_font::{ascii::FONT_6X10, MonoTextStyle},
          pixelcolor::BinaryColor,
          prelude::*,
          text::Text,
      };
      
    • 定义字体

      let style = MonoTextStyle::new(&FONT_6X10, BinaryColor::On);
      
    • 绘制文字

      Text::new("Hello Rust!", Point::new(20, 30), style).draw(&mut display).unwrap();
      
    • 刷新屏幕

      display.flush().unwrap();
      
    • 编译并上传

      连接开发板,使用如下命令编译并上传

      cargo espflash --release --monitor /dev/ttyUSB0
      
  3. 绘制直线

    for i in 0..32 {
        Line::new(Point::new(0, i * 2), Point::new(128, i * 2))
            .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
            .draw(&mut display).unwrap();
        display.flush().unwrap();
        thread::sleep(Duration::from_millis(500));
    }
    
  4. 绘制矩形

    let rect_style = PrimitiveStyleBuilder::new().stroke_color(BinaryColor::On).stroke_width(1).fill_color(BinaryColor::Off).build();
    Rectangle::new(Point::new(0, 0), Size::new(128, 64))
        .into_styled(rect_style)
        .draw(&mut display).unwrap();
    display.flush().unwrap();
    

参考

  1. Embedded Rust on Espressif
  2. embedded-hal
  3. esp-idf-hal
  4. embedded_graphics