Arduino環境で扱える最大クラスのILI9486 4.0inch を紹介します。
RP2040 Raspberry Pi picoとESP32-S3でのSPI接続とグラフィック表示、JPG画像表示、タッチパネルを使ってみます。
今回紹介するもの
LCDモジュール (ILI9486) 4.0inch
特徴
Arduino環境で使用できる液晶カラーモニタとしては大型の4.0inch サイズです。
画面描画命令をSPIを使って高速な表示をします。
感圧式タッチパネルとSDカードスロットがついていて、電源とGNDは共通です。
CS以外のSPI通信線は共通の配線で使用することができます。
製品情報
サイズ | 4.0inch |
LCDドライバ | ILI9486 |
解像度(X, Y) | 480, 320 |
通信方式 | SPI |
動作電圧 | 3.3~5V |
タッチパネルドライバ | XPT2046 (HR2046と互換) |
タッチパネル分解能 | 4K x 4K |
その他 | SDカードリーダ |
外観
前面
背面
使用感
ILI9341 LCDと並べてみると倍以上のサイズです。
ピン配置も同じなので、ILIのLCDシリーズに慣れていれば作業はしやすいと思います。
感圧タッチパネルの分解能は縦横比が違いますが4K x 4Kです。
ILI9341と同じで±30程度のばらつきがあるので平均化処理などの工夫が必要です。
解像度も大きくなり、視野も広いのでゲーム画面にしても見やすいと思います。
タッチパネルを利用した操作盤として使用するときに複数のボタンを配置しても、窮屈さはだいぶん軽減されます。
小型サイズLCD ST7735はこちらで紹介しています。
中型サイズLCD ILI9341はこちらで紹介しています。
準備
ライブラリ
LCDとタッチパネルを制御するためのライブラリをインストールします。
SDカードリーダはArduinoIDEインストール時にインストールされています。
ライブラリ名 | 用途 | 検索 | 確認時バージョン |
---|---|---|---|
Adafruit GFX Library by Adafruit | グラフィック | GFX | 1.11.3 |
ILI9486_SPI by Jean-Marc Zingg | グラフィック | ILI9486 | 1.0.5 |
XPT2046_Touchscreen by Paul Stoffregen | タッチパネル | XPT2046 | 1.4 |
TJpg_Decoder by Bodmer | jpg表示 | jpg | 1.0.8 |
不足している依存関係のインストールの問い合わせがあれば「すべてをインストール」を選択してください。
使い方(LCD表示)
RP2040系 Raspberry Pi Pico(SPI0)でLCD表示
説明
サンプルとして文字列を表示します。
サンプルはテキストの表示のみです。
各マイコンでのSPIの設定方法について記述します。
そのほかの描画サンプルについては
スケッチ例 > ILI9486 > graphictest を参照してください。
RP2040系のSPIの設定方法についての参考にしてください。
配線
LCDのMISOは配線なしで動作します。
Raspberry Pi pico | 配線 | ILI9486 |
---|---|---|
3.3V | 赤 | VCC |
3.3V | 赤 | LED |
GND | 黒 | GND |
GPIO1(SPI0 CS) | 黄 | CS |
GPIO22 | 青 | Reset |
GPIO28 | 橙 | D/C |
GPIO3(SPI0 TX) | 緑 | SDI(MOSI) |
GPIO2(SPI0 SCK) | 紫 | SCK |
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/
【マイコン基板】
Raspberry Pi Pico
【スケッチの説明】
LCDのテスト表示を行います。
【ライブラリ】
Raspberry Pi Pico/RP2040 > Raspberry Pi Pico
Adafruit GFX Library
Adafruit ILI9486
【準備】
Raspberry Pi Pico <-> ILI9486
3.3V <-> VCC
GND <-> GND
GPIO17(SPI0 CS) <-> TFT CS
GPIO22 <-> TFT Reset
GPIO28 <-> TFT AO(D/C)
GPIO19(SPI0 MOSI) <-> TFT SDA
GPIO18(SPI0 SCK) <-> TFT SCK
3.3V <-> LED
【バージョン情報】
2023/2/14 : 新規
**********************************************************************/
#include <SPI.h>
#include <ILI9486_SPI.h>
#include <Adafruit_GFX.h>
//TFT SPIピン設定
#define TFT_CS 17
#define TFT_RST 22
#define TFT_DC 28
#define TFT_MOSI 19
#define TFT_SCK 18
#define ILI9486_BLACK 0x0000
#define ILI9486_WHITE 0xFFFF
#define ILI9486_RED 0xF800
#define ILI9486_GREEN 0x07E0
#define ILI9486_BLUE 0x001F
#define ILI9486_CYAN 0x07FF
#define ILI9486_MAGENTA 0xF81F
#define ILI9486_YELLOW 0xFFE0
#define ILI9486_ORANGE 0xFC00
ILI9486_SPI tft(TFT_CS, TFT_DC, TFT_RST);
void setup(void)
{
//SPIピン設定
SPI.setTX(TFT_MOSI);
SPI.setSCK(TFT_SCK);
//TFTの初期化と初期設定
tft.setSpiKludge(false); // false to disable rpi_spi16_mode
tft.init(); //Init ILI9486初期化
tft.fillScreen(ILI9486_BLACK); //背景の塗りつぶし
//テキスト表示
tft.setRotation(3); //画面回転
tft.setTextSize(7); //サイズ
tft.setCursor(0, 10); //カーソル位置
tft.setTextColor(ILI9486_GREEN); //緑
tft.printf("TAMANEGI\n\n");
tft.setTextSize(4); //サイズ
tft.setTextColor(ILI9486_RED); //赤
tft.printf("4.0inch LCD\n");
tft.setTextColor(ILI9486_YELLOW); //黄
tft.printf("Res=480 x 320\n");
tft.setTextColor(ILI9486_BLUE); //青
tft.printf("ILI9486\n");
}
void loop(void)
{
}
結果
LCDの表示ができました。
ESP32系 BananaPi picoW(VSPI)でLCD表示
説明
サンプルとして文字列を表示します。
サンプルはテキストの表示のみです。
各マイコンでのSPIの設定方法について記述します。
そのほかの描画サンプルについては
スケッチ例 > ILI9486 > graphictest を参照してください。
ESP32系のSPIの設定方法についての参考にしてください。
マイコン基板にはBananaPi picoW ESP32-S3を使用しています。
配線
LCDのMISOは配線なしで動作します。
Banana Pi picoW | 配線 | ILI9486 |
---|---|---|
3.3V | 赤 | VCC |
3.3V | 赤 | LED |
GND | 黒 | GND |
GPIO2 | 黄 | CS |
GPIO7 | 青 | Reset |
GPIO10 | 橙 | D/C |
GPIO4 | 緑 | SDI(MOSI) |
GPIO3 | 紫 | SCK |
Banana Pi picoWはRaspberry Pi picoと同サイズ基板で、電源、GNDは同じ位置にあります。
Raspberry Pi picoと同じピン位置になるよう配置しています。
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/
【マイコン基板】
Banana Pi PicoW
【スケッチの説明】
LCDのテスト表示を行います。
【ライブラリ】
esp32 > ESP32S3 Dev Module
Adafruit GFX Library
Adafruit ILI9486
【準備】
Raspberry Pi Pico <-> ILI9486
3.3V <-> VCC
GND <-> GND
GPIO2 <-> TFT CS
GPIO7 <-> TFT Reset
GPIO10 <-> TFT AO(D/C)
GPIO4 <-> TFT SDA
GPIO3 <-> TFT SCK
3.3V <-> LED
【バージョン情報】
2023/2/27 : 新規
**********************************************************************/
#include <SPI.h>
#include <ILI9486_SPI.h>
#include <Adafruit_GFX.h>
#define TFT_CS 2
#define TFT_RST 7
#define TFT_DC 10
#define TFT_MOSI 4
#define TFT_SCK 3
#define ILI9486_BLACK 0x0000
#define ILI9486_WHITE 0xFFFF
#define ILI9486_RED 0xF800
#define ILI9486_GREEN 0x07E0
#define ILI9486_BLUE 0x001F
#define ILI9486_CYAN 0x07FF
#define ILI9486_MAGENTA 0xF81F
#define ILI9486_YELLOW 0xFFE0
#define ILI9486_ORANGE 0xFC00
ILI9486_SPI tft(TFT_CS, TFT_DC, TFT_RST);
void setup(void)
{
//SPIピン設定
SPI.begin(TFT_SCK, -1, TFT_MOSI, TFT_CS);
//TFTの初期化と初期設定
tft.setSpiKludge(false); // false to disable rpi_spi16_mode
tft.init();
tft.fillScreen(ILI9486_BLACK); //背景の塗りつぶし
//テキスト表示
tft.setRotation(3); //画面回転
tft.setTextSize(7); //サイズ
tft.setCursor(0, 10); //カーソル位置
tft.setTextColor(ILI9486_GREEN); //緑
tft.printf("TAMANEGI\n\n");
tft.setTextSize(4); //サイズ
tft.setTextColor(ILI9486_RED); //赤
tft.printf("4.0inch LCD\n");
tft.setTextColor(ILI9486_YELLOW); //黄
tft.printf("Res=480 x 320\n");
tft.setTextColor(ILI9486_BLUE); //青
tft.printf("ILI9486\n");
}
void loop(void)
{
}
結果
LCDの表示ができました。
タッチパネル
説明
タッチパネルのタッチ状態と、タッチ座標を読み出して表示します。
使用したILI9486のタッチドライバはXPT2046が実装されていました。
ILI9341ではHR2046が実装されていて互換があります。
配線
画面の表示とタッチの読み取りはSPI0を共通で使用します。
タッチに使用するCSピンは画面とは別のCSピンを指定してください。
Raspberry Pi pico | 配線 | ILI9486 |
---|---|---|
3.3V | 赤 | VCC |
3.3V | 赤 | LED |
GND | 黒 | GND |
GPIO1(SPI0 CS) | 黄 | CS |
GPIO28 | 青 | Reset |
GPIO27 | 橙 | D/C |
GPIO3(SPI0 TX) | 緑 | SDI(MOSI) |
GPIO2(SPI0 SCK) | 紫 | SCK |
GPIO9 | 黄 | T_CS |
GPIO0(SPI0 MISO) | 茶 | T_OUT(MISO) |
GPIO2(SPI0 SCK) | 紫 | T_CLK |
GPIO3(SPI0 MOSI) | 緑 | T_DIN(MOSI) |
配線図ではTFT MISO 接続していますがなくても動作します。
[2023/6/2] MISO配線必要です。
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/
【マイコン基板】
Raspberry Pi Pico
【スケッチの説明】
タッチパネルを使用し、タッチ位置をLCD画面に表示します。
【ライブラリ】
Raspberry Pi Pico/RP2040 > Raspberry Pi Pico
Adafruit GFX Library
Adafruit ILI9486
XPT2046_Touchscreen
【準備】
<<LCD側>>
Raspberry Pi Pico <-> ILI9486
3.3V <-> VCC
GND <-> GND
GPIO17(SPI0 CS) <-> TFT CS
GPIO22 <-> TFT Reset
GPIO28 <-> TFT AO(D/C)
GPIO19(SPI0 MOSI) <-> TFT SDA
GPIO18(SPI0 SCK) <-> TFT SCK
3.3V <-> LED
<<Touch側>>
GPIO20 <-> T_CS
GPIO16(SPI0 MISO) <-> T_OUT(MISO)
GPIO18(SPI0 SCK) <-> T_CLK
GPIO19(SPI0 MOSI) <-> T_DIN(MOSI)
【バージョン情報】
2023/2/14 : 新規
**********************************************************************/
#include <SPI.h>
#include <ILI9486_SPI.h>
#include <Adafruit_GFX.h>
#include <XPT2046_Touchscreen.h>
//TFT SPIピン設定
#define TFT_CS 17
#define TFT_RST 22
#define TFT_DC 28
#define TFT_MOSI 19
#define TFT_SCK 18
#define ILI9486_BLACK 0x0000
#define ILI9486_WHITE 0xFFFF
#define ILI9486_RED 0xF800
#define ILI9486_GREEN 0x07E0
#define ILI9486_BLUE 0x001F
#define ILI9486_CYAN 0x07FF
#define ILI9486_MAGENTA 0xF81F
#define ILI9486_YELLOW 0xFFE0
#define ILI9486_ORANGE 0xFC00
#define COMMON_SCK 18
#define COMMON_MOSI 19
#define COMMON_MISO 16
#define TOUCH_CS 20
XPT2046_Touchscreen ts(TOUCH_CS);
ILI9486_SPI tft(TFT_CS, TFT_DC, TFT_RST);
void setup()
{
Serial.begin(115200);
//ESP SPI ピン設定
SPI.setTX(COMMON_MOSI);
SPI.setRX(COMMON_MISO);
SPI.setSCK(COMMON_SCK);
//TFTの初期化と初期設定
tft.setSpiKludge(false); // false to disable rpi_spi16_mode
tft.init(); //Init ILI9486初期化
tft.fillScreen(ILI9486_BLACK); //背景の塗りつぶし
tft.setRotation(3);
tft.setTextSize(2);
tft.fillScreen(ILI9486_BLACK);
//タッチ入力開始
ts.begin();
ts.setRotation(1);
}
void loop()
{
//タッチ状態読み取り
boolean bTouch = ts.touched();
//画面クリア
tft.fillRect(0, 0, 640, 100, ILI9486_BLACK);
//タッチがあればタッチされている座標の表示
if (bTouch == true)
{
TS_Point tPoint = ts.getPoint();
tft.setTextColor(ILI9486_WHITE);
tft.setCursor(0, 0);
tft.printf("(x,y) = (%d, %d)\r\n", tPoint.x, tPoint.y);
Serial.printf("(x,y) = (%d, %d)\r\n", tPoint.x, tPoint.y);
}
else
{
//タッチがなければタッチ無表示
tft.setTextColor(ILI9486_RED);
tft.setCursor(0, 0);
tft.print("No Touch");
}
delay(200);
}
結果
タッチの座標を読み出しました。
表示(SDカードからjpgファイルの表示)
説明
SDカードリーダよりjpgファイル”test.jpg”を読み取り、LCDに表示をします。
SDカードのルートフォルダには”test.jpg”ファイルを保存してください。
jpgファイルのサイズは480 x 320で作成します。
配線
RP2040系(Raspberry Pi Pico)を使用した配線を掲載します。
SPI0をLCDとSDカードリーダ共通で使用します。
LCDのSDカードリーダも使用することができます。
電源とGND以外をシルク記載のピンに接続します。
Raspberry Pi pico | 配線 | ILI9486 | 配線 | TFカードリーダ |
---|---|---|---|---|
3.3V | 赤 | VCC | 赤 | VCC |
GND | 黒 | GND | 黒 | GND |
GPIO17(SPI0 CS) | 黄 | TFT CS | ||
GPIO22 | 青 | TFT Reset | ||
GPIO28 | 橙 | TFT AO(D/C) | ||
GPIO19(SPI0 MOSI) | 緑 | TFT SDA | 緑 | MOSI |
GPIO18(SPI0 SCK) | 紫 | TFT SCK | 紫 | SCK |
3.3V | 赤 | LED | ||
GPIO21 | 黄 | SD CS | ||
GPIO16(SPI0 MISO) | 茶 | 茶 | MISO | |
GPIO20 | 黄 | 黄 | CS |
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/
【マイコン基板】
Raspberry Pi Pico
【スケッチの説明】
SDカードモジュールからtest.jpgを読み出しILI9486に表示します。
【ライブラリ】
Raspberry Pi Pico/RP2040 > Raspberry Pi Pico
Adafruit GFX Library
Adafruit ILI9486
TJpg_Decoder
【準備】
SDカードのルートフォルダに "test.jpg"を保存します。
jpgファイルのサイズは 480 x 320 サイズで保存します。
SPI0のMOSIとSCKは共通で使用します。
ILI9486に実装されているSDカードリーダ以外のモジュールを使用する場合、電源とGNDを配線します。
<<TFT側>>
Raspberry Pi Pico <-> ILI9486
3.3V <-> VCC
GND <-> GND
GPIO17(SPI0 CS) <-> TFT CS
GPIO22 <-> TFT Reset
GPIO28 <-> TFT AO(D/C)
GPIO19(SPI0 MOSI) <-> TFT SDA
GPIO18(SPI0 SCK) <-> TFT SCK
3.3V <-> LED
<<SDカードリーダ側>>
Raspberry Pi Pico <-> TFカードリーダ
3.3V <-> VCC
GND <-> GND
GPIO21 <-> SD CS
GPIO19(SPI0 MOSI) <-> SD MOSI
GPIO16(SPI0 MISO) <-> SD MISO
GPIO18(SPI0 SCK) <-> SD SCK
【バージョン情報】
2023/2/14 : 新規
**********************************************************************/
#include <SPI.h>
#include <SD.h>
#include <TJpg_Decoder.h>
#include <ILI9486_SPI.h>
#include <Adafruit_GFX.h>
//TFT SD共通ピン設定
#define COMMON_MOSI 19
#define COMMON_SCK 18
//TFTピン設定
#define TFT_CS 17
#define TFT_RST 22
#define TFT_DC 28
//SDピン設定
#define SD_CS 21
#define SD_MISO 16
#define FILENAME "/test.jpg"
#define BLACK 0x0000 //パレット 黒
#define WHITE 0xFFFF //パレット 白
// JPGの最大サイズ(バッファを静的に確保するようにしているため、決め打ち。取り扱う最大ファイルサイズで変えるようにする)
#define JPG_SIZE_MAX (100 * 1024) //MAX 100KByteを想定
ILI9486_SPI tft(TFT_CS, TFT_DC, TFT_RST);
struct jpg_file
{
size_t size;
uint8_t buf[JPG_SIZE_MAX];
};
jpg_file jpg;
//デコードを行うコールバック関数
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *bitmap)
{
if (y >= tft.height())
return 0;
tft.drawRGBBitmap(x, y, bitmap, w, h);
return 1;
}
void setup()
{
//SPIピン設定
SPI.setTX(COMMON_MOSI);
SPI.setRX(SD_MISO);
SPI.setSCK(COMMON_SCK);
//TFTの初期化と初期設定
tft.setSpiKludge(false); // false to disable rpi_spi16_mode
tft.init(); //Init ILI9486初期化
tft.fillScreen(BLACK); //背景の塗りつぶし
tft.setRotation(3);
Serial.begin(115200);
//while(!Serial);
delay(1000);
//SDカードリーダの初期化とファイルの読み取り
if (!SD.begin(SD_CS, SD_SCK_MHZ(8)))
{
Serial.println("SD initialization failed!");
while(1);
}
TJpgDec.setCallback(tft_output);
File jpgFile = SD.open(FILENAME, FILE_READ);
if (!jpgFile)
{
Serial.printf("Open file failed [%s]\r\n", FILENAME);
while(1);
}
jpg.size = jpgFile.size();
if(sizeof(jpg.buf) < jpg.size)
{
Serial.println("File size over");
return;
}
//ファイル情報の表示
uint16_t w = 0, h = 0;
Serial.printf("file size = %d bytes\r\n", jpgFile.readBytes((char *)jpg.buf, jpg.size));
TJpgDec.getJpgSize(&w, &h, jpg.buf, jpg.size);
Serial.printf("Width = %d, height = %d\r\n", w, h);
TJpgDec.setJpgScale(1);
TJpgDec.drawJpg(0, 0, jpg.buf, jpg.size); //画像の表示
jpgFile.close();
}
void loop()
{
}
結果
SDカード内のjpgファイルの表示をしました。
こちらではSDカードのファイルリストの作成 を紹介しています。
組み合わせて使用することでフォトフレームなどを作ることができます。
コメント
たまねぎさん 初めまして、
aruduino環境でLCDモジュールを使う(ILI9486)を拝見してコメント欄を拝借してメールしいます。
さて、今弊社ではILI9486を表示ツールにしてESP32を使った制御盤を開発しようと思い表示テストを試みています。たまねぎさんのこのブログを参考にESP32系LCD制御スケッチを動かしてみましたがコンパイルはうまく行きますが何も表示されないような状態です。ピンアサインは変更しています。
ご多忙とは思いますが、もしよろしかったら何かアドバイス又はご指導を頂けないでしょうか?
有償でも結構ですのでよろしくお願いします。
#define TFT_CS 2 → 5
#define TFT_RST 7 → 4
#define TFT_DC 10 → 17
#define TFT_MOSI 4 → 23
#define TFT_SCK 3 → 18
こんにちは。
指定されたピン設定を使用し、当方では動作しましたのでピンの選択に間違いはありません。
使用した基板はESP32-WROOM NODE-MCUで試しています。
過去の経験を列挙します。
・LCD自体の個別不良で表示されなかったことがある。>他のLCDモジュールで試してみる。
・ESP32の起動電圧不足。>電源供給がUSBハブの場合ACアダプタ付きのものを使う。
・ピンの差し間違い、または端子の接触不良。>よく確認する。
他にもESP32のボードライブラリバージョンによっては動作しないことがあるので、バージョンの変更をしてみてはいかがでしょうか?
今回使用したバージョン情報は以下です。
・ILI9486_SPI by Jean-Marc Zingg : 1.0.5
・Adafruit GFX Library by Adafruit : 1.11.9
・esp32 by Espressif Systems : 2.0.17