Arduino Nanoで2.4インチ 240x320 TFTディスプレイを使ってみる


# はじめに
* 以前からこの液晶ディスプレイが気になっていた。
 * [2.4インチ　TFT LCD　シールド](https://www.amazon.co.jp/Lovoski-2-4インチ-TFT-LCD-シールド-ソケット-タッチ-パネル-モジュール-ディスプレイ-Arduino-メガ-2560適用/dp/B0753WM6PQ/ref=pd_day0_hl_21_2/357-1994387-6430244?_encoding=UTF8&pd_rd_i=B0753WM6PQ&pd_rd_r=8df2796b-4b17-11e9-a2f4-9d4732929a0d&pd_rd_w=HSXtw&pd_rd_wg=5Bul5&pf_rd_p=e14bc52c-c42d-4186-8791-83a2ac0bb011&pf_rd_r=B9Z368S8FE8E1YAQVWN7&psc=1&refRID=B9Z368S8FE8E1YAQVWN7) （現在価格 690円）
* ただしArduino UNOとかMEGAのシールドモジュールとなっている。
* 自分はArduino Nanoしか持ってないが、ピン配置は同じはずなので、とりあえず買って試してみた。

![IMG_1854.JPG](https://qiita-image-store.s3.amazonaws.com/0/283854/5f87d3c4-6537-a989-376e-f5eaca2e4991.jpeg)


# Spec
* 2.4インチTFTタッチパネルディスプレイ
* 18ビットカラー
* 4線式抵抗タッチスクリーン
* MicroSDカードスロット付きでSDカードから画像ファイルの読出しが可能
* ILI9341 240 x 320
* デジタルピン5-13とアナログ0-3を使用

## 注意点
* Amazonの記載ではILI9341となっているが[こちら](http://nopnop2002.webcrow.jp/Arduino-Hard/ArduinoTFTShield.html)にあるように、個体によってドライバのICが結構違うらしい。
* 自分が取り寄せたものもいくつかのWEBサイトに出回ってる型番では無かった。
* その場合は、後述の手順でコードをちょっといじる必要がある。

![IMG_1855.JPG](https://qiita-image-store.s3.amazonaws.com/0/283854/2a29539e-bdc8-31e6-e156-8bd8c69e5d57.jpeg)

# ライブラリの取得
* 製造元より以下のサンプルコードを入手し、Arduino IDEで「.ZIP 形式のライブラリをインストール」しておく。
 * https://github.com/prenticedavid/MCUFRIEND_kbv
* 「Adafruit GFX Library」も入れておく。

# ピン配線
* 以下の定義に沿ってArduinoのピンとディスプレイのピンをつなぐ。
 * スケッチ例 --> MCUFRIEND_kbv --> LCD_ID_readreg 

```
#define LCD_RST A4
#define LCD_CS A3
#define LCD_RS A2
#define LCD_WR A1
#define LCD_RD A0

#define LCD_D0 8
#define LCD_D1 9
#define LCD_D2 2
#define LCD_D3 3
#define LCD_D4 4
#define LCD_D5 5
#define LCD_D6 6
#define LCD_D7 7
```

# サンプルが実行できない
* この状態で スケッチ例 --> MCUFRIEND_kbv --> Font_simple を書き込んで実行してみる。
 * が、バックライトは点灯するものの、画面に何も表示されない。。。
 * 国内、国外の情報を色々調べた所、どうやらドライバICがコードとマッチしてないのが原因らしい。
 * いくつか試行錯誤し、以下のように解決した。


# レジスタ情報を調べる
* 以下のサンプルコードを実行し、シリアルモニタの出力内容を確認。
 * スケッチ例 --> MCUFRIEND_kbv --> LCD_ID_readreg
 * これにより、この基板のドライバICは0x9797であることが分かる。

```
Read Registers on MCUFRIEND UNO shield
controllers either read Read Registers on MCUFRIEND UNO shield
controllers either read as single 16-bit
e.g. the ID is at readReg(0)
or as a sequence of 8-bit values
in special locations (first is dummy)

reg(0x0000) 97 97	ID: ILI9320, ILI9325, ILI9335, ...
reg(0x0004) 97 97 97 97	Manufacturer ID
reg(0x0009) 97 97 97 97 97	Status Register
reg(0x000A) 97 97	Get Power Mode
reg(0x000C) 97 97	Get Pixel Format
reg(0x0061) 97 97	RDID1 HX8347-G
reg(0x0062) 97 97	RDID2 HX8347-G
reg(0x0063) 97 97	RDID3 HX8347-G
reg(0x0064) 97 97	RDID1 HX8347-A
reg(0x0065) 97 97	RDID2 HX8347-A
reg(0x0066) 97 97	RDID3 HX8347-A
reg(0x0067) 97 97	RDID Himax HX8347-A
reg(0x0070) 97 97	Panel Himax HX8347-A
reg(0x00A1) 97 97 97 97 97	RD_DDB SSD1963
reg(0x00B0) 97 97	RGB Interface Signal Control
reg(0x00B4) 97 97	Inversion Control
reg(0x00B6) 97 97 97 97 97	Display Control
reg(0x00B7) 97 97	Entry Mode Set
reg(0x00BF) 97 97 97 97 97 97	ILI9481, HX8357-B
reg(0x00C0) 97 97 97 97 97 97 97 97 97	Panel Control
reg(0x00C8) 97 97 97 97 97 97 97 97 97 97 97 97 97	GAMMA
reg(0x00CC) 97 97	Panel Control
reg(0x00D0) 97 97 97	Power Control
reg(0x00D2) 97 97 97 97 97	NVM Read
reg(0x00D3) 97 97 97 97	ILI9341, ILI9488
reg(0x00D4) 97 97 97 97	Novatek ID
reg(0x00DA) 97 97	RDID1
reg(0x00DB) 97 97	RDID2
reg(0x00DC) 97 97	RDID3
reg(0x00E0) 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97	GAMMA-P
reg(0x00E1) 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97	GAMMA-N
reg(0x00EF) 97 97 97 97 97 97	ILI9327
reg(0x00F2) 97 97 97 97 97 97 97 97 97 97 97 97	Adjust Control 2
reg(0x00F6) 97 97 97 97	Interface Control

```


# コンフィグレーションの変更

* 以下のファイルに修正方法が記載されている。
 * https://github.com/prenticedavid/MCUFRIEND_kbv/blob/master/extras/mcufriend_how_to.txt
 * "0x9797"で検索するとこんな記載が見つかった。
 * 要は、SUPPORT_1289 をdefineしろと。
 
```
SSD1297  240x320  ID=0x9797 #define SUPPORT_1289 (unstable readGRAM())
```

* これに沿って、以下のファイルを編集。
 * Documents/Arduino/libraries/MCUFRIEND_kbv-master/MCUFRIEND_kbv.cpp 
 * 3行目で0x9797はデフォルトで無効になっているため、これを有効にする。

* 修正前

```
//#define SUPPORT_0139              //S6D0139 +280 bytes
#define SUPPORT_0154              //S6D0154 +320 bytes
//#define SUPPORT_1289              //SSD1289,SSD1297 (ID=0x9797) +626 bytes, 0.03s
//  (以下省略)
```

* 修正後

```
//#define SUPPORT_0139              //S6D0139 +280 bytes
#define SUPPORT_0154              //S6D0154 +320 bytes
#define SUPPORT_1289              //SSD1289,SSD1297 (ID=0x9797) +626 bytes, 0.03s
//  (以下省略)
```

# リトライ
* Arduino IDEを開いて再度コンパイル。
 * スケッチ例 --> MCUFRIEND_kbv --> Font_simple をコンパイルして書き込む。
* 今度は成功！！！

![IMG_1850.jpg](https://qiita-image-store.s3.amazonaws.com/0/283854/ea5bf10f-b453-7c06-8a9e-e37af49d12ee.jpeg)

# Arduino Nano用のシールドを自作する。
* ひとまず動作確認が取れたので、色々試して行きたい。
* が、このディスプレイ基板、Arduino UNO用の独自ピン間隔のため、ユニバーサル基板に刺さらない。。。
* Arduino Nanoで使う場合、空中配線になってしまい、非常に使いずらいのでサクッと自作してみた。

![IMG_1849.JPG](https://qiita-image-store.s3.amazonaws.com/0/283854/462e51e4-de6d-5e02-9358-6e9109740e5e.jpeg)

* とりあえずこんな感じで、ユニバーサル基板に合わないピンだけギリギリ基板の外に出して配線だけ済ませる。

![IMG_1852.JPG](https://qiita-image-store.s3.amazonaws.com/0/283854/1d74b737-c5f4-c2f4-1c80-4985ae01a635.jpeg)

* んで、このままだとプカプカ浮いてる状態なので、周りをグルーガンでがっちり固定！！

![IMG_1853.JPG](https://qiita-image-store.s3.amazonaws.com/0/283854/d6cbe781-3ea7-c784-e520-05efbb018745.jpeg)

* 反対側もがっちり固定。

![IMG_1851.jpg](https://qiita-image-store.s3.amazonaws.com/0/283854/daae2084-ff9c-3b0b-83cd-73d88868a903.jpeg)


# まとめ
* 激安カラーTFTディスプレイはArduino Nanoでも問題なく使える。
* この価格と解像度でカラー液晶が使えるのは良い。
* ESP32で制御したらゲームとか作れちゃいそう。
* 以下は制約だが、そのうち詳細に検証してみたい。
 * かなりピンを占有するので、他のモジュールを使う際はI2Cがマストな感じ。
 * 実はArduino Nanoのメモリ容量制限で、graphictest_kbvが 101% RAMサイズオーバーでそのままでは書き込めない。