RustとRP2040マイコンでディスプレイに「Hello World」を出力してみた(SSD1306 )(組み込み開発)
はじめに
Rustの組み込み開発で、デファクトスタンダードになりつつあるディスプレイ制御クレートであるEmbedded Graphicsを利用して、お手頃な価格で手に入るSSD1306ディスプレイ、そして手軽にRust組み込み開発ができる開発ボードのBaker link. Devでディスプレイ出力をしてみました。
使用するハードウェア
-
SSD1306ディスプレイ
https://www.amazon.co.jp/dp/B07FNFYZRV?ref=ppx_yo2ov_dt_b_fed_asin_title -
Baker link. dev(Rev.1)
https://www.switch-science.com/products/10044?pr_prod_strat=e5_desc&pr_rec_id=a6e73e66d&pr_rec_pid=8373209497798&pr_ref_pid=8328468431046&pr_seq=uniform
Embedded Graphicsとは?
Embedded Graphicsは、組み込みシステム向けのグラフィックスライブラリです。これを使うと、ディスプレイにテキストや図形を描画することができます。Rustの安全性と効率性を活かしつつ、組み込みシステムでのグラフィックス処理を簡単に行えます。また、RAMを使用せずに描画する仕様になっており、組み込み開発に配慮された作りになっております。
プロジェクトを作成
-
Baker link. Envを起動し、プロジェクト名を入力、createをクリック、プロジェクト保存先のフォルダを選択してください。
-
Visual Studio Code起動後は、左下のコンテナで再度開くをクリックしてください。しばらくすると、Dockerの環境がビルドされ、環境構築が完了します!
コーディング(コードを書く)
- 以下の設定を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"
- 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);
}
}
ハードウェアの準備
- 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
-
配線とコーディングが終わったら、Baker link. EnvのRunをクリックしてください。するとバックグラウンドで、probe-rsのDAP Serverが起動します。
-
Visual Studio CodeでF5キーを押してください。すると、以下のようなアイコンが表示されます。
-
もう一度、F5キーを押すと、プログラムが動作します。
するとディスプレイに「Hello World」が表示されます!
最後に
以上の手順で、Rustでディスプレイ出力することができました。Embedded Graphicsは他のタイプのディスプレイを接続することが可能なので、ぜひ他のディスプレイでも試してみてください!
今回のプログラム
Discussion