Arduino環境で小型IPS LCDモジュールを使う(ST7735 0.96inch)

コンピュータ、組み込み

Arduino環境で使用できる小型のLCDモジュール ST7735 0.96を使ってみます。
小型の表示OLEDパネル SSD1331 0.95inchとの比較、RP2040系でのSPI接続によるLCD表示、JPG表示とバックライトを利用したフェードイン、フェードアウトをしてみます。

今回紹介するもの

LCDモジュール (ST7735 0.96inch)

製品情報
サイズ0.96inch
解像度(X, Y)80, 160
パネル方式IPS
通信方式SPI
ドライバST7735
動作電圧3.3V
ピン配置
外観

前面

背面

比較(vs OLED SSD1331 0.95inch)

同サイズ帯のOLED SSD1331 0.95inch とST7735 0.96inchの比較をしました。

主な仕様の比較です。

SSD1331 0.95inchST7735 0.96inch
ドライバSSD1331ST7735
画面サイズ0.95inch0.96inch
解像度(W, H)※96, 64160, 80
表示方式OLED カラーLCD IPS カラー
電源電圧3.2 ~ 5V3.3V
通信方式SPI (7Pin)
電源, GND含む
SPI (8Pin)
電源, GND含む
差異は BLK
※ここでの表記は長手方向をW, 短手方向をHとします。
ライブラリにより表示角度を回転させることで、W, H を入れ替えることができます。

表示の見え方についてjpg画像を表示して比較しました。
画像サイズはそれぞれのモニタのサイズに調整しています。
画像左はOLED SSD1331 0.95inch、右はST7735 0.96inchです。

表示面積はわずかな差ですが、画素分解能がST7735 0.96inchのほうが高いことからST7735 0.96inchのほうが詳細な画像に見えます。
またOLED SSD1331は少しぼやけた画像に見えますが、ST7735 0.96inchのほうが鮮やかな色彩に見えます。

配線上では、ST7735 0.96inchはBLK(バックライト)がある分1Pin多いです。
このBLKライトはマイコンの3.3Vから取り出してもいいですが、GPIOのアナログ出力(PWM)を使用することで明るさ調整に使用したり、画像切り替えの時のフェード効果に使用することもできます。
使用しているサンプルのスケッチは「使い方」の「表示(SDカードからJPG表示)」にて紹介します。

使用感

SPIですので配線数は多いです。
ピン配置はST7735を使用しているLCDパネルですが、OLEDのSPI系に近い配線なのでピン配置表をよく見て作業する必要があります。

OLEDに比べてバックライトの電源分1ピン多い配線ですが、バックライトはGPIOのアナログ出力機能(PWM)を使うことでフェード効果の表示を行うことができるので、使い方次第では有効に使用することもできます。

小さな表示範囲に高い解像度のものですので、細かな画像でも鮮明に表示することができました。
国内で利用できるショッピングサイトでも安価で入手性も良いモジュールなので2,3個常備しておきたいところです。

準備

ライブラリ

LCDを制御するためのライブラリにはAdafruit製ライブラリを使用します。
ST7735と共通ライブラリです。

ライブラリ名用途検索確認時バージョン
Adafruit GFX Library by AdafruitグラフィックGFX1.11.3
Adafruit ST7735 and ST7789 Library by AdafruitグラフィックST77891.9.3
TJpg_Decoder by BodmerJPG表示JPG1.0.8

Adafruit ST7735 and ST7789 Library by Adafruitライブラリをインストールすると、依存ライブラリが不足している場合不足している依存関係のインストールの問い合わせがあります。
「すべてをインストール」を選択してください。

画像はILI9341ライブラリをインストールするときの依存関係のインストール画面を流用しています。

使い方

表示

説明

RP2040系(Pico Bit RP2040)とESP32系(ESP32C3 Super Mini)を使用して表示制御します。
H/W SPIを使用する参考にしてください。

図形などほかの描画サンプルは
スケッチ例 > Adafruit ST7735 and ST7789Library > graphicstest
を参照してください。

配線(RP2040系 Pico Bit RP2040の場合)
Pico Bit RP2040配線ST7735
GNDGND
3.3VVCC
GPIO1CS
GPIO8DC
GPIO7RES
GPIO3SDA(MOSI)
GPIO2CLK(SCK)
3.3VBLK

スケッチ

/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
Pico Bit RP2040

【スケッチの説明】
ST7735 LCDの制御をします。
SPIは SPI0とSPI1のどちらのサンプルも掲載しますが、
SPI1側はコメントアウトしますので、状況に応じてコメントを外してください。
※コメント検索 [SPI1の場合]

【ライブラリ】
Raspberry Pi Pico / RP2040 > Generic RP2040
Adafruit ST7735 and ST7789 Library
Adafruit GFX Library

【準備】
マイコン基板 <-> ST7735
3V3               <-> VCC
GND               <-> GND
GPIO1(SPI0 CS)    <-> CS
GPIO7             <-> Reset
GPIO8             <-> AO
GPIO3(SPI0 MOSI)  <-> SDA
GPIO2(SPI0 SCK)   <-> SCK

【バージョン情報】
2023/4/30 : 新規
**********************************************************************/

#include <Adafruit_GFX.h> 
#include <Adafruit_ST7735.h>
#include <SPI.h>

//SPIピン定義
#define TFT_CS          1   // CS
#define TFT_RST         7   // Reset 
#define TFT_DC          8   // DC
#define TFT_MOSI        3   // MOSI
#define TFT_SCK         2   // SCK


//SPI0の場合
Adafruit_ST7735 tft = Adafruit_ST7735(&SPI, TFT_CS, TFT_DC, TFT_RST);
//SPI1の場合
//Adafruit_ST7735 tft = Adafruit_ST7735(&SPI1, TFT_CS, TFT_DC, TFT_RST);

void setup(void) 
{
  //SPI0の場合
  SPI.setTX(TFT_MOSI);
  SPI.setSCK(TFT_SCK);

  //SPI1の場合
  // SPI1.setTX(TFT_MOSI);
  // SPI1.setSCK(TFT_SCK);
  

  tft.initR(INITR_MINI160x80_PLUGIN);                  //Init ST7735初期化
  
  tft.fillScreen(ST77XX_BLACK);               //背景の塗りつぶし

    //テキスト表示
  tft.setRotation(3);                         //画面回転
  tft.setTextSize(2);                         //サイズ

  tft.setCursor(0, 10);                       //カーソル位置                      
  tft.setTextColor(ST77XX_GREEN);             //緑
  tft.printf("TAMANEGI\n");

  tft.setCursor(0, 30);                       //カーソル位置                      
  tft.setTextSize(1);                         //サイズ
  tft.setTextColor(ST77XX_RED);               //赤
  tft.printf("0.96inch LCD\n");
  tft.setTextColor(ST77XX_YELLOW);            //黄
  tft.printf("Res=80 x 160\n");
  tft.setTextColor(ST77XX_BLUE);              //青
  tft.printf("ST7735\n");
}

void loop()
{
}
配線(ESP32系 ESP32C3 Super Miniの場合)
ESP32C3 Super Mini配線ST7735
GNDGND
3.3VVCC
GPIO1CS
GPIO8DC
GPIO7RES
GPIO3SDA(MOSI)
GPIO2SCL(SCK)
3.3VBLK

スケッチ

/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
ESP32C3 Super Mini

【スケッチの説明】
ST7735 LCDの制御をします。

【ライブラリ】
esp32 > ESP32C3 Dev Module
Adafruit ST7735 and ST7789 Library
Adafruit GFX Library

【準備】
マイコン基板 <-> ST7735
3V3               <-> VCC
GND               <-> GND
GPIO1             <-> CS
GPIO7             <-> Reset
GPIO8             <-> AO
GPIO3             <-> SDA
GPIO2             <-> SCK

【バージョン情報】
2023/5/2 : 新規
**********************************************************************/

#include <Adafruit_GFX.h> 
#include <Adafruit_ST7735.h>
#include <SPI.h>

//SPIピン定義
#define TFT_CS          1   // CS
#define TFT_RST         7   // Reset 
#define TFT_DC          8   // DC
#define TFT_MOSI        3   // MOSI
#define TFT_SCK         2   // SCK

Adafruit_ST7735 tft = Adafruit_ST7735(&SPI, TFT_CS, TFT_DC, TFT_RST);

void setup(void) 
{
  //SPIデフォルトピンから変更する場合
  SPI.begin(TFT_SCK, -1, TFT_MOSI, TFT_CS);

  tft.initR(INITR_MINI160x80_PLUGIN);         //Init ST7735初期化
  
  tft.fillScreen(ST77XX_BLACK);               //背景の塗りつぶし

    //テキスト表示
  tft.setRotation(3);                         //画面回転
  tft.setTextSize(2);                         //サイズ

  tft.setCursor(0, 10);                       //カーソル位置                      
  tft.setTextColor(ST77XX_GREEN);             //緑
  tft.printf("TAMANEGI\n");

  tft.setCursor(0, 30);                       //カーソル位置                      
  tft.setTextSize(1);                         //サイズ
  tft.setTextColor(ST77XX_RED);               //赤
  tft.printf("0.96inch LCD\n");
  tft.setTextColor(ST77XX_YELLOW);            //黄
  tft.printf("Res=80 x 160\n");
  tft.setTextColor(ST77XX_BLUE);              //青
  tft.printf("ST7735\n");
}

void loop()
{
}
結果

表示ができました。

表示(SDカードからjpgファイルの表示)

説明

SDカードリーダよりjpgファイル”test.jpg”を読み取り、TFTに表示をします。

SDカードのルートフォルダには”test.jpg”ファイルを保存してください。
jpgファイルのサイズは160 x 80で作成します。

バックライトをOFFの状態で画像の表示を行い、GPIOのアナログ出力(PWM)によりフェード効果により表示と消去を繰り返します。

配線

RP2040系(Pico Bit RP2040)を使用した配線を掲載します。
SPI0をTFTとSDカードリーダ共通で使用します。

Pico Bit RP2040配線ST7735配線TFカードリーダ
GNDGNDGND
3.3VVCCVCC
GPIO8DC
GPIO1CS
GPIO2CLKCLK
GPIO3SDAMOSI
GPIO7RES
GPIO14赤破線BLK
GPIO29CS
GPIO4MISO
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
Pico Bit RP2040

【スケッチの説明】
SDカードモジュールからtest.jpgを読み出しST7735 0.96inchに表示します。

【ライブラリ】
Raspberry Pi Pico/RP2040 > Generic RP2040

Adafruit ST7735 and ST7789 LibraryTJpg_Decoder
Adafruit GFX Library

【準備】
SDカードのルートフォルダに "test160x80.jpg"を保存します。
jpgファイルのサイズは 160 x 80 サイズで保存します。

SPI0のMOSIとSCKは共通で使用します。
Pico Bit RP2040       <-> SSD1331
<<TFT側>>
3.3V                  <-> VCC
GND                   <-> GND
GPIO1                 <-> TFT CS
GPIO7                 <-> TFT Reset
GPIO8                 <-> TFT AO(D/C)
GPIO3(SPI0 MOSI)      <-> TFT SDA
GPIO2(SPI0 SCK)       <-> TFT SCK
GPIO14                <-> TFT BLK

<<TFカードリーダ側>>
GPIO29                <-> SD CS
GPIO3(SPI0 MOSI)      <-> SD MOSI
GPIO4(SPI0 MISO)      <-> SD MISO
GPIO2(SPI0 SCK)       <-> SD SCK

【バージョン情報】
2023/5/2 : 新規
**********************************************************************/

#include <SPI.h>
#include <SD.h>

#include <TJpg_Decoder.h>

#include <Adafruit_SSD1331.h>
#include <Adafruit_ST7735.h>
#include <Adafruit_GFX.h>

//TFT SD共通ピン設定
#define COMMON_MOSI   3
#define COMMON_SCK    2

//TFTピン設定
#define TFT_CS        1
#define TFT_RST       7
#define TFT_DC        8
#define TFT_BK        14      //Back Light
//SDピン設定
#define SD_CS         29  
#define SD_MISO       4
#define FILENAME_TFT      "/test160x80.jpg"

// JPGの最大サイズ(バッファを静的に確保するようにしているため、決め打ち。取り扱う最大ファイルサイズで変えるようにする)
#define JPG_SIZE_MAX (20 * 1024) //MAX 20KByteを想定

// Color definitions
#define	BLACK           0x0000
#define	BLUE            0x001F
#define	RED             0xF800
#define	GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0
#define WHITE           0xFFFF

Adafruit_ST7735 tft = Adafruit_ST7735(&SPI, TFT_CS, TFT_DC, TFT_RST);     //SPI0を使用

struct jpg_file
{
  size_t size;
  uint8_t buf[JPG_SIZE_MAX];
};

jpg_file jpg;

//デコードを行うコールバック関数
bool TFT_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *bitmap)
{
  if (y >= tft.height())
    return 0;

  tft.drawRGBBitmap(x, y, bitmap, w, h);

  return 1;
}

void setup()
{
  Serial.begin(115200);
  delay(1000);

  pinMode(TFT_BK, OUTPUT);                    //バックライトの電源にGPIOを使用する

  //SPIピン設定
  SPI.setTX(COMMON_MOSI);
  SPI.setRX(SD_MISO);
  SPI.setSCK(COMMON_SCK);

  //TFTの初期化と初期設定
  tft.initR(INITR_MINI160x80_PLUGIN);         //Init ST7735初期化  
  tft.fillScreen(ST77XX_BLACK);               //背景の塗りつぶし
  tft.setRotation(3);

  
  //SDカードリーダの初期化とファイルの読み取り
  if (!SD.begin(SD_CS, SD_SCK_MHZ(16)))
  {
    Serial.println("SD initialization failed!");
    while(1);
  }

  TJpgDec.setCallback(TFT_output);

  File jpgFileTFT = SD.open(FILENAME_TFT, FILE_READ);
  if (!jpgFileTFT)
  {
    Serial.printf("Open file failed [%s]\r\n", FILENAME_TFT);
    while(1);
  }

  jpg.size = jpgFileTFT.size();

  if(sizeof(jpg.buf) < jpg.size) 
  {
    Serial.println("File size over");
    return;
  }

  uint16_t w = 0, h = 0;

  //ファイル情報の表示
  Serial.printf("file size = %d bytes\r\n", jpgFileTFT.readBytes((char *)jpg.buf, jpg.size));
  TJpgDec.getJpgSize(&w, &h, jpg.buf, jpg.size);
  Serial.printf("Width = %d, height = %d\r\n", w, h);

  TJpgDec.setJpgScale(1);
  TJpgDec.drawJpg(0, 0, jpg.buf, jpg.size);             //画像の表示

  jpgFileTFT.close();


}

void loop()
{

  int i;

  //バックライトをフェード効果でゆっくり表示と、ゆっくり消去を繰り返す。
  //表示側
  for(i = 0; i < 256; i ++)
  {
    analogWrite(TFT_BK, i);
    delay(10);
  }
  delay(1000);

  //消去側
  for(i = 0; i < 256; i ++)
  {
    analogWrite(TFT_BK, 255 - i);
    delay(10);
  }

}
結果

SDカード内のjpgファイルの表示をしました。
バックライトがついていない状態で画像を表示したあとで、バックライトをアナログ出力(PWM)しています。
フェード効果で画像の切り替えを優しく演出しています。

こちらではSDカードのファイルリストの作成 を紹介しています。
組み合わせて使用することでフォトフレームなどを作ることができます。

ライセンスについて

MIT License および ST7735/ST7789

コメント

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