ITで遊ぶ

e-inkのディスプレイを使ってみる

e-inkディスプレイをちょくちょく見かけます。
私がもっているものだとKindle Paper Whiteです。

大きいと高いので安いものを探すとAmazonで見つけました。
似たようなデバイスがたくさんあります。Aliexpressで探してみても値段があまりAmazonと変わりませんでした。
購入してみると、裏にPico-ePaper-2.13とあり、V4というシールが貼ってあります。

調べると日本語表示を試したサイトがありました。

環境構築

*最初からe-paperモジュールを取り付けないこと。MicroPythonがインストールできません。

まずMicroPython(本家はこちら )をインストールするわけですが、。これを使わずにPython IDEのThonnyをインストールします。
なぜか?こんな疑問もちませんか?MicroPythonをボード上で動かしてどうやってPythonプログラムを読み込ませ実行するのだろうか?Thonnyを入れておけばシリアルで接続してMicroPythonプログラムを簡単に試せます。
最終的にはmain.pyをルートにおいておけば自動実行されます。

Thonnyをインストールしたら、ツール->オプションを選択します。(もちろん話はすべてMac上です)

ここで「ジェネラル」タブで言語を選べるので「日本語」を設定しておきます。
次に「インタプリタ」でPythonはMicroPython(Raspberry PI Pico)を選びます。
ここでRaspberry PI picoをUSBで接続します。
ThonnyにUSBシリアル接続するために「ポートまたはWebREPL」をクリックして妥当っぽいものを選びます。
そして
をクリックすると、MicroPythonがインストールされ、Thonnyとつながるはず。

OKを押して、メイン画面に戻るとシェルにPythonの状況が出力されています。

ここまでが開発環境作成です。

ちょっと試しにコードを書いて実行してみます。毎度おなじみLチカです。

右上のペインにコードを書いて、最上段のメニューで実行のコントロールができます。▶で実行STOP🛑で停止です。

e-paperディスプレイ表示

動作テストプログラムはここにあります。

ソースコードを睨むと、

class EPD_2in13_B_V4_Portrait:
class EPD_2in13_B_V4_Landscape:

とクラスがふたつあります。縦向き用、横向き用ですね。
__main__のスタート部分を見ると

epd = EPD_2in13_B_V4_Portrait()  #インスタンス化
epd.Clear(0xff, 0xff) #リセット

がスタートのようです。

epd = EPD_2in13_B_V4_Landscape()
epd.Clear(0xff, 0xff)
    
epd.imageblack.fill(0xff)
epd.imageblack.text("Waveshare", 5, 20, 0x00)
epd.display()
# epd.delay_ms(2000)

epd.sleep()

が最小限のルーチンでテキストを表示します。
imageblack.fillに0xffを渡すと画面が白くなります。

日本語フォントをもってこねばならず、https://github.com/Tamakichi/pico_MicroPython_Multifontを使わせてもらいます。ダウンロードし、misakifontのフォルダーをRaspi内にアップロードします。Thonnyの左上のローカルフォルダーを表示しているペインでダウンロードしたmfontに移動します。mfontフォルダーを右クリックすると「/にアップロード」というメニューがあるのでこれをクリックします。(このメニューはRaspiに接続していないと出ません)
なお、mfontのReadmeにあるとおり全部のフォントをそのままコピーすると入りきれません。私は14×14と16×16だけをアップロードしています。

このフォルダーを使うために、Pythonプログラムの冒頭のimportしているところに次を書き加えます。

from mfont import mfont

先のブログを参考にして、以下の2つの関数をクラス定義の後に追加します。

def jpblackchar(fd, epd, x, y, width, height): 
    bn = (width+7)>>3
    py = y
    for i in range(0, len(fd), bn):
        px = x
        for j in range(bn):
            for k in range(8 if (j+1)*8 <=width else width % 8): if fd[i+j] & 0x80>>k:
                    epd.imageblack.pixel(px + k, py, 0x00)
            px+=8
        py+=1

def jpblacktext(str, x, y, mf, epd):
    mf.begin()
    for c in str:
        d = mf.getFont(ord(c))
        jpblackchar(d, epd, x, y, mf.getWidth(), mf.getHeight())
        x = x + mf.getWidth() 
    mf.end()

メインを次のように書き換えてみましょう。

if __name__=='__main__':
epd = EPD_2in13_B_V4_Landscape()
epd.Clear(0xff, 0xff)

epd.imageblack.fill(0xff)
# epd.imageblack.text("Waveshare", 5, 20, 0x00)
mf = mfont()
mf.setFontSize(16)
str = "日本語表示"
jpblacktext(str, 5, 35, mf, epd)
mf.setFontSize(14)
str = "日本語表示2行目"
jpblacktext(str,5,60,mf,epd)
epd.display()
# epd.delay_ms(2000)

epd.sleep()

こんな感じ。電源を切っても表示されたままなところがうれしいです。

ちなみに使っているピンは次の図のとおり。

電源以外にgpio 8,9,10,11,12,13ピンを使っているようです。

スリープにいれる

ここからが問題です。せっかくe-inkでディスプレイしているのだから、システムはスリープ状態に入れて、スイッチを押したらまた動作させたい、と思うじゃないですか。そうすれば電池でもいいわけです。(省電力、大好き!)

ところがMicroPythonのmachine.lightsleepやmachine.deepsleepはGPIOをトリガーにして復活はしません。
これらの関数は長時間を消費電力を絞って待つためのもののようです。

探すとpico-micropython-lowpower-workaroundという解決策がありました。これはlopower.pyだけをダウンロードしてインポートすれば使えますが、deepsleep並に省電力モードに入ります。
電気を使わないモードなのでピンは当然、電源にくっつけたら起きる、ということになります。

import lowpower
---
DORMANT_PIN = 16 #GPIO PIN番号
---
#スリープしたいところで
lopower.dormant_until_pin(DORMANT_PIN)
machine.reset()

とします。
ただし、これを含むプログラムはmain.pyとしてラズパイに書き込んでください。
理由はresetで最初からスタートすると、Thonnyのプログラムは実行しません。main.pyを実行します。
再び、Thonnyとつなぎたい場合はThonnyのSTOP🔴ボタンを押すとmain.pyの実行を中断し、再度、接続できます。

 

関連記事

  1. JavaScriptグラフィック(1)

  2. PyUSB 私家版日本語訳(3)

  3. 製品を作るおじさんの独り言

  4. M5StickC資料

  5. AIを使ったプログラミング

  6. M5StickCなどをさらに研究

  7. Mac OSXでのFTDIの問題

  8. Arduinoでセンシングしてモーターを動かす