1.8インチや1.44インチの小さなTFTディスプレイの制御にST7735が使われています。小型のTFTディスプレイは、場所も取らずに手軽に利用できるので、デバイスの状況を確認するためにちょっとした表示機能が欲しい時に重宝します。

弊社のESP32-SLIMには、これらの小さなディスプレイを開発基板上に直接接続できる端子が用意されています。以下の写真は、ESP32-SLIMに1.44インチのTFTディスプレイを搭載した例です。

Arduinoではいくつかのライブラリが提供されていてスケッチを書いて楽しめるので、MicroPythonでもTFTのプログラミングを楽しめるようにST7735を使用したTFTディスプレイの利用法を紹介します。

ST7735用のドライバの取得

まず、Thonnyのパッケージ管理システムを利用してST7735用のドライバを検索すると、MicroPython用のドライバが登録されていないようです。そこで、WEBの検索を行うと以下のドライバ[ST7735.py]が見つかりました。

また、このドライバは、以下のサイトのプログラムを基に作られたようで、このサイトで配布されているフォントファイル[sysfont.py]を使用します。

上記のサイトから、[ST7735.py, sysfont.py]を取得して、2つのファイルを開発ボードのファイルシステムに登録してください。

ST7735用ドライバの変更

取得したST7735用のドライバは、1.8インチのTFTディスプレイ専用に作成されており、表示領域の指定が160x128ピクセルに固定されています。残念ながら、表示領域のサイズをコンストラクタやメソッドで変更できるようにはなっていません。1.8インチのTFTディスプレイで利用する場合には問題ありませんが、1.44インチのTFTディスプレイで使用する場合には、ピクセルサイズを128x128に変更する必要があります。

表示領域のサイズは、ST7735.pyの36行目にハードコーディングされています。1.44インチのTFTディスプレイを使用る場合には、この指定を(128, 128)に変更してください。

デモプログラム

ST7735用ドライバのデモプログラムとしてgraphicstest.pyが提供されているので、このプログラムで動作確認をしましょう。

graphicstest.pyの冒頭部分は以下のようになっています。

from ST7735 import TFT
from sysfont import sysfont
from machine import SPI,Pin
import time
import math
spi = SPI(2, baudrate=20000000, polarity=0, phase=0, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
tft=TFT(spi,16,17,18)
tft.initr()
tft.rgb(True)

これのspiの設定以下の数行を以下のように変更します。

以下の変更例は、ESP32-SLIMのCN3にTFTディスプレイを接続した場合です。

from ST7735 import TFT
from sysfont import sysfont
from machine import SPI,Pin
import time
import math

spi = SPI(2, 20000000) # ESP32-SLIM用の設定
tft=TFT(spi,17,2,5)
tft.initb2()
tft.rgb(False)

上記の記述では、プログラムの全体像が分かりにくいかもしれませんので、graphicstest.pyを簡略化したようなデモプログラムを以下に示します。これも、ESP32-SLIM用となっています。

from st7735 import TFT
from sysfont import sysfont
from machine import SPI
import time

spi = SPI(2, 20000000) #ESP32-SLIMのCN3にTFTディスプレイを取り付けた場合の設定
tft=TFT(spi,17,2,5)

# 4つの初期化法から適切なものを選ぶ
tft.initb2() # V1.1?
# tft.initr()
# tft.initg() #V 2.1?
# tft.initb()

# 2つの色指定から適切なものを選ぶ
tft.rgb(False) # V1.1, V2.1?
# tft.rgb(True)

tft.fill(TFT.BLACK) # 画面のクリア
for y in range(0,128,8):
    tft.line((0,0),(127,y),TFT.WHITE) # 斜線

for x in range(127,0,-8):
    tft.line((0,0),(x,127),TFT.WHITE) # 斜線
time.sleep_ms(500)

tft.fill(TFT.BLACK) # 画面のクリア
for n in range(0,32,2):
    tft.rect((64-n*2,64-n*2),(n*4,n*4),TFT.RED) # 方形
time.sleep_ms(500)

tft.fill(TFT.BLACK) # 画面のクリア
for n in range(0,32,2):
    tft.fillrect((64-n*2,64-n*2),(n*4,n*4),TFT.GREEN) # 塗潰し方形
time.sleep_ms(500)

tft.fill(TFT.BLACK) # 画面のクリア
for n in range(2,64,4):
    tft.circle((64,64),n,TFT.YELLOW) # 楕円
time.sleep_ms(500)

tft.fill(TFT.BLACK) # 画面のクリア
for n in range(2,64,4):
    tft.fillcircle((64,64),n,TFT.CYAN) # 楕円
time.sleep_ms(500)

tft.fill(TFT.BLACK) # 画面のクリア
tft.text((0, 30), "1.44 or 1.8 INCH TFT DISPLAY, ST7735 Controler", TFT.WHITE, sysfont, 1)
tft.text((0, 65), "MicroPython", TFT.BLUE, sysfont, 2)
tft.text((20, 90), "MicroFan", TFT.YELLOW, sysfont, 2)

ST7735ドライバの利用上の注意

SPI端子の指定

SPIによるMCUとTFTディスプレイの通信で使用するMCUの端子は複数あり、SPI()コンストラクタと、TFT()コンストラクタの2つのコンストラクタへの指定で行います。

# spi = SPI(1, 20000000) # ESP32のHSPIのデフォルト利用
# spi = SPI(2, 20000000) # ESP32のVSPIのデフォルト利用
# spi = SPI(1, 20000000, sck=Pin(14), mosi=Pin(13), miso=Pin(12)) # ESP32のHSPIの明示的な端子指定

SPI()コンストラクタの引数は以下の通りです。

  • 第1引数: 使用するSPIのチャネル指定
  • 第2引数以降: 一般的には、第2引数に周波数を指定し、第3引数以降に必要に応じて、端子の指定や、信号の極性の指定などを行う。

各MCUでデフォルトのピンを使用するのであれば、チャネルと周波数だけを指定する方法で、デフォルトと異なる端子などを使用するのであれば、それを第3引数以降に指定します。

TFT()コンストラクタの引数は以下の通りです。

  • 第1引数: spi通信機能のインスタンス
  • 第2引数: TFTディスプレイのDC端子の制御端子
  • 第3引数: TFTディスプレイのリセット端子の制御端子
  • 第4引数: TFTディスプレイのCS端子の制御端子

ディスプレイの実装内容の差異

同じST7735を使用しているTFTディスプレイであっても、細かな実装方法が異なっており、実際に使用するために確認と調整が必要です。

現在私の手元にある1.44インチのTFTディスプレイは挙動の違いで2種類に分けられます。

適切に動くように設定するためには、以下の初期化メソッドや色指定方式の選択を行います。

初期化メソッドの選択

TFT()コンストラクタでTFTのインスタンスを生成したら、以下の4種類の初期化メソッドのうちの一つを選択して初期化します。

  • initr() 赤
  • initg() 緑
  • initb() 青
  • initb2() 青

初期化のメソッドがそのTFTディスプレイに合致していないと、画面表示ができなかったり、画面の周辺にノイズが乗ったり、画面の周辺部で表示した文字の端がかけたりします。

基本的には、TFTディスプレイの画面の保護シートに貼られているテープの色にあったものを選択するようにいわれています。実際には、初期化メソッドを一通り確かめて、問題なく動いているように見えるメソッドを使用するのがよいでしょう。

色指定方式の選択

上記の初期化メソッドの次に、以下のメソッドを使用して、色指定方式の選択を行います。指定が誤っていると、赤色と青色が入れ替わって表示されます。

  • rgb(True)
  • rgb(False)

これも、実際に2つの設定を切り替えて使ってみて、適切な色表示ができる方を選択するとよいでしょう。

初期化法の確認プログラム

上記の初期化法の確認と選択をするために、以下のプログラムを利用するとよいでしょう。このプログラムは、単純に、黒、白、赤、緑、青の順番で画面を塗潰していきます。初期化や色指定が適切でない場合には、画面の端にノイズや塗残しが現れたり、表示される赤と青の順番が入れ替わったりします。

from st7735 import TFT
from sysfont import sysfont
from machine import SPI,Pin
import time
import math

spi = SPI(2, 20000000) #ESP32-SLIMのCN3にTFTディスプレイを取り付けた場合の設定
tft=TFT(spi,17,2,5)

# 4つの初期化法から適切なものを選ぶ
tft.initb2() # V1.1?
# tft.initr()
# tft.initg() #V 2.1?
# tft.initb()

# 2つの色指定から適切なものを選ぶ
tft.rgb(False) # V1.1, V2.1?
# tft.rgb(True)

while True:
    tft.fill(TFT.BLACK)
    time.sleep_ms(1000)
    tft.fill(TFT.WHITE)
    time.sleep_ms(1000)
    tft.fill(TFT.RED)
    time.sleep_ms(1000)
    tft.fill(TFT.GREEN)
    time.sleep_ms(1000)
    tft.fill(TFT.BLUE)
    time.sleep_ms(1000)

initX()メソッドを変えると、適切な初期化メソッドではなかった場合に、画面の端が塗り変わらなかったりノイズが表示されたりします。

rgb()メソッドの引数を変えると、適切な指定ではなかった場合に、赤と青の表示順が入れ替わります。

現時点では、弊社に在庫があり販売している1.44インチのTFTディスプレイに関しては、基板の裏側にV1.1と記載されているものは、initb2()とrgb(False)の組み合わせ、V2.1と記載されているものは、initg()とrgb(False)の組み合わせで適切に表示されるようです。