Aliexpressで買える安くて小さい液晶(ST7789搭載)の使い方(Raspberry Pi編)

Aliexpressを見ているとよく安くて小さい液晶が売られています。


0.96/1.14/1.28/1.3/1.54/1.69/1.9/2.0 inch IPS TFT LCD OLED Display Module for ardunio raspberry pi stm

こういうのです。
Amazonでも似たようなのが1400円くらいで売られてますが、Aliexpressだと600円ほど(2インチの場合)なので激安です。
でもマニュアルもついてなさそうだし、どうやって使うんでしょうね。
……と思っていたところ仕事で使うことになり、いくつか注文……のついでに気になって自分用にも追加注文しまいました。

左が2.0インチ、右が1.54インチです。

↑2.0インチ。解像度は240x320ピクセル。袋に書いてある型番はMSP2008です。

↑1.54インチ。解像度は240x240ピクセル。袋に書いてある型番はMSP1541です。

液晶の種類はIPS液晶です。いずれもST7789というコントローラを搭載、通信方式はSPIです。

わりとよく見る部品ではあるので、WEB上にすでに解説記事がたくさんある……と思うじゃないですか。近いものがあるにはあるのですが、ピン構成が違ったり使われてるライブラリがこの部品に対応していなかったりして意外にそのまま適用できなかったので、動かすまでちょっと時間がかかりました。備忘録も兼ねてやり方を残しておくので、類似の部品を買った方は参考にしてください。

本記事の対象の液晶モジュールの条件

  • ピンが8本出ているもの(GND、VCC、SCL、SDA、RES、DC、CS、BLK)
  • コントローラーがST7789である
  • SPI通信で制御する

Raspberry Pi で動かす

まずRaspberry Piから表示してみます。このディスプレイにいろいろ表示して遊びたいなーという場合は、気軽に画像ファイルなどを扱えるのでRaspberry Piを使うのがいちばんいいと思います。
他のマイコンはこちらを見てください→Raspberry Pi編(この記事) / Arduino編 / Raspberry Pi Pico編

ターミナルかSSHで操作します。

Raspberry PiのSPI通信を有効にする

SPIっていうのは液状に信号を送る際の通信方式ですね。
デフォルトだとこの機能が使えないようになっているので、有効化します。

sudo raspi-config

Interfacing Options → SPI → Yes の順にEnterを押していって決定します。
終わったら再起動。

sudo reboot

再起動は要らない説もありますが一応やっときました。

ライブラリを入れる

次にpython用のライブラリ類をインストールします。

sudo apt-get install python3-rpi.gpio python3-spidev python3-pip python3-pil python3-numpy

次にディスプレイ用ライブラリのインストールです。ここでいろいろ試して時間を取られました。
結局adafruitのがよさそう。

sudo pip3 install adafruit-circuitpython-rgb-display

これはCircuitPython(マイコン用のPython系言語)のライブラリのようなのですが、Pythonからも使うことができます。

インストール時、たまたまかもしれませんが、ネットワークが不安定なのか「socket.timeout: The read operation timed out」というエラーで止まることがありました。3回目くらいで成功。
ここまでで環境構築は終了です。

モジュールを接続する

液晶モジュールにはこんな感じでピンが8本あるので、それぞれしかるべきGPIOピンにつないでいきます。

GPIOピン番号 ピン名 液晶側ピン 用途
17 3.3V VIN,VCC 電源
19 SPI0_MOSI SDA,SDA SPI信号用
23 SPI0_SCLK SCL,SCK,SCLK SPIクロック
25 GND GND GND
28 GPIO1 CS 通信先選択
29 GPIO5 RES,RST リセット
31 GPIO6 DC データ/コマンド切替
33 GPIO13 BLK バックライト

液晶側ピンは製品によって表記ゆれがありそうなので、よくあるのを全部書いておきました。
下から4つは任意のGPIOピンに変更しても大丈夫です。(あとでプログラムのほうも変更する必要があります)
バックライトは制御しないのであれば省略可能です。(省略時点灯)

余談ですが僕はRaspberry PiのGPIOピンの番号の数え方がいつもわからなくなります。本体をGPIOピンが右上にくるように縦向きに置いて、一番上の行が左から1,2、二行目が3,4、三行目が4,5…という感じです。

https://www.raspberrypi.com/documentation/computers/raspberry-pi.html より

で、つなぐとこうなります。


動作テスト

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

Adafruit_CircuitPython_RGB_Display/examples/rgb_display_simpletest.py at main · adafruit/Adafruit_CircuitPython_RGB_Display · GitHub

gitを使って落としてもいいですが、エディタ上に直接コピペしてもいいです。

nano rgb_display_simpletest.py

保存する前に、ピン番号を今回接続したものに書き換えておきます。

# Configuratoin for CS and DC pins (these are FeatherWing defaults on M0/M4):
cs_pin = digitalio.DigitalInOut(board.D1)
dc_pin = digitalio.DigitalInOut(board.D6)
reset_pin = digitalio.DigitalInOut(board.D5)

バックライトのピンが書いてませんが、これはライブラリ通さずに普通にHIGHにしたりLOWにしたりすればいいっぽいです。よくわからない場合は何もしなかったら点灯します。

保存したら、実行しましょう。

python3 rgb_display_simpletest.py

画面がビロロビロロってなったら(いやちょっと言葉で表現しにくいのですがビロロビロロってなります)成功です。

画像を読み込む

せっかくなのでjpgを読み込んでみます。
液晶解像度より大きいサイズの画像はエラーになります。ちょうど240px * 320pxのテスト用を用意しました。DLしてください。


wget -O 240x320.jpg https://cdn-ak.f.st-hatena.com/images/fotolife/s/slideglide/20240424/20240424111329.jpg

240*240の場合はこちらをどうぞ。

wget -O 240x240.jpg https://cdn-ak.f.st-hatena.com/images/fotolife/s/slideglide/20240424/20240424111332.jpg

pythonコードはこちら。

import digitalio
import board

from adafruit_rgb_display import st7789
from PIL import Image, ImageDraw, ImageOps

# Configuratoin for CS and DC pins (these are FeatherWing defaults on M0/M4):
cs_pin = digitalio.DigitalInOut(board.D1)
dc_pin = digitalio.DigitalInOut(board.D6)
reset_pin = digitalio.DigitalInOut(board.D5)

# Config for display baudrate (default max is 24mhz):
BAUDRATE = 24000000

# Setup SPI bus using hardware SPI:
spi = board.SPI()

# Create the ST7789 display:
display = st7789.ST7789(spi, cs=cs_pin, dc=dc_pin, rst=reset_pin, baudrate=BAUDRATE)

# Clear the display
display.fill(0)

# Display image
image = Image.open("240x320.jpg")
display.image(image)

240*240の場合はファイル名を書き換えてください。

で、適当なファイル名で保存して実行すると…

エイが出ました!

ちなみに小さい画像だと下に寄って表示されます。

他にもこのライブラリは座標を90度回転させて横長のディスプレイとして使用できたりとかいろいろ機能があるみたいです。
サンプルコードはここにたくさんあるのでいろいろ試してみてください。
Adafruit_CircuitPython_RGB_Display/examples at main · adafruit/Adafruit_CircuitPython_RGB_Display · GitHub

2つつないで2画面にする

他サイトの記事を見ているとCSピンがないバージョンの液晶モジュールもあるようなのですが、今回紹介したものにはついています。
これは何に使うかというと、2つ以上のモジュールと同時にSPI通信するときに使います。
ということはこの製品なら簡単に2画面を扱うことができるわけです。

つなぎ方としては例えばこんな感じ。

GPIOピン番号 ピン名 液晶側ピン 用途
17 3.3V (液晶1&2)VIN,VCC 電源
19 SPI0_MOSI (液晶1&2)SDA,SDA SPI信号用
23 SPI0_SCLK (液晶1&2)SCL,SCK,SCLK SPIクロック
25 GND (液晶1&2)GND GND
28 GPIO1 (液晶1)CS 通信先選択
29 GPIO5 (液晶1)RES,RST リセット
31 GPIO6 (液晶1)DC データ/コマンド切替
28 GPIO4 (液晶2)CS 通信先選択
29 GPIO17 (液晶2)RES,RST リセット
31 GPIO12 (液晶2)DC データ/コマンド切替

上から4つはブレッドボード等を使って分岐させて、両方の液晶に接続してください。

pythonコードの例です。

import digitalio
import board

from adafruit_rgb_display import st7789
from PIL import Image, ImageDraw, ImageOps

# Configuratoin for CS and DC pins (these are FeatherWing defaults on M0/M4):
cs_pin1 = digitalio.DigitalInOut(board.D1)
dc_pin1 = digitalio.DigitalInOut(board.D6)
reset_pin1 = digitalio.DigitalInOut(board.D5)
cs_pin2 = digitalio.DigitalInOut(board.D4)
dc_pin2 = digitalio.DigitalInOut(board.D12)
reset_pin2 = digitalio.DigitalInOut(board.D17)

# Config for display baudrate (default max is 24mhz):
BAUDRATE = 24000000

# Setup SPI bus using hardware SPI:
spi = board.SPI()

# Create the ST7789 display:
display1 = st7789.ST7789(spi, cs=cs_pin1, dc=dc_pin1, rst=reset_pin1, baudrate=BAUDRATE)
display2 = st7789.ST7789(spi, cs=cs_pin2, dc=dc_pin2, rst=reset_pin2, baudrate=BAUDRATE)

# Clear the display
display1.fill(0)
display2.fill(0)

# Display image
image1 = Image.open("240x320.jpg")
display1.image(image1)
image2 = Image.open("240x320.jpg")
display2.image(image2)

ちなみにRaspberry PiにはSPIピンが2系統あって、設定で有効にすることができます。
ただ上記のように1系統で2画面を使用できるので、有効にする必要はありません。へー。

以上です。
安くて小さい液晶で楽しいディスプレイライフをお過ごしください。