Hello, e-Paper ディスプレイ!
センサープロジェクトに e-Paper ディスプレイを追加する前に、まずは単体で試してみます。1_hello_extended.rs を基にした新しいファイルから始めてください。
配線
✅ 開発ボードからすべてのジャンパーワイヤーを取り外します。ただし、ブレッドボードはそのままにしておきます。
✅ ePaper ディスプレイの以下のワイヤーを、それぞれ対応するピンに接続します。
| 名前 | 色 | ピン |
|---|---|---|
| vcc | 赤 | vdd |
| gnd | 黒 | gnd |
| din | 青 | p1.01 |
| clk | 黄 | p1.02 |
| cs | オレンジ | p1.03 |
| dc | 緑 | p1.04 |
| rst | 白 | p1.05 |
| busy | 紫 | p1.06 |
コード
Cargo.toml
✅ 次の依存関係を cargo.toml に追加します。
#![allow(unused)]
fn main() {
epd-waveshare = "0.4.0"
embedded-graphics = "0.6.2"
}
SPIM のインスタンス化
✅ spim と p1 モジュールをスコープに取り込みます。
#![allow(unused)]
fn main() {
// ボード周辺機能へのアクセス:
use nrf52840_hal::{
self as hal,
gpio::{p0::Parts as P0Parts, p1::Parts as P1Parts, Level},
prelude::*,
spim::{self, Spim},
Timer,
};
}
✅ ピンを次のように設定します。
#![allow(unused)]
fn main() {
let din = pins_1.p1_01.into_push_pull_output(Level::Low).degrade();
let clk = pins_1.p1_02.into_push_pull_output(Level::Low).degrade();
let cs = pins_1.p1_03.into_push_pull_output(Level::Low);
let dc = pins_1.p1_04.into_push_pull_output(Level::Low);
let rst = pins_1.p1_05.into_push_pull_output(Level::Low);
let busy = pins_1.p1_06.into_floating_input();
}
din はデータライン、clk はクロックです。どちらもフローティングである必要があります。
cs は chip select の略で、dc は data/command control pin、rst は reset の略です。これらはすべて、初期レベルが Low のプッシュプル出力でなければなりません。
busy は入力として設定されます。これは、ディスプレイがビジーかどうかを通信できるチャネルです。
SPI プロトコルは、クロックを持つという点で I2C と似ていますが、周辺デバイスとの間で送受信されるデータには MISO と MOSI という 2 つの異なるチャネルを使用します。データはディスプレイに送信されるだけで、ディスプレイからは送信されないため、ここでは MOSI ラインのみを使用します。
✅ SPIM ピンを設定し、SPIM 周辺機能の新しいインスタンスを作成します。
#![allow(unused)]
fn main() {
let spi_pins = spim::Pins {
sck: clk,
miso: None,
mosi: Some(din),
};
let mut spi = Spim::new(board.SPIM3, spi_pins, spim::Frequency::K500, spim::MODE_0, 0);
}
✅ プログラムを実行して、ビルドできることを確認します。この時点では、ディスプレイは何もしないはずです。
ePaper ディスプレイのインスタンス化
✅ 次のモジュールをスコープに取り込みます。
#![allow(unused)]
fn main() {
use epd_waveshare::{
epd4in2::*,
graphics::Display,
prelude::*,
};
}
✅ タイマーのインスタンスを追加します。 ✅ 4.2 インチ E Paper ディスプレイの新しいインスタンスを作成します。 ✅ デフォルトのディスプレイを追加します。
#![allow(unused)]
fn main() {
// ePaper をインスタンス化
let mut delay = Timer::new(board.TIMER1);
let mut epd4in2 = EPD4in2::new(&mut spi, cs, busy, dc, rst, &mut delay).unwrap();
let mut display = Display4in2::default();
}
✅ プログラムを実行して、ビルドできることを確認します。この時点で、e-paper ディスプレイは何度か暗くなってから明るく戻ります。
ePaper ディスプレイへの描画
✅ 次のモジュールをスコープに取り込みます。
#![allow(unused)]
fn main() {
use embedded_graphics::{
geometry::Point,
pixelcolor::BinaryColor,
prelude::*,
primitives::{ Circle, Triangle },
style::PrimitiveStyle,
};
}
✅ waveshare e-Paper ディスプレイは二値カラーシステムを持っています。色は On または Off のどちらかです。On は黒を意味し、Off は白を意味します。
ディスプレイに描画する方法の 1 つは、プリミティブな図形を使用することです。この crate は、円、三角形、長方形、線を提供しています。それぞれは重要な点と距離によって定義されます。たとえば、円は中心と半径によって定義されます。
各図形は塗りつぶすことも、エッジの周囲の線だけで表すこともできます。ディスプレイのコンテンツを定義するたびに、ディスプレイバッファーに追加する必要があります。これは draw メソッドで行います。
✅ 次の図形定義、2 つの円と 1 つの三角形をプログラムに追加します。
#![allow(unused)]
fn main() {
let c1 = Circle::new(Point::new(171, 110), 30)
.into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
.draw(&mut display);
let c2 = Circle::new(Point::new(229, 110), 30)
.into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
.draw(&mut display);
let t1 = Triangle::new(Point::new(259, 120), Point::new(141, 120), Point::new(200, 200))
.into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
.draw(&mut display);
}
draw() メソッドを使うだけでは、実際に画面に何かを表示するには不十分です。図形をディスプレイに表示するには、spi 接続を介してフレームを更新し、フレームを表示する必要があります。
✅ 次の行をコードに追加します。
#![allow(unused)]
fn main() {
epd4in2.update_frame(&mut spi, &display.buffer()).unwrap();
epd4in2.display_frame(&mut spi)
.expect("新しいグラフィックのフレームを表示");
}
✅ コードを実行します。2 つの円と 1 つの三角形で構成されたシンボルが表示されるはずです。