はじめに
ESP32-S3で170x320の1.9インチIPSカラーLCDを、TFT_eSPIライブラリを使って8ビットパラレル接続したので、ピンアサインとサンプルスケッチ変更点をまとめておく(備忘録)。
使用機材
主なパーツ | 購入先 | (購入時点) 税込価格 |
---|---|---|
ESP32-S3-WROOM-1-N16R8 | 秋月電子通商 | 530円 |
ESP32S3用開発ボード(部品+PCB) | 74th@Booth | 700円 |
1.9インチTFT液晶ディスプレイ | AliExpress | 581円 |
FFC変換基板(30P) | aitendo | 650円 |

LCDとESP32s3のピン接続
LCDとESP32s3の接続はLILYGO® T-Display-S3
に倣って、以下のアサインとした。
LCD FFC# | PIN | ESP32s3 GPIO | LCD FFC# | PIN | ESP32s3 GPIO | |
---|---|---|---|---|---|---|
1 | GND | GND | 16 | DB5 | 46 | |
2 | VDD | 15 (3V3) | 17 | DB6 | 47 | |
3 | IM2 | GND | 18 | DB7 | 48 | |
4 | IM1 | GND | 19 | SDO | - | |
5 | RES | 5 | 20 | LEDA | 38 (3V3) | |
6 | CS | 6 | 21 | LEDK | GND | |
7 | DC | 7 | 22 | LEDK | - | |
8 | WR | 8 | 23 | LEDK | - | |
9 | RD | 9 | 24 | LEDK | - | |
10 | SDA | GND | 25 | GND | - | |
11 | DB0 | 39 | 26 | - | - | |
12 | DB1 | 40 | 27 | - | - | |
13 | DB2 | 41 | 28 | - | - | |
14 | DB3 | 42 | 29 | - | - | |
15 | DB4 | 45 | 30 | GND | - |
今回使用したLCDは、IM1
,IM2
をLo
とすることで、8ビットParallel
接続となる。(IM1
,IM2
をHi
にすると4-line SPI
接続になる)
(ST7789
のIM0
,IM3
が引き出されていないが、上記の動作からLo
固定と推測する)
動作検証プログラム
Arduino IDEを使用して、TFT-eSPIに用意されているサンプルスケッチを使い、使用パネルの設定を行った。
サンプルスケッチ パス:TFT_eSPI/examples/160 x 128/TFT_graphicstest_PDQ3/TFT_graphicstest_PDQ3.ino
変更その1
スケッチにUser_Setup_Select.h
のインクルード文を追加
: : (省略)
+ #include <User_Setup_Select.h>
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
: : (省略)
変更その2
#include <User_Setups/Setup206_LilyGo_T_Display_S3.h>
のコメントを外す(使用パネルの宣言)
(ピンアサインをLILYGO® T-Display-S3
に倣ったのは、設定を楽にするため)
: : (省略)
//#include <User_Setups/Setup205_ESP32_TouchDown_S3.h> // Setup file for the ESP32 TouchDown S3 based on ILI9488 480 x 320 TFT
- //#include <User_Setups/Setup206_LilyGo_T_Display_S3.h> // For the LilyGo T-Display S3 based ESP32S3 with ST7789 170 x 320 TFT
+ #include <User_Setups/Setup206_LilyGo_T_Display_S3.h> // For the LilyGo T-Display S3 based ESP32S3 with ST7789 170 x 320 TFT
//#include <User_Setups/Setup207_LilyGo_T_HMI.h> // For the LilyGo T-HMI S3 based ESP32S3 with ST7789 240 x 320 TFT
: : (省略)
変更その3
今回のLCDはST7789V3
ドライバのため、#define ILI9341_DRIVER
をコメントアウト。
(最初うまく動作せず、ここに気付くまでに苦労した)
: : (省略)
// Only define one driver, the other ones must be commented out
- #define ILI9341_DRIVER // Generic driver for common displays
+ //#define ILI9341_DRIVER // Generic driver for common displays
//#define ILI9341_2_DRIVER // Alternative ILI9341 driver, see https://github.com/Bodmer/TFT_eSPI/issues/1172
: : (省略)
動作結果
以下の動画のとおり、うまく動作しました。
描画性能はどうでしょうか? SPI接続よりは高速だと思いますが・・・
動画に映っているベンチマーク結果をリストにしておきます。
(単位:マイクロ秒)
Benchmark | TFT-eSPI | LovyanGFX |
---|---|---|
HaD logo | 102,682 | 44,709 |
Clear | 1,317,037 | 350,834 |
Text | 8,468 | 6,270 |
Pixels | 136,271 | 118,911 |
Lines | 166,924 | 144,065 |
H/V Lines | 11,310 | 2,822 |
Rectangles | 5,005 | 1,431 |
Rects-Fill | 145,034 | 31,091 |
Circles | 13,196 | 13,326 |
CircleFill | 30,490 | 12,535 |
Triangles | 7,019 | 5,787 |
Tris-Fill | 49,284 | 14,717 |
Rnd-Rects | 7,650 | 3,997 |
RRects-Fill | 145,861 | 32,577 |
Total | 2,146,231 | 783,072 |
追記
LovyanGFXライブラリを使ってみる
TFT-eSPIより高速との評判のLovyanGFXで表示してみた。下記動画のとおり、確かに高速に描画している。
ベンチマーク結果は、上の表に列追加しました。fill系のAPIが高速です。DMA転送しているから?
ピン接続などは、TFT-eSPIと同じです。下記にパネル定義を載せておきます。
#include <LovyanGFX.hpp>
class LGFX : public lgfx::LGFX_Device
{
// 接続するパネルの型にあったインスタンスを用意します。
lgfx::Panel_ST7789 _panel_instance;
// パネルを接続するバスの種類にあったインスタンスを用意します。
lgfx::Bus_Parallel8 _bus_instance; // 8ビットパラレルバスのインスタンス
// バックライト制御が可能な場合はインスタンスを用意します。(必要なければ削除)
lgfx::Light_PWM _light_instance;
public:
// コンストラクタを作成し、ここで各種設定を行います。
LGFX(void)
{
{ // バス制御の設定を行います。
auto cfg = _bus_instance.config(); // バス設定用の構造体を取得します。
// 8ビットパラレルバスの設定
//cfg.i2s_port = I2S_NUM_0; // 使用するI2Sポートを選択 (I2S_NUM_0 or I2S_NUM_1) (ESP32のI2S LCDモードを使用します)
cfg.freq_write = 20000000; // 送信クロック (最大20MHz, 80MHzを整数で割った値に丸められます)
cfg.pin_wr = 8; // WR を接続しているピン番号
cfg.pin_rd = 9; // RD を接続しているピン番号
cfg.pin_rs = 7; // RS(D/C)を接続しているピン番号
cfg.pin_d0 = 39; // D0を接続しているピン番号
cfg.pin_d1 = 40; // D1を接続しているピン番号
cfg.pin_d2 = 41; // D2を接続しているピン番号
cfg.pin_d3 = 42; // D3を接続しているピン番号
cfg.pin_d4 = 45; // D4を接続しているピン番号
cfg.pin_d5 = 46; // D5を接続しているピン番号
cfg.pin_d6 = 47; // D6を接続しているピン番号
cfg.pin_d7 = 48; // D7を接続しているピン番号
_bus_instance.config(cfg); // 設定値をバスに反映します。
_panel_instance.setBus(&_bus_instance); // バスをパネルにセットします。
}
{ // 表示パネル制御の設定を行います。
auto cfg = _panel_instance.config(); // 表示パネル設定用の構造体を取得します。
cfg.pin_cs = 6; // CSが接続されているピン番号 (-1 = disable)
cfg.pin_rst = 5; // RSTが接続されているピン番号 (-1 = disable)
cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable)
// ※ 以下の設定値はパネル毎に一般的な初期値が設定されていますので、不明な項目はコメントアウトして試してみてください。
cfg.panel_width = 170; // 実際に表示可能な幅
cfg.panel_height = 320; // 実際に表示可能な高さ
cfg.offset_x = 35; // パネルのX方向オフセット量
cfg.offset_y = 0; // パネルのY方向オフセット量
cfg.offset_rotation = 0; // 回転方向の値のオフセット 0~7 (4~7は上下反転)
cfg.dummy_read_pixel = 8; // ピクセル読出し前のダミーリードのビット数
cfg.dummy_read_bits = 1; // ピクセル以外のデータ読出し前のダミーリードのビット数
cfg.readable = true; // データ読出しが可能な場合 trueに設定
cfg.invert = true; // パネルの明暗が反転してしまう場合 trueに設定
cfg.rgb_order = false; // パネルの赤と青が入れ替わってしまう場合 trueに設定
cfg.dlen_16bit = false; // 16bitパラレルやSPIでデータ長を16bit単位で送信するパネルの場合 trueに設定
cfg.bus_shared = false; // SDカードとバスを共有している場合 trueに設定(drawJpgFile等でバス制御を行います)
//cfg.memory_width = 170; // ドライバICがサポートしている最大の幅
//cfg.memory_height = 320; // ドライバICがサポートしている最大の高さ
_panel_instance.config(cfg);
}
{ // バックライト制御の設定を行います。(必要なければ削除)
auto cfg = _light_instance.config(); // バックライト設定用の構造体を取得します。
cfg.pin_bl = 38; // バックライトが接続されているピン番号
cfg.invert = false; // バックライトの輝度を反転させる場合 true
cfg.freq = 44100; // バックライトのPWM周波数
cfg.pwm_channel = 7; // 使用するPWMのチャンネル番号
_light_instance.config(cfg);
_panel_instance.setLight(&_light_instance); // バックライトをパネルにセットします。
}
setPanel(&_panel_instance); // 使用するパネルをセットします。
}
};
おわりに
元々は、CircuitPythonでパラレル接続を使いたかったが、ESP32s3ではparalleldisplay
が使えず、SPI接続しかできなかった。
少しでも高速描画したいため、CircuitPythonからCのTFT-eSPI LovyanGFXを呼び出すブリッジ機能を作ろうかと思います。実現できるか分かりませんが、上手くできたらQiita記事にします。