電子ペーパー GDEH0154D27 を動かし調整し描画速度などを測定して遊んだメモ

ふとしです。

Rust + 電子工作勉強の一環として、適当にモジュールを買って、Rust でライブラリを書いて動かすということをしています。

今回は電子ペーパー GDEH0154D27 を Raspberry Pi Zero で動かして遊んだので日記にします。

とりあえず動かしてみるためのさまざま

GDEH0154D27 を動かしてみる上でいちばん苦労したのはこの公式マニュアルと公式サンプルコードの入手で、Google からのサイト検索でようやくみつけることができました。

サンプルコードを動かして配線の正しさを確認すれば、パラメーターを調整してなにがどうなっているかを実機を通して観察できるようになります。

描画の流れ

初期化を除いた描画ごとのフローは以下のようになります。

  1. 描画で使う RAM の範囲を送信する
  2. 描画で使う RAM 位置のカウンター開始位置を送信する
  3. 画像データを送信する
  4. 画像の反映オプションを送信する
  5. 画像を反映する命令を送信する
  6. 描画が終わるまで待つ
  7. 1 にもどる

画像データの形式および RAM に関する値

この電子ペーパーでは 2 色しか扱わないので、送信する画像データもそれにあわせて最適化されています。2 色のデータの最適化には流派があるようですが、この電子ペーパーでは 1 行 8 列を 1 byte として送信します。

たとえば 24 * 2 の画像では以下のように扱い、6 bytes のデータとして送信します。

******** ******** ********
******** ******** ********

同様に RAM に関する値を送信する場合の x 座標は x >> 3 した値となります。

問題になる局面

全画面を描画する際には問題ありませんが、画面の一部を描画しなおす場合は 8 の倍数の範囲を必ず含めなければなりません。

例えばなんらかの計測値の数字のみを描画しなおす場合でも、単位部分が範囲に含まれる場合には忘れずに送信データに含める必要があります。

マニュアルにのっていない定数

VCOM と LUT はサイトなどで見つけられなかったため、サンプルコードのものが公式であるとみなしています。

const VCOM: u8 = 0xA8;

const LUT_FULL_UPDATE: [u8; 30] = [0x66, 0x66, 0x44, 0x66, 0xAA, 0x11, 0x80, 0x08, 0x11, 0x18, 0x81, 0x18, 0x11, 0x88, 0x11, 0x88, 0x11, 0x88, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x5F, 0xAF, 0xFF, 0xFF, 0x2F, 0x00];

const LUT_PARTIAL_UPDATE: [u8; 30] = [0x10, 0x18, 0x18, 0x28, 0x18, 0x18, 0x18, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x11, 0x22, 0x63, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00];

描画速度

この電子ペーパーでは使用する LUT を送信して切りかえることで描画をフルアップデートかパーシャルアップデートかに設定できます。

(なお、LUT はサンプルコードに添付されている他、独自に調整したものを公開しているサイトもあるようです)

描画速度うちわけ

画像によって変化する部分としない部分があります。

ほぼ固定値 (画像反映時)

アップデート形式により以下の時間がほぼ固定でかかります。

形式時間
フルアップデート3600ms
パーシャルアップデート500ms

画像によって可変 (画像送信時)

それに加え、画像のデータ量に応じた時間がかかります。以下はテストでライフゲームを送信した時の値です。各辺が 2 倍になっていくので、データ量は 4 倍になっていっています。

面積時間
16 * 932ms
32 * 1872ms
64 * 36205ms
128 * 72758ms

全画面の場合は以下のようになります。

面積時間
200 * 2003220ms

つまり

全画面再描画かつフルアップデートだと 3600 + 3220 で 7 秒近くかかってアニメーション用途には使えません。

一方 64 * 36 かつパーシャルアップデートなら 500 + 72 で 0.6 秒程度となり、比較的アニメーションに耐える描画速度と言えるでしょう。秒あたりで計測値が変わるようなものの表示なら大丈夫かもしれません。

まとめ

以下は電子ペーパーを操作する部分と、1 byte に 8 ピクセル詰め込むために書いたおれおれクレートです。

Raspberry Pi Zero で動かしたモジュール 2 発目がこの電子ペーパーでしたが、データの送信形式など、バブリーなウェブプログラミングとは違った点が様々にあり、勉強になりました。

また、Rust はこのような用途にも非常に相性がよく書いてて非常に快適でした。もっと Rust を書けるようになりたいですね。