Arduinoの基礎 - ST7735
ナビゲーションに移動
検索に移動
概要
接続
ArduinoとST7735の一般的な接続方法を以下に示す。
SCLとSDAはハードウェアSPIを使用するため、指定のピンを使用する必要がある。
RESET、D/C、CSは任意のデジタルピンに接続可能であるが、下表上に示すような組み合わせが一般的である。
もし、ST7735に背景光用のLEDピンがある場合、適切な抵抗を介して任意のデジタルピンに接続できる。
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
上記のライブラリのインストール手順を以下に示す。
- Arduino IDEのメインメニューから[ツール] - [ライブラリを管理...]を選択する。
- ライブラリマネージャーの検索欄にそれぞれ、"Adafruit ST7735"、"Adafruit GFX"、"Adafruit BusIO"と入力する。
- 各ライブラリの[インストール]ボタンを押下する。
- 依存ライブラリのインストールが求められる場合は、[すべてインストール]を選択する。
使用例
ピンの定義
// ライブラリのインクルード
#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
メソッドで使用できる引数を示す。
もし、不確かな場合は、各引数を試して正しい表示になるものを選択することもできる。
誤った引数を使用する場合、色の反転、あるいは、表示位置がずれる可能性がある。
引数 | ディスプレイタイプ | 補足 |
---|---|---|
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();
}
}