液晶ディスプレイ ST7789 (SPI) をESP32で使ってみる(Arduino)

今回は、液晶ディスプレイ ST7789 を使った、
 ・スケッチ例のデモ表示
 ・温度・湿度センサモジュールを繋いで、温度・湿度の表示
をしてみます。

私の製品です。
 ・TFTディスプレイ 1.3インチIPS 7PIN SPI (CSピンなし)
   フルカラー液晶モジュールST7789 240*240
   ¥249-

液晶ディスプレイ ST7789 (SPI)
液晶ディスプレイ ST7789 (SPI)

いつもの大陸調達品ですが、
国内通販サイトで検索してみましたが、
まったく同じのもの販売は、数少ないようです。
”液晶ディスプレイ ST7789 通販”
などと検索すると、類似製品はいろいろ販売されています。
・・・大陸通販では、多く扱われているのですが。

購入サイトでは、3.0V~5.0Vの表記でしたが、
実際試してみたところ、5.0Vでは利用できませんでした。
・・・私の配線ミス等の可能性も大です。

そこで、この製品を、ESP32で使用することにしました。
調べてみると、この製品は、3.3V 仕様のようなので、
3.3V対応のESP32で使用してみることにしました。
なんせ、
抵抗などを使用して、5Vから3.3Vに分圧なんて、
私の技量では無理です。

回路は図の通りです。
   この回路図の作図には fritzing を利用させて頂いております。
   https://fritzing.org/home/

回路図1
回路図1
ESP32側液晶ディスプレイ液晶ST7789側
GNDGND
3.3VVCC
D18 (VSPI CLK)SCK
D23 (VSPI MOSI)SDA
D5RES
D19 (VSPI MISO)DC
未接続BLK
接続端子

SPI通信では、
マスタ(Arduino)に複数のスレーブ(機器)を接続し、
通信線を共有して、マスタ、スレーブ間の通信を
可能にする仕組みを提供しています。
これにより、通信線(ピン端子)を節約できます。
・・・スレーブが増える毎に、SS(CS)線が1本増えます。

SPI通信概要図
SPI通信概要図
信号線の名称信号線内容
SCL(SLK,SCLK)共有シリアルクロック (Serial Clock Line)
MISOやMOSIのデータ転送の同期信号線
マスタ時:クロック出力、スレーブ時:クロック入力
MOSI(SDA)共有データ送受信線(Slave Out Master In)
スレーブ(ST7789)からマスタ(Arduino)へのデータ転送線
マスタ時:データ入力、スレーブ時:データ出力
MISO(RS/DC)共有データ送受信線(Slave In Master Out)
マスタ時:データ出力、スレーブ時:データ入力
マスタ(Arduino)からスレーブ(ST7789)へのデータ転送線
SS(CS)単独チップ選択(SlaveSelect/ChipSelect)
マスタ(Arduino)が通信機器を選択するための信号線
- - - - - - SPI通信仕様外 - - - - - - -
VCC電源
GNDグランド(Ground)
Reset(RES)単独リセット信号線(Controller Reset)
SPI通信仕様

という配線になりますが、
この製品( 液晶ディスプレイ ST7789 )にはSS(CS) 端子がありません。
複数のSPI機器を接続した場合、この製品を選択して
通信を行うことができないことになります。
SS(CS)の信号が L 値の機器が通信対象機器になりますので、
1台のみの使用であれば その機器の SS を L 値に、
固定することができれば、この線は不要となります。

ESP32のプログラム開発をArduino IDEで行う場合は、
ESP32用に開発環境の設定を済ませてある必要があります。
この設定は、
Arduino IDE ESP32 (ESP-32) の開発準備
に記載しています。
 https://shinog.jp/computer/arduino/arduino-ide-esp32-esp-32-%e3%81%ae%e9%96%8b%e7%99%ba%e6%ba%96%e5%82%99/

今回の液晶ディスプレイ ST7789 の使用に必要な
ライブラリ群をインストールします。
 ・Adafruit-GFX-ライブラリ
 ・Arduino-ST7789 ライブラリ
の2つが必要になります。

ライブラリのインストール手順です。

 1.Adafruit-GFX-ライブラリのインストール
  メニュー「スケッチ」 → 「ライブラリインストール」
    → 「ライブラリ管理」 を選択します。

ライブラリ管理の選択
ライブラリ管理の選択

  開いた、ライブラリマネジャ画面の検索欄に、
   ”Adafruit GFX”
  と入力し、
  表示された一覧から、
  ”Adafruit GFX Library” を選択し、
  バージョン選択から、最新バージョンを選択し、
  〔インストール〕ボタンをクリックします。

 ”Adafruit GFX Library” の選択
”Adafruit GFX Library” の選択

  インストール内容の選択画面が表示された場合は、
  〔Install all〕 をクリックします。

インストール項目の選択
インストール項目の選択

  インストールが完了したら、
  〔閉じる〕ボタンをクリックします。

インストールの完了
インストールの完了

  ※GitHub の Adafruit-GFX-ライブラリ ページから、
   https://github.com/adafruit/Adafruit-GFX-Library
   ダウンロードして、

ライブラリのダウンロードページ
ライブラリのダウンロードページ

   メニュー「スケッチ」 → 「ライブラリインストール」
     → 「.ZIP形式のライブラリインストール…」 を選択して、
   インストールすることも可能です。 

ZIP形式ライブラリのインストール
ZIP形式ライブラリのインストール

 2.Arduino-ST7789 ライブラリ のインストール
   Arduino-ST7789 ライブラリ ページから、
   https://github.com/ananevilya/Arduino-ST7789-Library
  ライブラリ群をダウンロードします。

ライブラリのダウンロードページ
ライブラリのダウンロードページ

  メニュー「スケッチ」 → 「ライブラリインストール」
    → 「.ZIP形式のライブラリインストール…」 を選択します。

ZIP形式ライブラリのインストール
ZIP形式ライブラリのインストール

  開いたファイル指定画面から、
  ダウンロードした、
   ”Arduino-ST7789-Library-master.zip”
  ファイルを選択し、〔開く〕ボタンをクリックします。

インストールライブラリの選択
インストールライブラリの選択

これで、ライブラリのインストールは完了です。

では、スケッチ例の
”graphicstest” スケッチを実行してみます。

1.ボードを選択します。
 ESP32のボードの種類に合わせ選択します。  
 メニュー「ツール」 → 「ボード:xxxxx」
  → 「ESP32 Arduino」 → 「ESP32 Dev Module」 を選択します。

ボードの選択
ボードの選択

2.シリアルポートを選択します。
 ESP32のボードの種類に合わせ選択します。  
 メニュー「ツール」 → 「シリアルポート:xxxxx」
  → 「COMx」 を選択します。

シリアルポートの選択
シリアルポートの選択

 ※ESP32が使用しているポートを選択します。
 ※分からない場合は、
  Windowsメニューを右クリック → デバイスマネージャー(M)を選択し、
  開いたデバイスマネージャ-画面のポート(COM と LPT)から確認します。
  ※私の場合:Silicon Labs CP210x USB to UART Bridge(COM4)でした。

 デバイスマネジャー画面
デバイスマネジャー画面
ボード、シリアルポートの設定確認
ボード、シリアルポートの設定確認

3.”graphicstest” を開きます。
 メニュー「ファイル」 → 「スケッチ例」
  → 「Arduino ST779 Library」 → 「graphicstest」 を選択します。

スケッチ例の選択
スケッチ例の選択

4.スケッチの修正を行います。
 4.1.オブジェクト生成文の選択を変更します。

//or you can use software SPI on all available pins (slow)
//Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK); //for display without CS pin
//Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_CS); //for display with CS pin
// ↓ 初期値としてこのこの生成文が選択されています。
Arduino_ST7789 tft = Arduino_ST7789(-1, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_CS); //for display with CS pin and DC via 9bit SPI

   ↓ CSピンを使用しないオブジェクト生成文に変更します。

//or you can use software SPI on all available pins (slow)
// ↓ この生成文を使用します。
Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK); //for display without CS pin
//Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_CS); //for display with CS pin
//Arduino_ST7789 tft = Arduino_ST7789(-1, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_CS); //for display with CS pin and DC via 9bit SPI

 4.2.ピンアサインを変更します。

#define TFT_DC    8
#define TFT_RST   9 
#define TFT_CS    10   // only for displays with CS pin
#define TFT_MOSI  11   // for hardware SPI data pin (all of available pins)
#define TFT_SCLK  13   // for hardware SPI sclk pin (all of available pins)

    ↓

#define TFT_DC    19
#define TFT_RST   5 
#define TFT_CS    10   // only for displays with CS pin
#define TFT_MOSI  23   // for hardware SPI data pin (all of available pins)
#define TFT_SCLK  18   // for hardware SPI sclk pin (all of available pins)

5.アイコンメニュー「検証」をクリックし、検証します。

検証
検証

6.アイコンメニュー「マイコンボードに書き込む」をクリックし、
 マイコンボードに書き込み、実行します。

マイコンボードへ書き込み
マイコンボードへ書き込み

液晶ディスプレイ ST7789 に、
文字やグラフィックがデモ表示されます。
このスケッチは、
各図形描画や文字表示関数を、
void setup(void) 関数から呼び出されるかたちで
記述されていますので分かりやすいと思います。

実行結果画面
実行結果画面

続いて、このESP32に、温度・湿度センサモジュールを
接続し、この温度。湿度を、
液晶ディスプレイ ST7789 に表示させてみます。

回路は図の通りです。

回路図2
回路図2

※使用する温度・湿度センサは、
 ”温度センサを使ってみる (湿度も測る)
   https://shinog.jp/computer/arduino/%e6%b8%a9%e5%ba%a6%e3%82%bb%e3%83%b3%e3%82%b5%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b-%ef%bc%88%e6%b9%bf%e5%ba%a6%e3%82%82%e6%b8%ac%e3%82%8b%ef%bc%89/
 で使用した、デジタル温度(湿度)センサ DHT11です。
 GPIO27番ピンで、センサデータを受け取ります。
 このセンサは、3.0V~5.0V仕様なので、
 3.3V端子から電源を供給して使用します。

デジタル温度(湿度)センサ DHT11
デジタル温度(湿度)センサ DHT11

スケッチです。

スケッチは、
サンプル例の ”graphicstest” スケッチに、
デジタル温度(湿度)センサ DHT11関連の記述を
追加することにします。

このスケッチでは、
デジタル温度(湿度)センサ DHT11 用に、
 ・DHT-sensor-library
 ・Adafruit_Unified_Sensor
2つのライブラリのインストールが必要です。

インストールは、
 ”温度センサを使ってみる (湿度も測る)
に記載しています。

追加スケッチは、
 1.グローバル領域に、インクルード宣言とオブジェクト生成
 2.void setup(void) 関数に、センサの初期化
 3.void loop() 関数に、温度・湿度の取得と表示
の3点について追加、修正します。

追加修正部分のスケッチの抜粋です。

1.の部分 (グローバル領域に、インクルード宣言とオブジェクト生成)

// インクルード(ライブラリ利用)宣言
#include <DHT.h>
// オブジェクト生成
DHT dht( 27, DHT11 );  // デジタルピン27番、DHT11を使用

2.の部分 (void setup(void) 関数に、センサの初期化)

void setup(void) {
  //  DHT11センサ初期化
  dht.begin();
}

3.の部分 (void loop() 関数に、温度・湿度の取得と表示)

void loop() {
  tft.invertDisplay(true);
  delay(2500);              // 待機時間変更
  tft.invertDisplay(false);
  delay(2500);              // 待機時間変更

   // 変数宣言
  float temp; // 温度格納用
  float humi; // 湿度格納用

  // 温度取得
  temp = dht.readTemperature();
  // 湿度取得
  humi = dht.readHumidity();

  // 取得情報確認
  if ( isnan( humi ) || isnan( temp )) {
    // 取得に失敗
    Serial.println( "-- sensor read error --");
  } else {
    // 液晶ディスプレイ初期設定
    tft.setTextWrap(false);
    tft.fillScreen(BLACK);
    tft.setCursor(0, 0);
    // 温度表示
    tft.setTextColor(RED);
    tft.setTextSize(3);
    tft.println( "temperature:" );
    tft.setTextSize(4);
    tft.println(  temp );
    tft.println( "" );
    // 湿度表示     
    tft.setTextColor(YELLOW);
    tft.setTextSize(3);
    tft.println( "Humidity:" );
    tft.setTextSize(4);
    tft.println( humi );
  } 
}

スケッチの追加修正部分( 1, 2, 3の部分 )の抜粋です。

#include <Adafruit_GFX.h>         // Core graphics library by Adafruit
#include <Arduino_ST7789.h>  // Hardware-specific library for ST7789 (with or without CS pin)
#include <SPI.h>

#define TFT_DC    19
#define TFT_RST   5 
#define TFT_CS    10 // only for displays with CS pin
#define TFT_MOSI  23   // for hardware SPI data pin (all of available pins)
#define TFT_SCLK  18   // for hardware SPI sclk pin (all of available pins)

//You can use different type of hardware initialization
//using hardware SPI (11, 13 on UNO; 51, 52 on MEGA; ICSP-4, ICSP-3 on DUE and etc)
//Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST); //for display without CS pin
//Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST, TFT_CS); //for display with CS pin
//or you can use software SPI on all available pins (slow)
Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK); //for display without CS pin
//Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_CS); //for display with CS pin
//Arduino_ST7789 tft = Arduino_ST7789(-1, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_CS); //for display with CS pin and DC via 9bit SPI

float p = 3.1415926;

// インクルード(ライブラリ利用)宣言
#include <DHT.h>

// オブジェクト生成
DHT dht( 27, DHT11 );  // デジタルピン27番、DHT11を使用

void setup(void) {
  //  DHT11センサ初期化
  dht.begin();
   
  Serial.begin(9600);
  Serial.print("Hello! ST7789 TFT Test");

  tft.init(240, 240);   // initialize a ST7789 chip, 240x240 pixels

  Serial.println("Initialized");

  uint16_t time = millis();
  tft.fillScreen(BLACK);
  time = millis() - time;

  Serial.println(time, DEC);
  delay(500);

  // large block of text
  tft.fillScreen(BLACK);
  testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", WHITE);
  delay(1000);

  // tft print function
  tftPrintTest();
  delay(4000);

  // a single pixel
  tft.drawPixel(tft.width()/2, tft.height()/2, GREEN);
  delay(500);

  // line draw test
  testlines(YELLOW);
  delay(500);

  // optimized lines
  testfastlines(RED, BLUE);
  delay(500);

  testdrawrects(GREEN);
  delay(500);

  testfillrects(YELLOW, MAGENTA);
  delay(500);

  tft.fillScreen(BLACK);
  testfillcircles(10, BLUE);
  testdrawcircles(10, WHITE);
  delay(500);

  testroundrects();
  delay(500);

  testtriangles();
  delay(500);

  mediabuttons();
  delay(500);

  Serial.println("done");
  delay(1000);
}

void loop() {
  tft.invertDisplay(true);
  delay(2500);              // 待機時間変更
  tft.invertDisplay(false);
  delay(2500);              // 待機時間変更

   // 変数宣言
  float temp; // 温度格納用
  float humi; // 湿度格納用

  // 温度取得
  temp = dht.readTemperature();
  // 湿度取得
  humi = dht.readHumidity();

  // 取得情報確認
  if ( isnan( humi ) || isnan( temp )) {
    // 取得に失敗
    Serial.println( "-- sensor read error --");
  } else {
    // 液晶ディスプレイ初期設定
    tft.setTextWrap(false);
    tft.fillScreen(BLACK);
    tft.setCursor(0, 0);
    // 温度表示
    tft.setTextColor(RED);
    tft.setTextSize(3);
    tft.println( "temperature:" );
    tft.setTextSize(4);
    tft.println(  temp );
    tft.println( "" );
    // 湿度表示     
    tft.setTextColor(YELLOW);
    tft.setTextSize(3);
    tft.println( "Humidity:" );
    tft.setTextSize(4);
    tft.println( humi );
  } 
}

~ 略 ~

アイコンメニュー「検証」をクリックし、検証します。

検証
検証

アイコンメニュー「マイコンボードに書き込む」をクリックし、
マイコンボードに書き込み、実行します。

マイコンボードへ書き込み
マイコンボードへ書き込み

液晶ディスプレイ ST7789 に、
文字やグラフィックがデモ表示された後、
温度と湿度が表示されます。

実行結果画面
実行結果画面

デモが必要ない場合、
void setup(void) 関数内の、
各デモ関数の呼び出しを停止(コメントアウト)します。