Arduino-ESP32で2.8インチTFT液晶ボードとその内蔵SDスロットを使用する

# 概要
ESP32と[SDカードスロット内蔵の液晶ボード](https://www.amazon.co.jp/HiLetgo%C2%AE-LCD%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4-%E3%82%BF%E3%83%83%E3%83%81%E3%83%91%E3%83%8D%E3%83%AB-SPI%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB240-ILI9341/dp/B072N551V3/ref=cm_cr_srp_d_product_top?ie=UTF8)（Amazonで1500円くらいで購入）を使用して、簡単なアプリケーションを作成しました。

SDカードから読み出したテキストファイルの内容を液晶ボードのLCDに表示させました。

※開発環境はArduino-ESP32を使用しました

写真：今回使用した液晶ボード
![tft.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155449/27533a9f-688c-e3db-39d9-d110b17eeaca.png)


# 使用したもの
* [ESPr® Developer 32](https://www.switch-science.com/catalog/3210/)　 ※これ以降は「ESP32］と呼称
* [HiLetgo® 2.8 "TFT LCDディスプレイ タッチパネル](https://www.amazon.co.jp/HiLetgo%C2%AE-LCD%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4-%E3%82%BF%E3%83%83%E3%83%81%E3%83%91%E3%83%8D%E3%83%AB-SPI%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB240-ILI9341/dp/B072N551V3)
* Arduino IDE（バージョン1.8.5を使用）
* SDカード
* 抵抗(10kΩ x 4）

# 結線

以下の通りにESP32と液晶ボードを結線します

### LCD
|ESP32  |LCD  |
|---|---|
|VOUT  |VCC  |
|GND  |GND  |
|IO5  |CS  |
|IO16  |RES  |
|IO17  |DC  |
|IO23  |MOSI  |
|IO18  |SCK  |
|3V3  |LED  |
|IO19  |MISO  |
### SD
|ESP32  |SD  |備考  |
|---|---|---|
|IO14  |SD_SCK  |10kの抵抗を使用して3.3Vでプルアップする（[参考記事](https://github.com/espressif/esp-idf/tree/master/examples/storage/sd_card)）|
|IO2  |SD_MISO  |10kの抵抗を使用して3.3Vでプルアップする（[参考記事](https://github.com/espressif/esp-idf/tree/master/examples/storage/sd_card)）|
|IO15  |SD_MOSI  |10kの抵抗を使用して3.3Vでプルアップする（[参考記事](https://github.com/espressif/esp-idf/tree/master/examples/storage/sd_card)）|
|IO13  |SD_CS  |10kの抵抗を使用して3.3Vでプルアップする（[参考記事](https://github.com/espressif/esp-idf/tree/master/examples/storage/sd_card)）|

# スケッチの書き込み＋動作確認

スケッチのLCD表示にはTFT_eSPI(ライブラリ)、SDカードにはarduino-esp32の[SDカードライブラリ](https://github.com/espressif/arduino-esp32/tree/master/libraries/SD)を使用しました。また、ESP32のSPIは「VSPI：LCD表示 HSPI：SDカード」のように使用しました。

スケッチ書き込みのポイントは、スケッチを書き込む前後でIO2を(上記の「結線」の10kΩプルアップ抵抗と)抜き差しする点です。
これは、スケッチ書込みのブートモードとするためにはブート時にIO2をLowにする必要があるためです。

図：IO2を切り離す
![プルアップ説明2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155449/1b3ac195-acd5-16a2-bb5b-6cfedf7ff569.png)

それでは実際の手順は以下の通りです。

1. TFT_eSPI(ライブラリ)の使用準備を行う
　→下記の「[TFT_eSPIの使用準備](#tft_espiの使用準備)」参照

1. テキストファイル（[実際に使用したファイル](https://github.com/bigw00d/esp32_ili9341_2.8_tft_touch_display/blob/master/examples/simple_display_sd_data/SdFile/hello.txt)）を入れたSDカードを液晶ボードに挿入する

1. PCとESP32を接続しているUSBケーブルを抜いてIO2を(プルアップ抵抗から)切り離す

1. USBを繋いでスケッチをESP32に書き込む[(スケッチはgithubに置きました)](https://github.com/bigw00d/esp32_ili9341_2.8_tft_touch_display/blob/master/examples/simple_display_sd_data/simple_display_sd_data.ino)
※Arduinoの設定は以下の通りにしました
![Arduino設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155449/681ee23a-2147-7bdb-6829-1165d77d46f4.png)


1. USBケーブルを抜いてIO2を(プルアップ抵抗と)接続する

1. USBケーブルを接続する

1. ESP32のアプリが立ち上がり、ファイル名とその中身が5秒ごとに交代でLCDに表示される  

# TFT_eSPIの使用準備

デフォルトの状態ではこの接続方法でTFT_eSPI(ライブラリ)を使用できません。以下の通りにTFT_eSPI/User_Setup.hを編集します。（[参考元の記事](https://www.amazon.co.jp/gp/customer-reviews/R19MQH3M73XD0O?ref=pf_vv_at_pdctrvw_srp))

※TFT_eSPIを使用する他のボードへ影響があるかもしれません。ファイルのバックアップ等を行い、実施は自己責任でお願いします。

図：編集対象のファイル
![該当ファイル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155449/1e1325c8-8514-bb13-aba5-7e1154949aea.png)


### １．使用しない定義をコメントアウトする
以下の3行をコメントアウトする

```
#define TFT_CS PIN_D8
#define TFT_DC PIN_D3
#define TFT_RST PIN_D4
```
※「// ###### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP8266 SETUP ######」のすぐ下の辺りにある


### ２. ポートの割り当てを有効にする

以下の「#define～」の各行をコメント化解除。また、TFT_CSを5、TFT_DCを17、TFT_RSTを16に変更

```
// For ESP32 Dev board (only tested with ILI9341 display)
// The hardware SPI can be mapped to any pins

//#define TFT_MISO 19
//#define TFT_MOSI 23
//#define TFT_SCLK 18
//#define TFT_CS 15 // Chip select control pin
//#define TFT_DC 2 // Data Command control pin
//#define TFT_RST 4 // Reset pin (could connect to RST pin)
```
※「// ###### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP32 SETUP ######」のすぐ下の辺りにある


### ３. SPIの周波数を変更する

以下のコードをコメントアウトする

```
#define SPI_FREQUENCY 27000000 // Actually sets it to 26.67MHz = 80/3
```

以下のコードのコメントアウトを解除する

```
// #define SPI_FREQUENCY 40000000 // Maximum to use SPIFFS
```

※「// Section 4. Other options」のすぐ下あたりにある


# スケッチの説明

### ポイント１
1つ目のポイントは、SDカードとの接続(SD.begin)を繰り返している点です。

```simple_display_sd_data.ino　(再接続を行う部分)
  //retry establishing SD connection
  if (sdHasError) {
    //retry establishing SD connection
    spiSD.begin(SD_CLK, SD_MISO, SD_MOSI, SD_SS);
    if(!SD.begin( SD_SS, spiSD, SDSPEED)){
     Serial.println("Card Mount Failed");
    }
    Serial.println("Card Mount Succeeded");
    sdHasError = false;
  }
```

実はこのスケッチでは、電源ON直後の初回のSDカードとの接続が失敗します。しかし、リセット後や2回目のSDアクセスには成功します。

おそらくそれは、IO2がデフォルトでは内蔵プルダウンになっていること、そしてESPr® Developer 32のボード上でIO2が10kΩでプルダウンされていることによって、MISO(IO2)の信号レベルが上がり切らず、ピンをSPIのMISO設定（入力＝内蔵プルアップ）にした後では上がり切るのでデータの判別ができるようになると予想しています。

必要であれば回路に手を加えたりコードで対応したりしますが、いまのところ困っていないので、現状では失敗時に再びSDとの接続を行うことにしています。

### ポイント２
2つ目のポイントはSDカードのアクセスにESP32のHSPIを使用している事です。

arduino-esp32の[SDカードライブラリ](https://github.com/espressif/arduino-esp32/tree/master/libraries/SD)ではVSPIを使用していますが、上記の結線のようにVSPIはLCDに使用しています。

そこで、ESP32が持つ別のSPIであるHSPIを使用することにしました。

しかし、arduino-esp32のSDカードライブラリでHSPIをそのまま使用できず、最終的に[githubのissues](https://github.com/espressif/arduino-esp32/issues/1219#issuecomment-445580654)を参考にコードを作成することで実現できました。

### ポイント３
最後のポイントは、CPUの周波数（CPU Frequency）です。当初は160MHzにしていたところ、アプリケーションが時々立ち上がらないことがありました。そこでArduino IDEの設定値をいろいろ変えてみたところ、周波数を240MHzにすることで解消できました。


# 終わりに

やってみたらスムーズに行かないところが結構ありましたが、1つのボードにLCDとSDカードが載っているのは、やはり便利です。（実はタッチ検出もできますが、まだやっていません・・・）

今回スムーズに行かない要因の1つに、ESP32のIO2が扱いづらい事がありました。SDカードとの通信にIO2を使用する場合、上記の方法のようにスケッチの書き込みの前後でIO2をプルアップ抵抗から抜き差しする必要があります。

そこで、HSPIをリマッピングしたり（※１）、VSPIのみを使用してLCDとSDカードを制御する（※２）をすると、もっと使い勝手が良くなるかもしれません。（本当にできるかは確認していませんが）

※１：[スイッチサイエンスの記事](https://trac.switch-science.com/wiki/esp32_tips)の「SPI通信」の項目が参考になります
※２：SPIの仕様上、CSを分けていればデータ線を共有できるはず

見ていただいてありがとうございました。
тнайк чoμ_〆(・ω・｡)			
			
			
# 参考記事

 + espressif公式のデータシート
  + https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf

 + Amazonのカスタマーレビュー　(TFT_eSPI使用の参考情報)
  + https://www.amazon.co.jp/gp/customer-reviews/R19MQH3M73XD0O?ref=pf_vv_at_pdctrvw_srp

 + espressifのSDカードライブラリREADME（SDカードとの結線の参考情報）　※esp-idf用
  + https://github.com/espressif/esp-idf/blob/master/examples/storage/sd_card/README.md

 + ESP-WROOM-32に関するTIPS（SPIの参考情報）
  + https://trac.switch-science.com/wiki/esp32_tips


			
# 更新履歴
* 2019-09-26：新規作成