ラズベリーパイで電子ペーパーの使い方

ラズベリーパイで電子ペーパー(WaveShare製)の使い方をまとめました。
電気を流すことで書き込み、消去、書き換えができ、電源をOffしても表示が消えないディスプレイデバイスのことです。書き込み時に電気を少し消費するだけで、同じものをずっと表示させておくのに電気を必要せず、超エコなデバイスとしてさまざまなところで使用されています。
使用する電子ペーパー
この記事で使用するのは、千石電商で販売している WaveShare 13357 2.7インチ 264×176 E-Ink 赤/黒/白 3色 電子ペーパーモジュール for RaspberryPi です。ほかWaveShare製の電子ペーパーでも使用方法は同じです。
使用準備
Raspberry Pi OSの最新化
ターミナルから以下のコマンドを実行します。
sudo apt update
apt full-upgrade -y
SPIインターフェースの有効化
電子ペーパーはSPIインターフェースでラズパイと接続しますので、ラズパイ側で有効化します。ターミナルから以下のコマンドを実行し
sudo raspi-config
5 Interface Options → P4 SPI の順にキーボードで選択し、<YES>の上でEnterキーを押し、最後にESCキーを押して完了です。

waveshare.comより
ラズパイの再起動
sudo reboot
BCM2835ライブラリーのダウンロードとインストール
wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.71.tar.gz
tar zxvf bcm2835-1.71.tar.gz
cd bcm2835-1.71/
sudo ./configure && sudo make && sudo make check && sudo make install
wiringPiライブラリーのインストール
git clone https://github.com/WiringPi/WiringPi
cd WiringPi
./build
gpio -v
Pythonライブラリーのインストール
sudo apt-get install python3-pip python3-pil python3-numpy
sudo pip3 install RPi.GPIO spidev
電子ペーパーの取り付け
以下のように電子ペーパーをラズパイに取り付けます。
サンプルのダウンロードと実行
以下のコマンドを実行します。画面が色々と切り替わるサンプルが2分間表示されます。実際の動作はこちらをごらんください。
cd ~
git clone https://github.com/waveshare/e-Paper
cd e-Paper/RaspberryPi_JetsonNano/python/examples/
sudo python epd_2in7b_V2_test.py
サンプルの解説
バッファーに図形や文字、ビットマップ画像ファイルを読み込み、最後に描画します。
初期化と消去
epd.init()
epd.Clear()
縦で使用
HBlackimage = Image.new('1', (epd.height, epd.width), 255) # 298*126
HRedimage = Image.new('1', (epd.height, epd.width), 255) # 298*126
drawblack = ImageDraw.Draw(HBlackimage)
drawred = ImageDraw.Draw(HRedimage)
横で使用
LBlackimage = Image.new('1', (epd.width, epd.height), 255) # 126*298
LRedimage = Image.new('1', (epd.width, epd.height), 255) # 126*298
drawblack = ImageDraw.Draw(LBlackimage)
drawred = ImageDraw.Draw(LRedimage)
文字、図形
以下の python epd_2in7b_V2_test.py に# 1 などとコメントをつけた部分と、実際の画面表示を見比べてみてください。
drawblack.text((10, 0), 'hello world', font = font24, fill = 0) # 1
drawblack.text((10, 20), '2.7inch e-Paper', font = font24, fill = 0) # 2
drawblack.text((150, 0), u'微雪电子', font = font24, fill = 0) # 3
drawblack.line((20, 50, 70, 100), fill = 0) # 4
drawblack.line((70, 50, 20, 100), fill = 0) # 5
drawblack.rectangle((20, 50, 70, 100), outline = 0) # 6
drawred.line((165, 50, 165, 100), fill = 0) # 7
drawred.line((140, 75, 190, 75), fill = 0) # 8
drawred.arc((140, 50, 190, 100), 0, 360, fill = 0) # 9
drawred.rectangle((80, 50, 130, 100), fill = 0) #10
drawred.chord((200, 50, 250, 100), 0, 360, fill = 0) # 11
drawblackおよびdrawredは、色が黒と赤に指定された描画オブジェクトです。
text()は文字を書き出すメソッドです。(10, 0)などとなっているのは開始座標です。10がX座標で左端からピクセルで数えます。0はY座標で、上から数えます。フォントは予め宣言しておいたfont24などを指定します。
line()は線を書き出すメソッドです(165, 50, 165, 100)などとなっているのは開始座標(165, 50)と終了座標(165, 100)です。
rectangle()は四角を書き出すメソッドです。2点の座標を指定して描画します。outline=0で枠線のみ、fill=0で塗りつぶしとなります。
arc()は弧を、chord()は塗りつぶし円を描き出すメソッドです。
フォントサイズ
フォントサイズは最初に定義しておく必要があります。
font24 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 24)
font22 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 22)
font20 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 20)
font18 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 18)
font16 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 16)
font14 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 14)
font12 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 12)
font10 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 10)
font8 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 8)
drawblack.text((0, 0), 'ラズパイからこんにちは!', font = font24, fill = 0)
drawred.text((0, 20), 'ラズパイからこんにちは!', font = font22, fill = 0)
drawblack.text((0, 40), 'ラズパイからこんにちは!', font = font20, fill = 0)
drawred.text((0, 60), 'ラズパイからこんにちは!', font = font18, fill = 0)
drawblack.text((0, 80), 'ラズパイからこんにちは!', font = font16, fill = 0)
drawred.text((0, 100), 'ラズパイからこんにちは!', font = font14, fill = 0)
drawblack.text((0, 120), 'ラズパイからこんにちは!', font = font12, fill = 0)
drawred.text((0, 140), 'ラズパイからこんにちは!', font = font10, fill = 0)
drawblack.text((0, 160), 'ラズパイからこんにちは!', font = font8, fill = 0)
文字をかなり大きくすることもできます。
font170 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 170)
font100 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 100)
font50 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 50
drawblack.text((0, 0), 'ラズパイからこんにちは!', font = font170, fill = 0)
drawred.text((0, 0), 'ラズパイからこんにちは!', font = font100, fill = 0)
drawblack.text((0, 100), 'ラズパイからこんにちは!', font = font50, fill = 0)
画像(全画面)
黒で表示したい画像と赤で表示したい画像をビットマップ(bmp)形式で準備しておいて使用します。
HBlackimage = Image.open(os.path.join(picdir, '2in7b-b.bmp'))
HRedimage = Image.open(os.path.join(picdir, '2in7b-r.bmp'))
画像(場所指定)
ウィンドウを先に作っておいて、そこに座標で指定してペーストします。
blackimage1 = Image.new('1', (epd.height, epd.width), 255) # 298*126
redimage1 = Image.new('1', (epd.height, epd.width), 255) # 298*126
newimage = Image.open(os.path.join(picdir, '100x100.bmp'))
blackimage1.paste(newimage, (50,10))
描画
バッファーに書き込んだ情報を描画します。
epd.display(epd.getbuffer(blackimage1), epd.getbuffer(redimage1))
スリープ
描画が終わって、sleep()メソッド実行以降は電源Offできます。
epd.sleep()
ラズパイから外しても書き込んだ文字・図形・画像は消えません。
リファレンス
以下をご参照ください。
https://www.waveshare.com/wiki/2.7inch_e-Paper_HAT_(B)_Manual#Raspberry_Pi
おわりに
いかがだったでしょうか? 電子ペーパーが使えると、応用でいろいろ作れますのでぜひ使ってみてくださいね😊