前回は RaspberryPi pico に小型 TFT モジュールを接続して表示、MicroPython のライブラリを導入して描画してみました。このモジュールには SD スロットが付いてるので、SD カードから画像データを読み出して表示してみます。
SD カードインターフェース
SD カードにアクセスする方法として「SDモード」と「MMCモード」があります。「SPIモード」はクロック・Data IN・Data Outの3線で "SPI" デバイスとしてアクセスします。「MMCモード」はクロック・コマンド・データ(1~4本)を使ってアクセスします。
どちらもコマンドを送ってレスポンスを返す、を繰り返しますが、SPI モードは受信データ長の分だけ空データの送信を行う必要があるのに対して、MMCモードはコマンドとデータを別々に扱うため高速な通信ができます。また SPI モードは実行可能なコマンドに制限があります。
ILI9341 モジュールに付属の SD カードスロットは「SPI モード」としての端子が出ているので、これらを RaspberryPi pico の SPI 端子と接続します。SPI の場合、先の3線の他に CS (Chip Select) の制御も必要になります。
結線
前回の結線に加えて、SD カード側の端子を接続します。pico が master、モジュールが slave なので、SPI0_TX を SD_MOSI に(送信)、SPI0_RX を SD_MISO に(受信)、SPI0_SCK を SD_SCK に(クロック) 接続します。さらに SD_CS を空き GPIO の GP28 に接続しておきます。
ILI9341 | RaspberryPi pico | ||
1 | SD_CS | 34 | GP28 |
2 | SD_MOSI | 10 | GP7(SPI0_TX) |
3 | SD_MISO | 6 | GP4(SPI0_RX) |
4 | SD_SCK | 9 | GP6(SPI0_SCK) |
5 | F_CS | N/C |
SD_MISO (pico: GP4) は SD から pico への受信信号ですが、この信号は 10kΩ抵抗でプルアップしておきます。これをしておかないとデータを連続で受信できないことが多く失敗するため必要になります(送信信号はほぼ空データになるので不要です)。
SDCard ライブラリ
micropython のリポジトリから sdcard.py を導入します。
追記: micropython-lib に移動したようです。
画像ファイルの準備
ILI9341 の画像フォーマットは RGB 16bit(RGB565) big-endian ですが、用意する手段がなかなかないので windows bitmap (.bmp) ファイルを元に加工して使います。任意の画像ツールで以下を行います。
- 240x320 のサイズに加工
- 上下反転 (bmp フォーマットが反転しているため)
- RGB16bit で "BITMAP_rgb565.bmp" のファイル名で保存 (ファイル名は例)
以下の python スクリプトで bmp ファイルのヘッダを削除し、エンディアンを反転します。このスクリプトは pico ではなく PC 上で実行します。
import os,struct data = [] with open('BITMAP_rgb565.bmp', 'rb') as f: f.seek(0x8a, os.SEEK_SET) while True: word = f.read(2) if word: val = struct.unpack('<H', word)[0] data.append(struct.pack('>H', val)) else: break with open('BITMAP_rgb565_be.raw', 'wb') as f: f.writelines(data)
出来上がった "BITMAP_rgb565_be.raw" が ILI9341 でそのまま表示できるファイルになります。これを FAT32 でフォーマットした SD カードの "/sd" ディレクトリに保存します。
サンプルプログラム
SD から画像ファイルを読み込んで LCD に描画する main.py を作成します。
from machine import Pin, SPI import ili9341, os, sdcard spi = SPI(1, baudrate=51200000, sck=Pin(14), mosi=Pin(15)) display = ili9341.Display(spi, dc=Pin(18), cs=Pin(16), rst=Pin(17)) sd = sdcard.SDCard(SPI(0), cs=Pin(28)) os.mount(sd, '/sd') os.chdir('/sd') display.draw_image('BITMAP_rgb565_be.raw', 0, 0, 240, 320)
1~2行目はモジュールのインポートです。
4~5行目は SPI インスタンスの設定を行い、それを指定して ili9341 の Display 関数を呼び出して LCD 表示できるようにします。
ここまでは前回と同じです。
7行目は SD カードの初期化・インスタンスの生成を行います。SPI0 とGP28 を指定します。
8~9行目は os 関数で SD カードの "/sd" へのマウントを行い、"/sd" に移動します。これが正しく動作すれば、SD カード上のファイルにアクセスができます。
10行目は SD カード上にある画像ファイル "BITMAP_rgb565_be.raw" を指定して読込み、LCD 上に表示します。
実行
画像ファイルを保存した SD カードをスロットに入れて、USB で pico と PC を接続します。
pico への main.py のインストールは前回と同じで VSCode で行います。アップロード後に main.py が実行され、LCD 上に用意した画像が出れば成功です。
コメント