はじめに
既製品を組み合わせてなるべく短時間で、
電子ペーパーに表示する内容をカスタマイズ可能なプロトタイプを作成することを目的とします。
あくまでプロトタイプなので、費用やオペレーションコストについては考えません。
用意するもの
Raspberry Pi WH Zero WH
似たような製品にRaspberry Pi Zero Wがあります。
Raspberry Pi Zero WHはRaspberry Pi Zero Wにピンヘッダが実装されたモデルです。
はんだごてをお持ちでない方にはRaspberry Pi Zero WHをお勧めします。
スイッチサイエンスさんから購入できます。
Raspberry Pi Zero WH - スイッチサイエンス
2.7インチ 264×176 E-Ink 赤/黒/白 3色 電子ペーパーモジュール for RaspberryPi
秋葉原の千石電商さんでも購入できます。
ディスプレイのサイズ・色数のバリエーションがあります。
今回は2.7inch/赤・黒・白のモデルを選択しました。
千石電商さんから購入できます。
WaveShare 13357 2.7インチ 264×176 E-Ink 赤/黒/白 3色 電子ペーパーモジュール for RaspberryPi
microSDカード/microUSB端子に対応した電源
Rapsberry Piを使うなら必須のアイテム。
microSDカードは容量が8GB以上のものを使いましょう。
電源は1.2A以上の給電能力が必要です3。
(オプショナル)キーボード/miniHDMIケーブル
sshを使わない場合に必要になります。
Raspberry Pi Zero WHをセットアップする
OSはこちらからダウンロードできます。
OSは執筆時点(2020/03/28)で最新のRaspibian Buster Liteを採用しました。
microSDにOSを書き込む手順は「Raspberry Pi セットアップ」などのキーワードで検索していただければ日本語の記事がヒットします。
公式からインストールガイドも公開されていますので載せておきます。
Installing operating system images - Raspberry Pi Documentation
ディスプレイに繋ぐのが面倒な人は、この設定をしておくと初期設定のためにディスプレイに接続する必要がなくなります。
Raspberry Piの無線LANをmicroSDで設定する - Qiita
電子ペーパーモジュールとRaspberry Pi Zero WHを接続する
サンプルコードを実行する
WaveShare社が公開している公式Wikiの通りに作業します。
ターミナルを開き、以下のコマンドを実行してください。
sudo raspi-config
すると設定画面が表示されます。
「Interfacing Options」を選択、
→「SPI」を選択、
→「Yes」を選択してください。
4
以下のコマンドを実行して再起動します
sudo reboot
必要なライブラリをインストールします。
# install bcm2835 libraries
wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.60.tar.gz
tar zxvf bcm2835-1.60.tar.gz
cd bcm2835-1.60/
sudo ./configure
sudo make
sudo make check
sudo make install
# install wiringPi libraries
sudo apt-get install wiringpi
# install Python3 libraries
sudo apt-get update
sudo apt-get install python3-pip
sudo apt-get install python3-pil
sudo apt-get install python3-numpy
sudo pip3 install RPi.GPIO
sudo pip3 install spidev
WaveshareさんがGitHubで公開しているリポジトリをクローンします。
sudo git clone https://github.com/waveshare/e-Paper
サンプルコードのあるディレクトリに移動して実行してみましょう。
cd e-Paper/RaspberryPi\&JetsonNano/python/examples
sudo python3 epd_2in7b_test.py
実行時の様子は動画にしましたので、こちらをご覧ください。2分ぐらいあります。
サンプルコード5をみてみましょう。
#!/usr/bin/python
# -*- coding:utf-8 -*-
import sys
import os
picdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'pic')
libdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'lib')
if os.path.exists(libdir):
sys.path.append(libdir)
import logging
from waveshare_epd import epd2in7b
import time
from PIL import Image,ImageDraw,ImageFont
import traceback
logging.basicConfig(level=logging.DEBUG)
try:
logging.info("epd2in7b Demo")
epd = epd2in7b.EPD()
logging.info("init and Clear")
epd.init()
epd.Clear()
time.sleep(1)
# Drawing on the image
logging.info("Drawing")
blackimage = Image.new('1', (epd.width, epd.height), 255) # 255: clear the frame
redimage = Image.new('1', (epd.width, epd.height), 255) # 255: clear the frame
font24 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 24)
font18 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 18)
# Drawing on the Horizontal image
logging.info("1.Drawing on the Horizontal image...")
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)
drawblack.text((10, 0), 'hello world', font = font24, fill = 0)
drawblack.text((10, 20), '2.9inch e-Paper', font = font24, fill = 0)
drawblack.text((150, 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)
drawred.line((165, 50, 165, 100), fill = 0)
drawred.line((140, 75, 190, 75), fill = 0)
drawred.arc((140, 50, 190, 100), 0, 360, fill = 0)
drawred.rectangle((80, 50, 130, 100), fill = 0)
drawred.chord((200, 50, 250, 100), 0, 360, fill = 0)
epd.display(epd.getbuffer(HBlackimage), epd.getbuffer(HRedimage))
time.sleep(2)
# Drawing on the Vertical image
logging.info("2.Drawing on the Vertical image...")
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)
drawblack.text((2, 0), 'hello world', font = font18, fill = 0)
drawblack.text((2, 20), '2.9inch epd', font = font18, fill = 0)
drawblack.text((20, 50), u'微雪电子', font = font18, fill = 0)
drawblack.line((10, 90, 60, 140), fill = 0)
drawblack.line((60, 90, 10, 140), fill = 0)
drawblack.rectangle((10, 90, 60, 140), outline = 0)
drawred.line((95, 90, 95, 140), fill = 0)
drawred.line((70, 115, 120, 115), fill = 0)
drawred.arc((70, 90, 120, 140), 0, 360, fill = 0)
drawred.rectangle((10, 150, 60, 200), fill = 0)
drawred.chord((70, 150, 120, 200), 0, 360, fill = 0)
epd.display(epd.getbuffer(LBlackimage), epd.getbuffer(LRedimage))
time.sleep(2)
logging.info("3.read bmp file")
HBlackimage = Image.open(os.path.join(picdir, '2in7b-b.bmp'))
HRedimage = Image.open(os.path.join(picdir, '2in7b-r.bmp'))
epd.display(epd.getbuffer(HBlackimage), epd.getbuffer(HRedimage))
time.sleep(2)
logging.info("4.read bmp file on window")
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))
logging.info("Clear...")
epd.init()
epd.Clear()
logging.info("Goto Sleep...")
epd.sleep()
except IOError as e:
logging.info(e)
except KeyboardInterrupt:
logging.info("ctrl + c:")
epd2in7b.epdconfig.module_exit()
exit()
電子ペーパーに表示したい内容はPillowのImageオブジェクトで渡してあげればいいことがわかります。
epd.getbuffer()
の第一引数には黒で描画したいイメージを、第二引数には赤で描画したいイメージを指定します。
epd.display(epd.getbuffer(LBlackimage), epd.getbuffer(LRedimage))
カスタマイズしてみた
日本語フォントを使うにはImageFont
でフォントファイルを読み込みます。
ImageFont Module — Pillow (PIL Fork) 7.0.0 documentation
附録
費用
項目 | 金額 |
---|---|
電子ペーパーモジュール | ¥2,590 |
Raspberry Pi Zero WH | ¥1,848 |
microSDカード 16GB | ¥800 |
microSDカードは価格幅が広いので参考程度に。
合計すると¥5,300ぐらいです。
ここには含めませんでしたが、電源も必要です。
消費電力
公式サイトのFAQをみるとRaspberry Pi Zero WHの平常時の消費電流は0.15Aです。
電源が近くにないような場面ではモバイルバッテリーによる電力供給も考えられますが、
何時間稼働させられるんでしょうか?
Pi Zero Wはモバイルバッテリーでどのくらいの時間動作するか
↑こちらの記事によると、
5200mAhのバッテリーで、Pi Zero W本体のみ動作した時間は28時間42分
と書かれています。たかだか1日しか稼働させられないので用途は限られますね。
別の選択肢として、公式からPoE HATが発売されています。
ただし、対応するモデルはRaspberry Pi 4 Model BとRaspberry Pi 3 Model B+のみです。
これを接続すればイーサネットケーブルで給電できます。
電子ペーパーモジュール使用上の注意
目を通すのを忘れがちなユーザマニュアルに大事なことが書いてあったので一部抜粋して掲載します。
公式ユーザマニュアル
The e-Paper cannot be powered on for long time, you must set e-Paper to sleep mode or power off when it needn’t refresh, otherwise, e-Paper keeps in high voltage status for long time, which will damage e-Paper and cannot be fixed.
電子ペーパーに電圧をかけた状態をキープすると、電子ペーパーがダメージを受けるのでスリープを設定してください。
We suggest you update e-Paper once every 24 hours or at least 10 days to update again. Otherwise, ghost of the last content may cannot be cleared.
毎日1回、最低でも10日に1回は電子ペーパーを更新することを推奨します。
そうしないと、ゴーストが生じる恐れがあります。
The e-Paper cannot refresh directly under sunlight. The refresh steps should be
done indoor
電子ペーパーは日光のあたるところでリフレッシュできません。リフレッシュは屋内でするようにしてください。
NFC対応電子ペーパー
Waveshareさんから電源不要でNFCで表示切替できる製品が発売されています。
4.2inch Passive NFC-Powered e-Paper, No Battery, Wireless Powering & Data Transfer
-
WaveShare 13357 2.7インチ 264×176 E-Ink 赤/黒/白 3色 電子ペーパーモジュール for RaspberryPiより引用 ↩
-
FAQs - Raspberry Pi DocumentationのPower > What are the power requirements?を参照 ↩
-
2.7inch e-Paper HAT (B) - Waveshare WikiのRaspberry Pi > Hardware connectionより引用 ↩