「Arduinoの基礎 - ST7735」の版間の差分

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
(ページの作成:「== 概要 == <br><br> == 接続 == ArduinoとST7735の一般的な接続方法を以下に示す。<br> <br> SCLとSDAはハードウェアSPIを使用するため、指定のピンを使用する必要がある。<br> RESET、D/C、CSは任意のデジタルピンに接続可能であるが、下表上に示すような組み合わせが一般的である。<br> <br> もし、ST7735に背景光用のLEDピンがある場合、適切な抵抗を介して任意の…」)
 
195行目: 195行目:
   tft.setTextColor(color);
   tft.setTextColor(color);
   tft.print(text);
   tft.print(text);
}
</syntaxhighlight>
<br><br>
== アニメーションの描画 ==
ST7735を使用してアニメーションを描画することができる。<br>
また、複数のアニメーションの組み合わせる、あるいは、パラメータの調整を行うことにより、より複雑な動きを実現することも可能である。<br>
<br>
ただし、メモリ使用量に注意する必要がある。<br>
また、更新頻度が高すぎると描画が追いつかない可能性があるため、可能な限り必要な部分のみを更新する。<br>
<br>
<u>delay関数は使用せずに、millis関数 (ノンブロッキング処理) を使用してタイミング制御をする必要がある。</u><br>
<br>
==== 例 : バウンドするボール ====
<syntaxhighlight lang="c++">
// アニメーションの状態変数
int ballX = 64;        // ボールのX座標
int ballY = 64;        // ボールのY座標
int ballSize = 10;    // ボールの大きさ
int ballSpeedX = 2;    // X方向の速度
int ballSpeedY = 2;    // Y方向の速度
void setup()
{
  tft.initR(INITR_BLACKTAB);
  tft.fillScreen(ST77XX_BLACK);
}
void loop()
{
  // 前のフレームのボールを消す
  tft.fillCircle(ballX, ballY, ballSize, ST77XX_BLACK);
  // ボールの位置を更新
  ballX += ballSpeedX;
  ballY += ballSpeedY;
  // 画面端での跳ね返り
  if (ballX >= tft.width() - ballSize || ballX <= ballSize) {
    ballSpeedX = -ballSpeedX;
  }
  if (ballY >= tft.height() - ballSize || ballY <= ballSize) {
    ballSpeedY = -ballSpeedY;
  }
  // 新しい位置にボールを描画
  tft.fillCircle(ballX, ballY, ballSize, ST77XX_RED);
  delay(30);  // アニメーションの速度調整
}
</syntaxhighlight>
<br>
==== 例 : 回転する線 ====
<syntaxhighlight lang="c++">
float angle = 0;
int centerX = tft.width() / 2;
int centerY = tft.height() / 2;
int radius = 30;
void loop()
{
  // 前のフレームをクリア
  tft.fillScreen(ST77XX_BLACK);
  // 新しい線を描画
  int endX = centerX + cos(angle) * radius;
  int endY = centerY + sin(angle) * radius;
  tft.drawLine(centerX, centerY, endX, endY, ST77XX_WHITE);
  angle += 0.1;  // 回転角度を更新
  delay(30);
}
</syntaxhighlight>
<br>
==== 例 : プログレスバー ====
<syntaxhighlight lang="c++">
void animateProgressBar()
{
  int barWidth = tft.width() - 20;  // バーの幅
  int barHeight = 10;              // バーの高さ
  int startX = 10;                  // 開始X座標
  int startY = tft.height() / 2;    // 開始Y座標
  for (int progress = 0; progress <= barWidth; progress++) {
    // バーの背景
    tft.drawRect(startX, startY, barWidth, barHeight, ST77XX_WHITE);
    // プログレス部分
    tft.fillRect(startX, startY, progress, barHeight, ST77XX_BLUE);
    delay(20);
  }
}
</syntaxhighlight>
<br>
==== アニメーションを滑らかにする手順 ====
===== ダブルバッファリング =====
<syntaxhighlight lang="c++">
// 前のフレームを消去してから新しいフレームを描画
void clearPreviousFrame()
{
  // 特定の領域だけを消去
  tft.fillRect(x, y, width, height, ST77XX_BLACK);
}
</syntaxhighlight>
<br>
===== フレームレート制御 =====
<syntaxhighlight lang="c++">
unsigned long previousMillis = 0;
const long frameInterval    = 33;  // 約30[FPS]
void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= frameInterval) {
    previousMillis = currentMillis;
    // アニメーションの更新処理
    updateAnimation();
  }
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>

2024年12月23日 (月) 02:26時点における版

概要



接続

ArduinoとST7735の一般的な接続方法を以下に示す。

SCLとSDAはハードウェアSPIを使用するため、指定のピンを使用する必要がある。
RESET、D/C、CSは任意のデジタルピンに接続可能であるが、下表上に示すような組み合わせが一般的である。

もし、ST7735に背景光用のLEDピンがある場合、適切な抵抗を介して任意のデジタルピンに接続できる。

ST7735とArduino R3 / R4の接続
ST7735 Arduino R3 / R4 補足
SCL (SCLK) Pin 13 SPI SCK
SDA (MOSI) Pin 11 SPI MOSI
RESET Pin 9 任意のデジタルピン
D/C Pin 8 データ / コマンド、任意のデジタルピン
CS Pin 10 SS、任意のデジタルピン



回路図



必要なライブラリ

ST7735を動作させるのに必要なライブラリを以下に示す。

  • Adafruit ST7735 and ST7789 Library
  • Adafruit GFX Library
  • Adafruit BusIO


上記のライブラリのインストール手順を以下に示す。

  1. Arduino IDEのメインメニューから[ツール] - [ライブラリを管理...]を選択する。
  2. ライブラリマネージャーの検索欄にそれぞれ、"Adafruit ST7735"、"Adafruit GFX"、"Adafruit BusIO"と入力する。
  3. 各ライブラリの[インストール]ボタンを押下する。
  4. 依存ライブラリのインストールが求められる場合は、[すべてインストール]を選択する。



使用例

ピンの定義

 // ライブラリのインクルード
 
 #include <Adafruit_GFX.h>     // グラフィックス描画用ライブラリ
 #include <Adafruit_ST7735.h>  // ST7735専用のドライバライブラリ
 #include <SPI.h>              // SPI通信用ライブラリ
 
 // ピンの定義
 #define TFT_CS    10  // チップセレクト用ピン (任意のGPIOピン)
 #define TFT_RST   9   // リセット用ピン (任意のGPIOピン)
 #define TFT_DC    8   // データ / コマンド切り替え用ピン (任意のGPIOピン)


ディスプレイオブジェクトの初期化

 // ディスプレイオブジェクトの初期化
 // 引数 : CS, DC, RSTの各ピン番号
 
 Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
 
 // カラー定義 (一般的に使用される色)
 #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::initRメソッドで使用できる引数を示す。
もし、不確かな場合は、各引数を試して正しい表示になるものを選択することもできる。

誤った引数を使用する場合、色の反転、あるいは、表示位置がずれる可能性がある。

Adafruit_ST7735::initRメソッドの引数
引数 ディスプレイタイプ 補足
INITR_BLACKTAB 1.8インチ (黒タブ) 一般的な1.8インチディスプレイ
INITR_GREENTAB 1.8インチ (緑タブ) 色の初期化が異なる1.8インチディスプレイ
INITR_REDTAB 1.8インチ (赤タブ) オフセット設定が異なる1.8インチディスプレイ
INITR_MINI160x80 0.96インチ 160x80ピクセルの小型ディスプレイ
INITR_MINI160x80_PLUGIN 0.96インチ プラグイン基板用の160x80ピクセル


識別方法 1

  • ディスプレイの背面やフレキケーブルの色 (タブの色) を確認
  • ディスプレイサイズを測定 (0.96インチ、1.8インチ等)
  • 解像度を確認 (160x80、160x128等)


 // シリアル通信の開始 (デバッグ用)
 Serial.begin(9600);
 
 // ディスプレイの初期化
 // 1.8インチ黒タブの場合
 tft.initR(INITR_BLACKTAB);  // ディスプレイタイプの設定
 
 // 0.96インチの場合
 // tft.initR(INITR_MINI160x80);
 
 // 画面の向きを設定 (必要に応じて)
 tft.setRotation(1);  // 0〜3の値で90度ずつ回転
 
 // 画面クリアと背景色の設定
 tft.fillScreen(BLACK);
 
 // 初期テキスト設定
 tft.setTextColor(WHITE);
 tft.setTextSize(1);


テキストの表示

 // テキストの表示
 tft.setCursor(0, 0);
 tft.println("Hello World!");


図形の描画

 // 四角形の描画
 tft.drawRect(10, 30, 50, 30, WHITE);      // 空の四角形
 tft.fillRect(70, 30, 50, 30, RED);        // 塗りつぶされた四角形
 
 // 円の描画
 tft.drawCircle(35, 90, 20, BLUE);         // 空の円
 tft.fillCircle(95, 90, 20, GREEN);        // 塗りつぶされた円
 
 // 線の描画
 tft.drawLine(10, 120, 110, 120, YELLOW);  // 直線
 
 // 1秒待機
 delay(1000);



ヘルパー関数の定義

ST7735を使用する上で、ヘルパー関数を定義すると便利である。

 // テキストの表示
 
 void displayText(const char* text, uint16_t x, uint16_t y, uint16_t color)
 {
   tft.setCursor(x, y);
   tft.setTextColor(color);
   tft.println(text);
 }


 // 画面の消去 (背景色を黒色で消去する場合)
 
 void clearScreen()
 {
   tft.fillScreen(BLACK);
 }


 // 四角形内にテキストを中央揃えで表示
 
 void drawCenteredText(const char *text, int x, int y, int w, int h, uint16_t color)
 {
   int16_t  x1,
            y1;
   uint16_t w1,
            h1;
 
   tft.getTextBounds(text, 0, 0, &x1, &y1, &w1, &h1);
   tft.setCursor(x + (w - w1) / 2, y + (h - h1) / 2);
   tft.setTextColor(color);
   tft.print(text);
 }



アニメーションの描画

ST7735を使用してアニメーションを描画することができる。
また、複数のアニメーションの組み合わせる、あるいは、パラメータの調整を行うことにより、より複雑な動きを実現することも可能である。

ただし、メモリ使用量に注意する必要がある。
また、更新頻度が高すぎると描画が追いつかない可能性があるため、可能な限り必要な部分のみを更新する。

delay関数は使用せずに、millis関数 (ノンブロッキング処理) を使用してタイミング制御をする必要がある。

例 : バウンドするボール

 // アニメーションの状態変数
 
 int ballX = 64;        // ボールのX座標
 int ballY = 64;        // ボールのY座標
 int ballSize = 10;     // ボールの大きさ
 int ballSpeedX = 2;    // X方向の速度
 int ballSpeedY = 2;    // Y方向の速度
 
 void setup()
 {
   tft.initR(INITR_BLACKTAB);
   tft.fillScreen(ST77XX_BLACK);
 }
 
 void loop()
 {
   // 前のフレームのボールを消す
   tft.fillCircle(ballX, ballY, ballSize, ST77XX_BLACK);
 
   // ボールの位置を更新
   ballX += ballSpeedX;
   ballY += ballSpeedY;
 
   // 画面端での跳ね返り
   if (ballX >= tft.width() - ballSize || ballX <= ballSize) {
     ballSpeedX = -ballSpeedX;
   }
 
   if (ballY >= tft.height() - ballSize || ballY <= ballSize) {
     ballSpeedY = -ballSpeedY;
   }
 
   // 新しい位置にボールを描画
   tft.fillCircle(ballX, ballY, ballSize, ST77XX_RED);
 
   delay(30);  // アニメーションの速度調整
 }


例 : 回転する線

 float angle = 0;
 int centerX = tft.width() / 2;
 int centerY = tft.height() / 2;
 int radius = 30;
 
 void loop()
 {
   // 前のフレームをクリア
   tft.fillScreen(ST77XX_BLACK);
 
   // 新しい線を描画
   int endX = centerX + cos(angle) * radius;
   int endY = centerY + sin(angle) * radius;
   tft.drawLine(centerX, centerY, endX, endY, ST77XX_WHITE);

   angle += 0.1;  // 回転角度を更新
   delay(30);
 }


例 : プログレスバー

 void animateProgressBar()
 {
   int barWidth = tft.width() - 20;  // バーの幅
   int barHeight = 10;               // バーの高さ
   int startX = 10;                  // 開始X座標
   int startY = tft.height() / 2;    // 開始Y座標
 
   for (int progress = 0; progress <= barWidth; progress++) {
     // バーの背景
     tft.drawRect(startX, startY, barWidth, barHeight, ST77XX_WHITE);
 
     // プログレス部分
     tft.fillRect(startX, startY, progress, barHeight, ST77XX_BLUE);
 
     delay(20);
   }
 }


アニメーションを滑らかにする手順

ダブルバッファリング
 // 前のフレームを消去してから新しいフレームを描画
 
 void clearPreviousFrame()
 {
   // 特定の領域だけを消去
   tft.fillRect(x, y, width, height, ST77XX_BLACK);
 }


フレームレート制御
 unsigned long previousMillis = 0;
 const long frameInterval     = 33;  // 約30[FPS]

 void loop()
 {
   unsigned long currentMillis = millis();
 
   if (currentMillis - previousMillis >= frameInterval) {
     previousMillis = currentMillis;
 
     // アニメーションの更新処理
     updateAnimation();
   }
 }