方言を話すおしゃべり猫型ロボット『ミーア』をリリースしました(こちらをクリック)

【ST7735】TFT LCDの描画問題解決ガイド:Green Tabの設定方法

この記事は約7分で読めます。

はじめに

方言を話すおしゃべり猫型ロボット「ミーア」を開発中。

https://mia-cat.com

目の描画としてST7735s LCDを利用しているのだが、画面の右下の一部のピクセルが描画されないというエラーが生じており、解消を試みる。この記事ではST7735 TFT LCDディスプレイで遭遇した描画問題とその解決策について記載。

なお、ST7735s 1.44 inchを利用しており、BodmerのTFT_eSPIライブラリを目の描画コードとして使用中。SP32ベースの自作基板とST7735を繋いでいる。

https://github.com/Bodmer/TFT_eSPI

ソフトウェア側の問題?

最初は、目を描画しているソフトウェア側の問題かと思い、該当コードを確認。

platformio.iniでは、TFT_eSPIライブラリをST7735用に設定し、HEIGHTとWIDTHも128pxに揃えている。

C++
// platformio.ini
; TFT_eSPIライブラリをST7735用に設定
build_flags =
  -DUSER_SETUP_LOADED=1
  -DST7735_DRIVER=1
  -DTFT_WIDTH=128
  -DTFT_HEIGHT=128

また、目の描画のコードでは、tft.pushImageを使い、IMG_HEIGHT、IMG_WIDTHで128pxを使ってディスプレイいっぱいに表示するように指定しているので、問題なさそうに見える。

C++
// src/eye.cpp
#define IMG_WIDTH 128
#define IMG_HEIGHT 128

//  静止画
void displayStaticEyeImage(const uint8_t *eyeImage, const uint8_t *eyeImage2) {
  Serial.println("静止画");
  for (uint8_t e = 0; e < NUM_EYES; e++) {
    digitalWrite(eye[e].tft_cs, LOW);
    tft.startWrite();
    if (e == 0 || eyeImage2 == nullptr) {
      tft.pushImage(eye[e].xposition, 0, IMG_WIDTH, IMG_HEIGHT, eyeImage, true, NULL);
    } else {
      tft.pushImage(eye[e].xposition, 0, IMG_WIDTH, IMG_HEIGHT, eyeImage2, true, NULL);
    }
    tft.endWrite();
    digitalWrite(eye[e].tft_cs, HIGH);
  }
}

tft.fillScreen関数を使用して完全な画面の再描画テスト

ソフトウェアの問題かハードウェアの問題かを特定するために、tft.fillScreen関数を使用して、画面全体を単色で塗りつぶし、全ピクセルが適切に描画されるかを確認する。

loop() 関数の中にテストコードを挿入する。

C++
// src/main.cpp
void loop() {
	TFT_eSPI tft;
  // ディスプレイにテストカラーを表示するテストコード
  tft.fillScreen(TFT_BLUE); 
  delay(5000); // 5秒間、画面をその色で表示し続ける
  // 以降は元のコード
  ...
}

ビルドしたところ、エラーは改善されなかった。なので、ハードウェア(ST7735)の方の問題だろうと推測。

ST7735にGreen tabを設定?

ググってたら、同じような問題に遭遇している人を発見

https://github.com/Bodmer/TFT_eSPI/issues/507

Green Tabって何?型番?と思い、購入したAliExpressのサイトを見たが特に記載されていない。

https://ja.aliexpress.com/item/1005004875729700.html?spm=a2g0o.order_list.order_list_main.11.6171585aAfIkDK&gatewayAdapt=glo2jpn

届いている商品を確認したところ、ディスプレイの保護カバーの横に緑の付箋のようなものを発見。Tabとはこのことを指しているらしい。

ST7735ディスプレイは同じ基本チップを使用しながらも、異なるメーカーや生産バッチによって、細かな仕様の違いがあるため、多くのバリエーションが存在する。これらの違いは、ディスプレイモジュールの製造中に、実際の表示可能エリアやピクセルの配列、オフセットなど、内部的な設定が異なることによる。“Green Tab”、”Red Tab”、”Black Tab” などといったタブは、ディスプレイのフレキシブルプリント回路(FPC)の端に付いている色付きのタブで、これによって異なるモデルやバージョンを識別する。

たとえば、”Green Tab” のバージョンが複数存在する場合(例: GREENTAB、GREENTAB2、GREENTAB3)、それぞれは以下のような理由で異なる名前が付けられている:

  • 製造時期:同じ色のタブでも、異なる時期に製造されたり、異なる製造ラインから出たりすることで、細かな違いが生じることがある。
  • ディスプレイの設定:タブの色が同じでも、内部のROMに焼かれた初期化コードや、アクティブなピクセルエリア、オフセット、色の順序(RGBやBGR)、表示方向などが異なる場合がある。
  • 互換性:一部のディスプレイは特定のメインチップやライブラリで特別に最適化されており、それに応じて別々の設定が必要になる。

なるほど、Green tabの中でもさらに複数のバージョンで細分化されているので、それを設定する必要があるとのこと。

BodmerのTFT_eSPIライブラリでは、使用しているLCDディスプレイのタイプなどユーザー固有の設定は、User_Setup.hファイルに記載するよう推奨しているが、今回はUser_Setup.hファイル自体は削除していて、固有設定はplatformio.iniに集約しているので、platformio.iniのbuild_flagsに「-DST7735_GREENTAB」を追加してビルド。

https://github.com/Bodmer/TFT_eSPI/blob/master/User_Setup.h

C++
// platformio.ini
; TFT_eSPIライブラリをST7735用に設定
build_flags =
  -DUSER_SETUP_LOADED=1
  -DST7735_DRIVER=1
  -DTFT_WIDTH=128
  -DTFT_HEIGHT=128
  -DST7735_GREENTAB

おお!?横表示だけ直って全画面になった。

残るは縦の表示のみ。

-DST7735_GREENTAB2を設定しても変わらず。

ダメもとで、-DST7735_GREENTAB3を設定したところ、、、

C++
// platformio.ini
; TFT_eSPIライブラリをST7735用に設定
build_flags =
  -DUSER_SETUP_LOADED=1
  -DST7735_DRIVER=1
  -DTFT_WIDTH=128
  -DTFT_HEIGHT=128
  -DST7735_GREENTAB3

おお!!ST7735sの画面全体に目が表示されるようになった!

同じLCDディスプレイモジュールなのに、ピクセルの配列やオフセットが製造会社によって異なるとか、やめてくれよ!という感じだが、無事解消できてよかった。

自分がTFTライブラリで使用しているのがBodmerなので、今回はBodmerについて記載したが、Adafruitの場合も同様にできそう。Adafruitの場合も同様のエラーに遭遇している人がいた。

https://forum.arduino.cc/t/problem-with-1-8-128×160-tft-display/468416/3

コメント

タイトルとURLをコピーしました