🍞

RustとRP2040マイコンでディスプレイに「Hello World」を出力してみた(SSD1306 )(組み込み開発)

2024/12/14に公開

はじめに

Rustの組み込み開発で、デファクトスタンダードになりつつあるディスプレイ制御クレートであるEmbedded Graphicsを利用して、お手頃な価格で手に入るSSD1306ディスプレイ、そして手軽にRust組み込み開発ができる開発ボードのBaker link. Devでディスプレイ出力をしてみました。

使用するハードウェア

Embedded Graphicsとは?

Embedded Graphicsは、組み込みシステム向けのグラフィックスライブラリです。これを使うと、ディスプレイにテキストや図形を描画することができます。Rustの安全性と効率性を活かしつつ、組み込みシステムでのグラフィックス処理を簡単に行えます。また、RAMを使用せずに描画する仕様になっており、組み込み開発に配慮された作りになっております。

https://github.com/embedded-graphics/embedded-graphics

プロジェクトを作成

  1. Baker link. Envを起動し、プロジェクト名を入力、createをクリック、プロジェクト保存先のフォルダを選択してください。

  2. Visual Studio Code起動後は、左下のコンテナで再度開くをクリックしてください。しばらくすると、Dockerの環境がビルドされ、環境構築が完了します!

コーディング(コードを書く)

  1. 以下の設定をCargo.tomlに追記し、embedded-graphicsを含め必要なクレートを追加します。
[dependencies]
# プロジェクト生成のデフォルトのクレート
cortex-m = "0.7"
cortex-m-rt = "0.7"
embedded-hal = { version = "1.0.0" }
defmt = "0.3"
defmt-rtt = "0.4"
panic-probe = { version = "0.3", features = ["print-defmt"] }
rp2040-hal = { version = "0.10", features = ["rt", "critical-section-impl"] }
rp2040-boot2 = "0.3"
critical-section = "1.0.0"

# 追加クレート
embedded-graphics = "0.8.1"
ssd1306 = "0.9.0"
fugit = "0.3.7"
  1. src/main.rsを次のコードに書き換えてください。
    これは、ディスプレイに「Hello World!」と表示する簡単なプログラムです。
#![no_std]
#![no_main]

use defmt_rtt as _;
use embedded_graphics::{
    mono_font::{ascii::FONT_7X13, MonoTextStyleBuilder},
    pixelcolor::BinaryColor,
    prelude::*,
    primitives::{PrimitiveStyle, Rectangle},
    text::{Baseline, Text},
};
use embedded_hal::delay::DelayNs;
use hal::fugit::RateExtU32;
use hal::pac;
use panic_probe as _;
use rp2040_hal as hal;
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};

#[link_section = ".boot2"]
#[used]
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_GENERIC_03H;

const XTAL_FREQ_HZ: u32 = 12_000_000u32;

#[rp2040_hal::entry]
fn main() -> ! {
    let mut pac = pac::Peripherals::take().unwrap();

    let mut watchdog = hal::Watchdog::new(pac.WATCHDOG);

    let clocks = hal::clocks::init_clocks_and_plls(
        XTAL_FREQ_HZ,
        pac.XOSC,
        pac.CLOCKS,
        pac.PLL_SYS,
        pac.PLL_USB,
        &mut pac.RESETS,
        &mut watchdog,
    )
    .ok()
    .unwrap();

    let mut timer = rp2040_hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks);

    let sio = hal::Sio::new(pac.SIO);

    let pins = hal::gpio::Pins::new(
        pac.IO_BANK0,
        pac.PADS_BANK0,
        sio.gpio_bank0,
        &mut pac.RESETS,
    );

    let sda_pin = pins.gpio14.reconfigure();
    // SCLピンを再構成
    let scl_pin = pins.gpio15.reconfigure();

    // I2Cインターフェースを初期化
    let i2c = hal::I2C::i2c1(
        pac.I2C1,
        sda_pin,
        scl_pin,
        400.kHz(),
        &mut pac.RESETS,
        &clocks.system_clock,
    );

    // I2Cディスプレイインターフェースを作成
    let interface = I2CDisplayInterface::new(i2c);

    // SSD1306ディスプレイを初期化
    let mut display = Ssd1306::new(interface, DisplaySize128x32, DisplayRotation::Rotate0)
        .into_buffered_graphics_mode();
    display.init().unwrap();

    // テキストスタイルを設定
    let text_sytle = MonoTextStyleBuilder::new()
        .font(&FONT_7X13)
        .text_color(BinaryColor::On)
        .build();

    // 表示するテキストを設定
    let text_line1 = Text::with_baseline("Hello World.", Point::zero(), text_sytle, Baseline::Top);

    // 画面クリア用の矩形を設定
    let clear = Rectangle::new(Point::zero(), Size::new(128, 64))
        .into_styled(PrimitiveStyle::with_fill(BinaryColor::Off));

    // メインループ
    loop {
        // テキストを描画
        text_line1.draw(&mut display).unwrap();
        display.flush().unwrap();
        timer.delay_ms(1500u32);

        // 画面をクリア
        clear.draw(&mut display).unwrap();
        display.flush().unwrap();
        timer.delay_ms(1500u32);
    }
}

ハードウェアの準備

  1. Baker link. DevとSSD1306ディスプレイを接続します。
    Baker link. Dev(Rev.1)のピンアサインは、次の通りです。

今回は、GP14、GP15のI2C1を使います。配線は、次の表のとおりです。

Baker link. Dev 接続 SSD1306ディスプレイ
VBUS(40Pin) --- VCC
GND(38Pin) --- GND
GP14(SDA 19Pin) --- SDA
GP15(SCL 20Pin) --- SCL

プログラムをRUN

  1. 配線とコーディングが終わったら、Baker link. EnvのRunをクリックしてください。するとバックグラウンドで、probe-rsのDAP Serverが起動します。

  2. Visual Studio CodeでF5キーを押してください。すると、以下のようなアイコンが表示されます。

  3. もう一度、F5キーを押すと、プログラムが動作します。

するとディスプレイに「Hello World」が表示されます!

最後に

以上の手順で、Rustでディスプレイ出力することができました。Embedded Graphicsは他のタイプのディスプレイを接続することが可能なので、ぜひ他のディスプレイでも試してみてください!

今回のプログラム

https://github.com/Baker-Tanaka/baker_link_dev_ssd1306

Discussion