ILI9341ディスプレイを使ってみる[Adafruit GFX Library編]
だいぶ前に買って放置されてた小型液晶ディスプレイで遊びました。
秋月で1500円くらいです。
https://akizukidenshi.com/catalog/g/g116265/
概要
- 2.8インチ
- 320x240 (4:3)
- フルカラー
- タッチパネル
- SPIインターフェース
- SDカードスロット
1500円とは思えないほど豪華ですね。
同じような商品が様々なところで販売されてますが、ものによっては一部部品が未実装でタッチパネルが使えないものもあるようです。
自分が秋月で買ったものには実装されていました。が、今回は画面表示のみでタッチパネルはまたいつか。
動かしてみる
Note
前提
Arduino IDE v2
Raspberry Pi Pico
今回はラズピコ&Arduino環境で動かします。
ピンを変えれば他のボードでも動くとはおもいますが、ロジックの電圧が3.3VなのでArduino UNOで使う場合はレベルシフトが必要です。
使用するライブラリはAdafruit_ILI9341です。ライブラリマネージャでAdafruit ILI9341と検索すると出てくるのでインストールしといてください。
公式チュートリアル:
https://learn.adafruit.com/adafruit-gfx-graphics-library
配線
配線が多くて見づらいので図にしました。

写真のようにPicoのピンを片方だけ刺すと一枚のブレッドボードで配線できます。
愚痴にはなりますが、この製品ピン名がなぜか裏面にしか書かれていないのでブレッドボードに刺すとピン配置がわからなくなるんですよね。どう見ても表にも記載できる空間はあるんですけど。
hello world!
テキストを表示する最小限のプログラムです。
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#define MISO 16
#define CS 17
#define SCK 18
#define MOSI 19
#define DC 20
#define RST 21
Adafruit_ILI9341 tft = Adafruit_ILI9341(CS, DC, MOSI, SCK, RST, MISO);
void setup() {
tft.begin();
tft.printf("hello world!");
}
void loop() {}

無事にhello world!と表示されました。
見えませんか?拡大してみましょう。

ちっさ
文字修飾
さすがに小さすぎるので大きくしましょう。他にも色やフォントなどが変更できます。
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <Fonts/FreeSerif12pt7b.h> // フォント読み込み
#define MISO 16
#define CS 17
#define SCK 18
#define MOSI 19
#define DC 20
#define RST 21
Adafruit_ILI9341 tft = Adafruit_ILI9341(CS, DC, MOSI, SCK, RST, MISO);
void setup() {
tft.begin();
tft.fillScreen(ILI9341_WHITE); // 塗りつぶし
tft.setRotation(3); // 画面の向き
tft.setTextSize(2); // 文字サイズ
tft.setTextColor(ILI9341_RED); // 文字色
tft.println("ILI9341 display &");
tft.printf("Adafruit GFX Library");
tft.setCursor(60, 120); // カーソル移動
tft.setFont(&FreeSerif12pt7b); // フォント設定
tft.setTextColor(0x03EF); // R:5bit G:6bit B:5bit
tft.printf("moris.day");
}
void loop() {}

Note
標準のフォントでは日本語は表示できません。
図形描画
もちろん図形描画もできます。
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#define MISO 16
#define CS 17
#define SCK 18
#define MOSI 19
#define DC 20
#define RST 21
Adafruit_ILI9341 tft = Adafruit_ILI9341(CS, DC, MOSI, SCK, RST, MISO);
void setup() {
tft.begin();
tft.fillScreen(ILI9341_WHITE);
// 四角形
tft.drawRect(50, 50, 50, 50, ILI9341_RED); // 左上x, 左上y, width, height
tft.fillRect(150, 180, 60, 80, ILI9341_BLUE);
// 円
tft.drawCircle(125, 250, 50, ILI9341_GREEN); // 中心x, 中心y, 半径, 色
tft.fillCircle(80, 150, 40, ILI9341_YELLOW);
// 三角形
tft.drawTriangle(70,70, 80,10, 140,80, ILI9341_MAGENTA); // 三点のx,y座標を順に指定,最後に色
tft.fillTriangle(230,120, 150,70, 170,140, ILI9341_CYAN);
}
void loop() {}

かなり写りが悪いですが実際はもっと綺麗に見えます。
画像表示
SDカードスロットが付いているので実行時にSDカードから読み込むこともできますが、多少めんどくさいのでとりあえずヘッダーファイルに配列として置いておく方法で表示します。
(この方法では画像1枚で100kB以上消費するのでArduino UNOとかでは動きません。)
ヘッダーファイルはimage2cppというツールで生成します。
https://javl.github.io/image2cpp/
使い方
- 変換したい画像をアップロード
- デフォルトが白黒になっているので、下にスクロールして
Draw modeをHorizontal - 2 bytes per pixel (565)にします - サイズを320x240にして配置などを調整
Generate codeを押すと配列が生成されるのでコピー
これをArduinoファイルと同じフォルダに.hファイルとして保存
一応、自分が使ったヘッダーファイルも置いておきます。
👉 Download Picture.h
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include "Picture.h" // image2cppで生成したファイル
#define MISO 16
#define CS 17
#define SCK 18
#define MOSI 19
#define DC 20
#define RST 21
Adafruit_ILI9341 tft = Adafruit_ILI9341(CS, DC, MOSI, SCK, RST, MISO);
void setup() {
tft.begin();
tft.setRotation(3);
tft.drawRGBBitmap(0, 0, IMG_0381, 320, 240); // x, y, 画像の配列, width, height
}
void loop() {}

画像を表示して気づいたのですがこのディスプレイ、視野角がとんでもなく狭くて本当に真正面から見ないと色味が酷いことになります。画質にはあまり期待しないようにしましょう。
メモ: サムネイルのコード
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <Fonts/FreeSerif24pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include "blobcat_coffee.h" // https://moris.day/files/blog/ili9341-with-adafruit-gfx-library/blobcat_coffee.h
#define MISO 16
#define CS 17
#define SCK 18
#define MOSI 19
#define DC 20
#define RST 21
Adafruit_ILI9341 tft = Adafruit_ILI9341(CS, DC, MOSI, SCK, RST, MISO);
void setup() {
tft.begin();
tft.fillScreen(ILI9341_WHITE);
tft.setRotation(3);
tft.fillRect(10, 10, 300, 220, 0x03EF);
tft.fillRect(15, 15, 290, 210, ILI9341_WHITE);
tft.setTextColor(ILI9341_BLACK);
tft.setFont(&FreeMonoBold12pt7b);
tft.setCursor(20, 35);
tft.println("ILI9341 display &");
tft.setCursor(20, 60);
tft.printf("Adafruit GFX Library");
tft.setCursor(72, 125);
tft.setFont(&FreeSerif24pt7b);
tft.setTextColor(0x03EF);
tft.printf("moris.day");
tft.drawRGBBitmap(220, 150, blobcat_coffee, 64, 64);
}
void loop() {}