昨日、小型TFT LCDのST7735、MicroPython用ドライバにスクロール機能を追加しましたが、その目的はこのLCDでFBConsoleを動かしてみることです。
FBConsoleは、MicroPythonのフレームバッファクラスのディスプレイデバイスに、MicroPythonのターミナルを出力するためのクラスです。
これまでもOLEDのSSD1306やRaspberry Piの画面にターミナルを表示するために使ってきました。
実際には、FBConsoleはフレームバッファに限らず、以下のAPIを持つグラフィックディスプレイであれば利用可能です。
・fill(self, color) --- 画面をcolorで塗りつぶす(画面消去用)
・fill_rect(self, x, y, w, h, color) --- 塗りつぶした矩形を描く(行消去用)
・scroll(self, dx, dy) --- dyピクセル縦スクロールする(横スクロールは不要)
・hline(self, x, y, w, color) --- 水平線を描く(カーソル表示用)
・text(self, c, x, y, color) --- 1文字描く
ST7735ドライバには、これまでスクロール機能が欠けていたのですが、前回追加しましたので必要条件は満たしています。
ただ、関数の形式がこのドライバと上記のAPIで若干異なっています。
たとえば上記のAPIではXY座標はそれぞれ別のパラメータで渡しているのに対して、ST7735ドライバは(X,Y)というタプルで渡すようになっています。
そこで、両者の橋渡しをするラッパークラスを作ってみました。
コードは、以下のFBConsoleのリポジトリに置いてあります。
FBConsole/ST7735fb.py at master · boochow/FBConsole
処理内容はAPIの差分吸収と、スクロール関連の計算です。
FrameBufferクラスは、スクロールは実際にフレームバッファ上のデータをコピーします。
一方、ST7735では一種の座標変換をするだけで、データは移動しません。
REPLで画面最下行で改行すると、1行分スクロールして、画面最下行を消去するという処理が必要になります。
画面最下行の領域を表す座標は、FrameBufferクラスでは常に一定ですが、ST7735ではスクロールの設定値に合わせて変化します。
このため、スクロール値を記憶して、画面上の座標を実際の座標(アドレス)に変換しています。
使い方は以下のようになります。
前回と同じく、ESP32での例です。結線も同じです。
まず、普通にTFT LCDドライバのオブジェクトを作成します。
次に、スクロールの設定をします。
ST7735Sのフレームバッファは縦162ピクセル、実際に表示できるのは160ピクセルなので、
トップとボトム1ピクセルずつ(スクロールしていない状態のときは表示されないピクセル)をスクロール領域から除外します。
そして、これをラッパークラスST7735fbでくるみます。
そして、さらにそれをFBConsoleに渡します。
最後にos.dupterm()を呼び出してREPLを出力させます。
duptermを終了するときは、dupterm(None)
を実行します。
なお、FBConsoleから使用するには文字表示の速度が遅かったので、これもST7735ドライバ側で改善しました。
改善前は、フォントデータのドット一つ一つについて、オンなら1ピクセル描画、という処理をしていたので遅かったのですが、これを1文字分のイメージを作成してまとめてLCDに転送するように変更しました。
高速というわけではないのですが、REPL程度ならまあまあ使える速度になりました。
また、MicroPythonのFrameBufferで文字表示するときに使われている「petme128」というフォントを使えるようにしました。
これもFBConsole/petme128.pyとしてFBConsoleのリポジトリに置いてあります。
コメント