Raspberry Pi で電子インクディスプレイを制御する
みんな大好き AliExpress を眺めていたら、E-Ink ディスプレイが Raspberry Pi から簡単に制御できそうだったので遊んでみることにしました。
どれにしようかな?
大小さまざま色々あります。2 ~ 3 インチくらいが主流のようですが、大きいものでは 5 ~ 7 インチくらい。価格は 2 インチ台のものであれば2千円ちょっとから3千円くらいで、色数は2色(白黒)か3色(白黒赤)。サイズが大きくなると7色のものもあるようです。
モジュールとして売られている E-Ink ディスプレイのほとんどが Waveshare Electronics という会社のものの様ですね。
こちらの会社、Wiki が非常に充実しています。Raspberry Pi や Arduino 向けのチュートリアルがサンプルコードも非常に充実していて、購入してはみたものの動かないということはなさそうです。
Raspberry Pi の 24 ピンに刺さる HAT タイプと、ジャンパー線で接続するタイプがって、HAT タイプだとヘッダピンがうまってしまって他のセンサーが接続できないなぁと思って、ジャンパー線で接続するタイプの 2.66 インチのものにしました。
とはいえ、HAT タイプでもジャンパー線ようのソケットはついているようですが。
ちなみに、わざわざ AliExpress で買わなくても Waveshare Electronics の E-Ink ディスプレイは Amazon などでも売られていて、価格もさほど変わらないようです。
とりあえず動かそう
Wiki に従って動かしてみましょう。Raspberry Pi とは SPI で接続するので、SPI を有効にしてサンプルを動かします。C と Python のサンプルがありますが、サンプルを動かすだけであれば、どちらでもすんなり動くでしょう。
自分で制御してみよう
サンプルを参考に、今度は自分で簡単なサンプルを書いてみましょう。はじめに、仮想環境を作って必要なモジュールをインストールします。
$ python3 -m venv .venv
$ . .venv/bin/activate
$ pip install pillow
$ pip install RPi.GPIO
$ pip install spidev
$ pip install waveshare-epaper
日本語フォントがインストールされていないようであれば IPA フォントをインストールします。
$ sudo apt install -y fonts-ipafont
$ fc-cache -fv
$ fc-list | grep -i ipa
まず、E-Inkディスプレイの初期化を行います。
import os
import epaper
from PIL import Image,ImageDraw,ImageFont
epd = epaper.epaper('epd2in66b').EPD()
epd.init()
epd.Clear()
Pillow で黒と赤の画面をそれぞれ作り、E-Ink ディスプレイに表示ます。作成したイメージを転送しているだけなので、リモートでイメージを作成して、ネットワーク越しに配信することもできそうですね。
font24 = ImageFont.truetype(os.path.join('/usr/share/fonts/opentype/ipafont-gothic/', 'ipagp.ttf'), 24)
font18 = ImageFont.truetype(os.path.join('/usr/share/fonts/opentype/ipafont-gothic/', 'ipagp.ttf'), 18)
HBlackimage = Image.new('1', (epd.height, epd.width), 255) # 296*152
drawblack = ImageDraw.Draw(HBlackimage)
drawblack.text((10, 0), 'hello world', font=font24, fill=0)
drawblack.text((10, 20), '2.66inch e-Paper b', font=font24, fill=0)
drawblack.text((165, 0), u'こんにちは', font=font24, fill=0)
drawblack.line((20, 50, 70, 100), fill=0)
drawblack.line((70, 50, 20, 100), fill=0)
drawblack.rectangle((20, 50, 70, 100), outline=0)
HRYimage = Image.new('1', (epd.height, epd.width), 255) # 296*152 ryimage: red or yellow image
drawry = ImageDraw.Draw(HRYimage)
drawry.line((165, 50, 165, 100), fill=0)
drawry.line((140, 75, 190, 75), fill=0)
drawry.arc((140, 50, 190, 100), 0, 360, fill=0)
drawry.rectangle((80, 50, 130, 100), fill=0)
drawry.chord((200, 50, 250, 100), 0, 360, fill=0)
epd.display(epd.getbuffer(HBlackimage), epd.getbuffer(HRYimage))
こんな感じで表示されます。書き換えを行う時だけ電力を消費するので、電源を抜いても表示された内容は保持されます。電子棚札などに使われているようです。
画面の書き換えにはちょっと時間がかかるのと、書き換え中はけっこう画面がちらつきます。センサーから取得した値など、リアルタイムで表示するには向いていないようです。
どうやら、部分書き換えに対応しているモデルもあるようですが、このモデルは対応していないようです。
まとめ
E-Ink ディスプレイで遊んでみました。可視性も高く、書き換え時以外は電源が不要なのがよいですね。ただし、書き換えには時間がかかるので、アニメーションやリアルタイムで変化する値を表示するのには向かないようです。
そういう用途で使いたい場合には、部分更新に対応したものを購入したほうがよさそうです。
Discussion