中国のお店が中国国外に売る通販モールAliExpressで小型液晶ディスプレイを買いました。
サイズは2.4インチ、解像度は320x240px(QVGA)、65万色対応だそうです。液晶コントローラとしてILI9341というLSIが搭載されており、SPIで制御できます。
小型でちょっとした情報を表示するのに便利そうですね🥰
おそらく、Amazon.co.jpで売られているこちらのものと類似品だと思います。画面サイズが微妙に違いますが、ピン配置や解像度は同じで、同じように使えるものだと思います。
AliExpressでの私が購入時の値段は、なんと$6.94でした!1000円しないのでお買い得ですね。
このディスプレイもPythonから簡単にアクセスできるライブラリを公開されている方がいて、ドライバを書かずとも簡単に好きなものが表示できます。 とても便利ですね🥰早速Raspberry Piにつないでみましょう。
Raspberry Piに接続
購入した小型液晶ディスプレイ
こんなものが届きました。画面についていた保護シールははがしています。 ピンヘッダも搭載されていて、はんだ付けなしでジャンパワイヤーなどを使って簡単にRaspberry Piに接続できます。
裏面はこのようになっています。なぜかSDカードスロットがついています。写真右側の4つのスルーホールにピンヘッダをはんだ付けすると、SDカードにもアクセスできます。何のためについているんでしょうね🤔
今回は液晶だけ使うので、SDカードスロットは無視します。
左側の黄色いピンヘッダですが、上5本のT_***
というピンはタッチパネル制御のためのピンです。私が購入したのはタッチパネルなしモデルなので使いません。同じシリーズにタッチパネルつきのモデルもあり、それらはこのピンが使えます。
Raspberry Piにつないでみよう
Raspberry Piのピンヘッダは上図のように機能が割り当てられています。 このモジュールはSPIで通信しますが、そのほかにも制御線をつなぐ必要があります。 SPI以外はどのGPIOでも良い(Pythonプログラムで指定可)のですが、以下のようにしてみました。
RasPiピン番号 | RasPi 機能 | 液晶ディスプレイ | 説明 |
---|---|---|---|
1 | 3V3 power | LED | LEDバックライトON/OFF |
17 | 3V3 power | VCC | 電源(3.3V) |
18 | GPIO24 | RESET | 液晶リセット信号 |
19 | MOSI | SDI(MOSI) | SPIデータ(Raspi→液晶) |
21 | MISO | SDO(MISO) | SPIデータ(液晶→Raspi) |
22 | GPIO25 | DC | 液晶データ・コマンド選択 |
23 | SCLK | SCK | SPIクロック |
24 | CS | GPIO8 | SPIチップセレクト |
25 | GND | GND | グランド(基準電圧0V) |
バックライトON/OFF信号はHIGHでONになるようです。GPIOで制御しても良いですが、今回は3.3Vに接続して常時ONとしました。
これらをジャンプワイヤーで接続すると、次のようになりました。
Raspberry Piの準備
SPIの有効化
Raspberry Pi OSのインストール直後はSPIが無効になっていて、そのままでは使えません🙅♀️
有効化するには、raspi-config
のメニューから設定できます。
$ sudo raspi-config
で設定画面を起動し、"5 Interfacing Options" → "P4 SPI" → "Yes" を選択してください。
Pythonで表示させてみよう
Pythonライブラリーのインストール
アメリカのオープンソースハードウェアベンダーのAdafruitがPythonライブラリを開発しています。
このライブラリは今回の液晶に搭載されているILI9341という液晶コントローラLSIの他に、ST7789など複数の液晶コントローラLSIに対応しています。SPIで制御できる液晶画面を幅広くサポートしていて便利です☺️
過去記事で紹介したST7789搭載液晶画面でもこのライブラリが使えます。
早速インストールしてみましょう。インストールは次のようにします。
$ sudo apt-get install python3-rpi.gpio python3-spidev python3-pip python3-pil python3-numpy $ pip3 install adafruit-circuitpython-rgb-display
依存ライブラリをaptでインストールして、最後にpip3でこのライブラリをインストールします。 2021年8月現在、numpyやPillow (PIL)はaptから入れた方がいいみたいです。
基本的な使い方
早速ですが、いちばん基本的なサンプルプログラムを載せます。
from adafruit_rgb_display.rgb import color565 from adafruit_rgb_display.ili9341 import ILI9341 from busio import SPI from digitalio import DigitalInOut import board # Pin Configuration cs_pin = DigitalInOut(board.D8) dc_pin = DigitalInOut(board.D25) rst_pin = DigitalInOut(board.D24) # Set up SPI bus spi = SPI(clock=board.SCK, MOSI=board.MOSI, MISO=board.MISO) # Create the ILI9341 display: display = ILI9341( spi, cs=cs_pin, dc=dc_pin, rst=rst_pin, width=240, height=320, rotation=90, baudrate=24000000 ) # Define color COLOR_ORANGE = color565((245, 124, 0)) # Fill display with one color display.fill(COLOR_ORANGE)
このプログラムを実行すると、画面がオレンジ色で塗りつぶされます。
簡単にプログラムの中を見ていきましょう。
spi = SPI(clock=board.SCK, MOSI=board.MOSI, MISO=board.MISO)
この部分でSPIバスの設定をします。Raspberry PiのピンヘッダはSPIバスは1つだけなので、この通りにすれば大丈夫です。
display = ILI9341( spi, cs=cs_pin, dc=dc_pin, rst=rst_pin, width=240, height=320, rotation=90, baudrate=24000000 )
続いて、この部分でILI9341コントローラのディスプレイインスタンスを作成します。引数がたくさんありますね。 第1引数で先ほど作成したSPIバスのインスタンスを指定します。
続いてcs
、dc
、rst
という引数でチップセレクト(CS)、データ制御(DC)、リセット(RST)ピンを指定します。
これらはDigitalInOutのインスタンスでDigitalInOut(board.D8)
のように指定します。D8というのはRaspberry PiのGPIO8を表しています。
GPIOはどのピンでも良いので、自分の接続に合わせて指定してください。
さらにwidth
、height
で液晶画面の解像度を指定します。実はこの液晶は240x320pxの縦長が本来の姿なので、このように指定します。
横長にして使いたいときは、rotation=90
とすると90度回転で表示できます(180、270も指定可)。
rotationを指定しなければ240x320pxの縦長のままとなります。今回は横長で使用します。
最後にbaudrate
でSPIのクロックレートを指定します。この液晶の場合、24MHzまで使えるようです、
私の場合はこれで問題なく表示できました。
いろいろ表示させてみよう
せっかくなので、いろんなものを表示させてみましょう。 Pillowを使って描画できれば、何でも表示できます。
画像の表示
やっぱり液晶があると、美しい画像を表示させたいですね。 このライブラリはPythonの画像処理ライブラリとして有名なPillow (PIL)と連携して、Pillowで作成した画像を表示できます。
試しに、ネットにある美しい画像を拾ってきましょう。
$ wget https://cdn-ak.f.st-hatena.com/images/fotolife/k/kimura_khs/20210110/20210110170457.jpg
次のようにして簡単に表示させられます。
from adafruit_rgb_display.rgb import color565 from adafruit_rgb_display.ili9341 import ILI9341 from busio import SPI from digitalio import DigitalInOut import board from PIL import Image, ImageDraw # Pin Configuration cs_pin = DigitalInOut(board.D8) dc_pin = DigitalInOut(board.D25) rst_pin = DigitalInOut(board.D24) # Set up SPI bus spi = SPI(clock=board.SCK, MOSI=board.MOSI, MISO=board.MISO) # Create the ILI9341 display: disp = ILI9341( spi, cs=cs_pin, dc=dc_pin, rst=rst_pin, width=240, height=320, rotation=90, baudrate=24000000 ) # Define image size (320x240, rotated) IMAGE_SIZE = (disp.height, disp.width) # Open image image = Image.open("20210110170457.jpg") # Resize to screen size image = image.resize(IMAGE_SIZE, resample=Image.LANCZOS) # Display image disp.image(image)
disp
インスタンス作成までは先ほどと全く同じです。
その後、Pillowの機能を使って画像を開き、画面サイズにあわせてリサイズしています。
注意点としては、90度回転を指定して液晶を横長で使っているので、Pillowの画像も320x240pxで作成します。
最後にdisp.image()
でPillowの画像が表示できます。
これをファイルに保存し、実行すると次のようになりました。
奈良にある東大寺 二月堂【国宝】の写真が映し出されました。
ちなみに、この写真は私が撮影した写真です😆
文字の表示
Pillowがあれば、OpenType/TrueTypeフォントで文字も書けます。 フォントをダウンロードしてみましょう。
$ sudo apt install fonts-noto-cjk fonts-roboto
プログラムは以下のようになります。
from adafruit_rgb_display.rgb import color565 from adafruit_rgb_display.ili9341 import ILI9341 from busio import SPI from digitalio import DigitalInOut import board from PIL import Image, ImageDraw, ImageFont # Pin Configuration cs_pin = DigitalInOut(board.D8) dc_pin = DigitalInOut(board.D25) rst_pin = DigitalInOut(board.D24) # Set up SPI bus spi = SPI(clock=board.SCK, MOSI=board.MOSI, MISO=board.MISO) # Create the ILI9341 display: disp = ILI9341( spi, cs=cs_pin, dc=dc_pin, rst=rst_pin, width=240, height=320, rotation=90, baudrate=24000000 ) # Define image size (320x240, rotated) IMAGE_SIZE = (disp.height, disp.width) # Define fonts FONT_ROBOTO = ImageFont.truetype("Roboto-Medium.ttf", 12) FONT_NOTO = ImageFont.truetype("NotoSansCJK-Regular.ttc", 18) FONT_NOTO_SMALL = ImageFont.truetype("NotoSansCJK-Regular.ttc", 12) # Define colors COLOR_WHITE = (236, 239, 241) COLOR_PURPLE = (239, 154, 154) # Create an image with black background image = Image.new("RGB", IMAGE_SIZE, (0, 0, 0)) # Draw some text draw = ImageDraw.Draw(image) text = """\ 祇園精舎の鐘の声 諸行無常の響きあり 沙羅双樹の花の色 盛者必衰の理をあらはす 奢れる人も久からず ただ春の夜の夢のごとし 猛き者も遂には滅びぬ 偏に風の前の塵におなじ """ for i, line in enumerate(text.split("\n")): draw.text((0, 24*i), line, font=FONT_NOTO, fill=COLOR_WHITE) draw.text((200, 185), "「平家物語」冒頭より", font=FONT_NOTO_SMALL, fill=COLOR_WHITE) draw.text((40, 200), "みかんのゆるふわ技術ブログ", font=FONT_NOTO, fill=COLOR_PURPLE) draw.text((100, 222), "www.mikan-tech.net", font=FONT_ROBOTO, fill=COLOR_PURPLE) # Show it on display disp.image(image)
これを実行すると、次のようになります。
これで、文字も表示できるようになりました。 QVGAなので近づいてみると多少ギザギザが見えて今時のスマホに少し劣りますが、12ptのフォントでも視認性は十分です👌
文字や画像を組み合わせて、ちょっとした情報をカッコよく表示できるので、皆様もぜひDIYなどにお使いください!