1.8インチ TFT LCDを使ってみた ~ まずはRaspberry Pi Picoで

2024年6月19日

今までグラフィックディスプレイはSSD1306ドライバを使うI2Cインタフェイスの単色OLEDを使ってきましたが、やっぱりフルカラーで表示したいです。そこで、ST7735Sドライバを使うSPIインタフェイスの1.8インチ TFT LCDを購入してみました。さて、うまくいくでしょうか。

1.使用する1.8インチ TFT LCDとRaspberry Pi Picoの接続

1.8インチ TFT LCDとRaspberry Pi Picoをジャンパーワイヤで接続します。

1.8inchTFT / Raspberry Pi Pico

GND -> GND
VCC -> 3.3V OUT
SCL -> GP18
SDA -> GP19
RES -> GP27
DC -> GP26
CS -> GP17
BL -> 未接続

2.画像を作成する

画像の表示ですが、JPEGやPNGなどの画像をライブラリで表示するわけにはいきません。ディスプレイサイズに合ったRGB565画像を用意する必要があります。どうすれば良いだろうと検索すると、以下のサイト様がWebツールを提供しています。

この界隈では有名な「Lang-ship」さんですね。ありがとうございます。

使用する画像は、いつも歩いている森で撮ったニリンソウの写真をディスプレイサイズに切り取りました。それを、上記のツールでRGB565形式に変換しています。

ここで注意ですが、使用する1.8インチ TFT LCDの公式サイズは128×160ドットなのですが、実際に動かしてみると130×161ドットサイズであるように見えます。公式サイズで動作させると、右と下が空いてしまいます。何か設定があるのかもしれませんが、130×161ドットでプログラムを作成します。
※サイズは128×160だが、原点が(-2, -1)みたいです。今後、修正する予定。

3.LovyanGFXを使う

使用するグラフィックライブラリは、LovyanGFXを使います。LovyanGFXは、Raspberry Pi PicoではSPIインタフェイスをサポートしています(I2Cはサポートしていない)。

そして、LovyanGFXの使い方例を公開している神サイトがあります。

いや、ほんとうにありがたいです。

4.プログラム

プログラムソースですが、画像ソースがとても長いので省略しています。ご了承ください。また、Arduino IDEを使います。

#define LGFX_USE_V1
#include <LovyanGFX.hpp>

#define TFT_MISO -1
#define TFT_MOSI 19
#define TFT_SCLK 18
#define TFT_CS   17
#define TFT_DC   26
#define TFT_RST  27

#include <pgmspace.h>

const uint16_t imgWidth = 128;
const uint16_t imgHeight = 160;

// RGB565 Dump(little endian)
const unsigned short img[20480] PROGMEM = {

■■ 長いので省略 ■■

};

// 「あろしーど」さん定義例使用
class LGFX : public lgfx::LGFX_Device
{
  lgfx::Panel_ST7735S _panel_instance;
  lgfx::Bus_SPI _bus_instance; // SPIバスのインスタンス
public:
  LGFX(void)
  {
    {                                    // バス制御の設定を行います。
      auto cfg = _bus_instance.config(); // バス設定用の構造体を取得します。

      // SPIバスの設定
      cfg.spi_host = 0;          // 使用するSPIを選択  (VSPI_HOST or HSPI_HOST)
      cfg.spi_mode = 0;          // SPI通信モードを設定 (0 ~ 3)
      cfg.freq_write = 40000000; // 送信時のSPIクロック (最大80MHz, 80MHzを整数で割った値に丸められます)
      cfg.freq_read = 20000000;  // 受信時のSPIクロック

      cfg.pin_sclk = TFT_SCLK; // SPIのSCLKピン番号を設定
      cfg.pin_mosi = TFT_MOSI; // SPIのMOSIピン番号を設定
      cfg.pin_miso = TFT_MISO; // SPIのMISOピン番号を設定 (-1 = disable)
      cfg.pin_dc = TFT_DC;     // SPIのD/Cピン番号を設定  (-1 = disable)

      _bus_instance.config(cfg);              // 設定値をバスに反映します。
      _panel_instance.setBus(&_bus_instance); // バスをパネルにセットします。
    }

    {                                      // 表示パネル制御の設定を行います。
      auto cfg = _panel_instance.config(); // 表示パネル設定用の構造体を取得します。

      cfg.pin_cs = TFT_CS;   // CSが接続されているピン番号   (-1 = disable)
      cfg.pin_rst = TFT_RST; // RSTが接続されているピン番号  (-1 = disable)
      cfg.pin_busy = -1;     // BUSYが接続されているピン番号 (-1 = disable)

      cfg.panel_width = 130;  // 実際に表示可能な幅
      cfg.panel_height = 161; // 実際に表示可能な高さ

      // cfg.offset_x = 0;       // パネルのX方向オフセット量
      // cfg.offset_y = 0;       // パネルのY方向オフセット量

      cfg.rgb_order = true; // パネルの赤と青が入れ替わってしまう場合 trueに設定

      _panel_instance.config(cfg);
    }
    setPanel(&_panel_instance); // 使用するパネルをセットします。
  }
};

// LovyanGFX インスタンス作成
static LGFX lcd; 
static LGFX_Sprite canvas(&lcd); 

void setup() {
  // put your setup code here, to run once:
  lcd.init(); 
  canvas.createSprite(lcd.width(), lcd.height()); 

  canvas.fillScreen(TFT_BLACK); // 背景塗り潰し

  canvas.setBuffer((void*)img, imgWidth, imgHeight, 16);

  canvas.pushSprite(0, 0); 

}

void loop() {
  // put your main code here, to run repeatedly:

  delay(1000);  // 1秒ごとに更新

}

スプライトを使用していますが、今回はまったく必要ないですね。将来的なことを考えてスプライトを使用しています。

5.ビルドする

ビルドの際、ボードは「Earle F. Philhower」さんのドライバを使用しています。また、ライブラリにLovyanGFXをインストールしておいてください。

ビルドが終了すると、問題なく画像が表示されました。ちょっと視野角が狭いTFTディスプレイですね。

6.やっぱりカラーディスプレイは良い!

スプライトを使うサンプルを動かしてみた アニメーションも結構良さそう

やっぱり、カラーディスプレイによる表示は美しくて良いです。実は、今回のカラーディスプレイの前にST7789ドライバのTFT LCDを購入していました。しかしながら、何をやっても表示されないし、終いには煙が出てお亡くなりになるなど、残念な結果になりました。最初から不良品だったのかもしれません。今回は、あっさりと動作してくれて、前回の苦労は一体何だったのだという感想です。

カラーディスプレイを使えるようになったので、これから作成する電子工作の情報表示に幅が広がりました。この次は、ATOM LITE系で表示してみます。