検索コード

ESP32-S3 RGB LEDマトリックスプロジェクト4 - 傾斜ドット

ESP32-S3 RGB LEDマトリックスプロジェクト4 - 傾斜ドット

プロジェクト4 - ティルトドット(ESP32-S3 RGB LEDマトリックスを傾けてドットを移動させる)

プロジェクト4では、ESP32-S3 RGB LEDマトリックスモジュールに搭載されたモーションセンサーを導入します。自動的にドットを動かしたり(プロジェクト1のように)、テキストをスクロールさせたり(プロジェクト2および3のように)するのではなく、このプロジェクトではボードを傾けるだけでドットの位置を制御できます。ドットは、モジュールの背面にあるQMI8658C加速度センサーからのライブデータに基づいて、8×8 RGBディスプレイ上をスムーズに移動します。

このシリーズの6つのプロジェクトすべてが1つのYouTube動画で紹介されています。 同じ動画がこのページに埋め込まれているので、ボードが傾くときに点がリアルタイムでどのように動くかを正確に見ることができます。このプロジェクトの完全なコードは、記事の下に自動的に読み込まれ、モジュールのアフィリエイト購入リンクはコードセクションの下に表示されます。

ESP32-S3 RGB LEDマトリックスモジュールの概要

このプロジェクトでは、次のものを含むESP32-S3 RGB LEDマトリックスモジュールを使用します:

  • ESP32-S3マイクロコントローラーWi-FiとBluetoothが搭載されています。
  • 8×8 RGB LEDマトリックス(64個の個別にアドレス指定可能なLED)
  • QMI8658C 加速度計傾斜と動きの検出のための背面にあります。
  • USBポートプログラミングと電力のために
  • ブート / リセットボタン
  • 使用可能なGPIOピン将来の拡張のために

QMI8658Cセンサーは読み取りますX,Y, とZ傾きに応じてドットが上下左右に移動できるようにする加速度と方向の値。:contentReference[oaicite:0]{index=0}

動画で紹介されたプロジェクト(タイムスタンプ)

  • 00:00- はじめに
  • 02:01- ESP32ボードのインストール
  • 03:32- ライブラリのインストール
  • 05:32- プロジェクト 1: 移動するドット
  • 11:11- プロジェクト2:テキストスクロール
  • 12:59- プロジェクト 3: HTTP テキスト
  • 16:41-プロジェクト4:ティルトドット(このプロジェクト)
  • 18:55- プロジェクト 5: アローアップ
  • 20:02- プロジェクト6: ターゲットゲーム

ビデオでの傾きデモを視聴することを強くお勧めします。ボードの向きに対してドットがどのようにスムーズに反応するかを見ることができます。:contentReference[oaicite:1]{index=1}

Arduino IDEでESP32ボードをインストールする

以前のプロジェクトを完了している場合、ボードサポートはすでにインストールされています。それ以外の場合は、次の手順に従ってください。

  1. 開くFile > PreferencesESP32ボードのURLを追加します。
  2. 行くTools > Board > Boards Manager…インストールするESP32.
  3. ESP32-S3ボードを選択してください。Tools > Board.
  4. 適切なCOMポートを選択してくださいTools > Port.

必要なライブラリのインストール

このプロジェクトには以下のライブラリが必要です:

  • Adafruit NeoMatrix
  • Adafruit NeoPixel
  • Adafruit GFX Library
  • QMI8658(モーションセンサー)

ライブラリマネージャにインストールしてください:

  1. オープンSketch > Include Library > Manage Libraries….
  2. 検索するAdafruit NeoMatrix→ インストール。
  3. 自動インストールを許可するAdafruit GFXアダフルート ネオピクセル.
  4. 検索するQMI8658その掲載された著者によって → インストール。:contentReference[oaicite:2]{index=2}

プロジェクト4の仕組み

QMI8658Cセンサーは、X、Y、Z軸に沿った加速度データを継続的に提供します。このプロジェクトでは、X軸とY軸のみを使用して決定します:

  • ドットを左または右(X軸)にどれだけ移動させるか
  • ドットを上下にどのくらい移動させるか(Y軸)

センサーの値は、0から7の座標範囲にマッピングされます(8×8 LEDマトリックス用)。ドットの位置は1秒間に何度も更新され、モジュールを傾けると滑らかなスライド効果が得られます。:contentReference[oaicite:3]{index=3}

プロジェクト4 - コード設定 (チルトドット)

プロジェクトのコードの上部近くにあるユーザーが編集可能な設定が以下に示されています。完全なスケッチは、記事の下に自動的に表示されます。

マトリックスピンとサイズ


// 8×8 RGB matrix configuration
const int MATRIX_PIN    = 14;   // fixed pin for this board
const int MATRIX_WIDTH  = 8;
const int MATRIX_HEIGHT = 8;

出るMATRIX_PIN14それはオンボードマトリックスにハードワイヤードされています。

明るさ


// Overall brightness (0–255)
uint8_t matrixBrightness = 40;

必要に応じて増やしてくださいが、近くで見るときは極端な明るさを避けてください。

ドットカラー


// Dot color (R, G, B)
uint8_t dotRed   = 0;
uint8_t dotGreen = 200;   // light green (default)
uint8_t dotBlue  = 0;

これらの値を変更して任意の色を作成します。例:

  • 赤色(255, 0, 0)
  • 黄色:(255, 255, 0)
  • 白色:(255, 255, 255)

動作感度

極端なジャンプを防ぐため、加速度計の値は通常制限またはスケーリングされます。典型的な設定は次のようになります:


// How aggressively tilt affects movement
float sensitivity = 4.0f;   // larger = faster movement across screen

点が動きすぎるほど遅い場合 → 値を増やしてください。点が動きすぎるほど急な場合 → 値を減らしてください。

更新速度(リフレッシュレート)

更新の間に小さな遅延を追加して動きを滑らかにすることができます:


// Delay between position updates (ms)
int refreshDelayMs = 20;   // lower = smoother and faster response

10~30ミリ秒の間の値は、非常に応答性が良く感じられます。

概要

プロジェクト4は、ESP32-S3に搭載されたQMI8658C加速度計を活用し、物理的な動きでLEDマトリックスをコントロールします。基板を少し傾けると、ドットが同じ方向に移動するため、このプロジェクトはより高度な「矢印上」や「ターゲットゲーム」プロジェクトへの完璧なステップストーンとなります。

この記事の下に完全なTilt Dotのスケッチが自動的にロードされています。最良の理解のために、ビデオでティルトデモンストレーションを見て、ボードが回転する際にドットがどれだけ滑らかに動くかを確認してください。ESP32-S3 RGB LEDマトリックスモジュールを購入するためのリンクは、コードセクションの下に含まれています。

画像

ESP32 S3 Matrix
ESP32 S3 Matrix
ESP32 S3 Matrix  pin out
ESP32 S3 Matrix pin out
ESP32-S3_RGB_8x8_matrix-3
ESP32-S3_RGB_8x8_matrix-3
ESP32 S3 Matrix displaying rainbow heart
ESP32 S3 Matrix displaying rainbow heart
ESP32-S3_RGB_8x8_matrix1
ESP32-S3_RGB_8x8_matrix1
ESP32-S3_RGB_8x8_matrix-2
ESP32-S3_RGB_8x8_matrix-2
802-ESP32-S3 RGB LED Matrix Project 4 - Tilt dot
言語: C++
/*
 * プロジェクト4: ティルトドット - ESP32-S3 RGB LEDマトリックス(Waveshare)
 * 
 * このスケッチは、QMI8658C IMUからティルトを読み取り、ボードの向きに基づいて8×8 RGB LEDマトリックス上でドットをスムーズに移動させます。
 * 
 * ▶️ ビデオチュートリアル:
 * https://youtu.be/JKLuYrRcLMI
 * 
 * 📚⬇️ リソースとコードページ:
 * https://robojax.com/RJT829
 * 
 * QMI8658_RGB_2
 */
#include <Arduino.h>
#include <math.h>

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#include <QMI8658.h> // ラハブ・ガハリによって

 // -------- LEDマトリックスセットアップ --------
#define MATRIX_PIN    14
#define MATRIX_WIDTH  8
#define MATRIX_HEIGHT 8

Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(
  MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_PIN,
  NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
  NEO_MATRIX_ROWS + NEO_MATRIX_PROGRESSIVE,
  NEO_RGB + NEO_KHZ800
);

 // -------- QMI8658 IMU セットアップ --------
QMI8658 imu;
QMI8658_Data imuData;

 // -------- ユーザー設定 --------

 // 真 -> 反対側の点: USB↔OUSB、34↔15
 // 偽 -> 上と同じ側の点
bool useOppositeMapping = false;

 // 点の色(各0-255)
uint8_t dotRed   = 0;
uint8_t dotGreen = 100;
uint8_t dotBlue  = 0;

 // 板の側面
enum Side {
  SIDE_CENTER = 0,
  SIDE_USB,
  SIDE_OUSB,
  SIDE_15,
  SIDE_34
};

 // スムーズなドット位置(ピクセル座標で、イージングのために浮動小数点として保持)
float dotPosX = 3.0f; // センターから始める
float dotPosY = 3.0f;

 // スムージングファクター:小さい = 動きが遅くなる (0.1 非常に遅い、0.5 より速い)
const float dotSmooth = 0.25f;


bool isFlat = false;

const char* sideName(Side s) {
  switch (s) {
    case SIDE_CENTER: return "CENTER";
    case SIDE_USB:    return "USB";
    case SIDE_OUSB:   return "OUSB";
    case SIDE_15:     return "15";
    case SIDE_34:     return "34";
    default:          return "?";
  }
}

 // キャリブレーションされた軸を使用して、どちらの側が上であるかを検出します。
 // +X = USB、-X = OUSB、+Y = 34、-Y = 15
Side detectSideUp(float ax_g, float ay_g, float az_g) {
 // フラット検出
  const float flatThreshXY = 0.15f;
  const float flatThreshZ  = 0.15f;

  if (fabs(ax_g) < flatThreshXY &&
      fabs(ay_g) < flatThreshXY &&
      fabs(az_g - 1.0f) < flatThreshZ) {
    isFlat = true;
    return SIDE_CENTER;
  }
  isFlat = false;

 // この軸は本当に傾いていると言うための閾値
  const float tiltThreshY = 0.5f;
  const float tiltThreshX = 0.5f;

 // 1) 明らかに傾いている場合は、15 / 34のY軸を優先してください。
  if (fabs(ay_g) >= tiltThreshY) {
    if (ay_g > 0) {
      return SIDE_15; // +Y = 34 上昇
    } else {
      return SIDE_34; // -Y = 15 上昇
    }
  }

 // 2) そうでなければ、USB / OUSB のために X 軸を確認してください。
  if (fabs(ax_g) >= tiltThreshX) {
    if (ax_g > 0) {
      return SIDE_USB; // +X = USB 上昇
    } else {
      return SIDE_OUSB; // -X = OUSB 上昇
    }
  }

 // 3) 何も強く傾いていなければ、それを中心と呼びます。
  return SIDE_CENTER;
}

 // UP側から点が行くべき場所までの地図
Side dotSideFromUpSide(Side upSide) {
  switch (upSide) {
    case SIDE_USB:
      return useOppositeMapping ? SIDE_OUSB : SIDE_USB;

    case SIDE_OUSB:
      return useOppositeMapping ? SIDE_USB : SIDE_OUSB;

    case SIDE_34:
      return useOppositeMapping ? SIDE_15 : SIDE_34;

    case SIDE_15:
      return useOppositeMapping ? SIDE_34 : SIDE_15;

    case SIDE_CENTER:
    default:
      return SIDE_CENTER;
  }
}

 // ドットサイドをマトリックス座標に変換する
void getDotPixel(Side dotSide, int &px, int &py) {
 // マトリックス (0,0) = 左上
 // トップセンター: (3,0) → USB
 // ボトムセンター: (3,7) → OUSB
 // 左中央: (0,3) → 15
 // 右中央: (7,3) → 34
 // センター: (3,3)

  switch (dotSide) {
    case SIDE_USB:   px = 3; py = 0; break;
    case SIDE_OUSB:  px = 3; py = 7; break;
    case SIDE_15:    px = 0; py = 3; break;
    case SIDE_34:    px = 7; py = 3; break;
    case SIDE_CENTER:
    default:         px = 3; py = 3; break;
  }
}

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

  matrix.begin();
  matrix.setBrightness(20);
  matrix.fillScreen(0);
  matrix.show();

 // IMU: SDA=11, SCL=12 は ESP32-S3-Matrix 用です
  if (!imu.begin(11, 12)) {
    Serial.println("Failed to initialize QMI8658!");
    while (1) { delay(1000); }
  }

  imu.setAccelUnit_mg(true);
  imu.setGyroUnit_dps(true);
  imu.setDisplayPrecision(4);

  Serial.print("QMI8658 initialized. useOppositeMapping = ");
  Serial.println(useOppositeMapping ? "TRUE" : "FALSE");
}

void loop() {
  if (!imu.readSensorData(imuData)) {
    return;
  }

  float ax_g = imuData.accelX / 1000.0f;
  float ay_g = imuData.accelY / 1000.0f;
  float az_g = imuData.accelZ / 1000.0f;

  Side upSide  = detectSideUp(ax_g, ay_g, az_g);
  Side dotSide = dotSideFromUpSide(upSide);

  int targetX, targetY;
  getDotPixel(dotSide, targetX, targetY);

 // --- 目標に向かってのスムーズな動き ---
  dotPosX += (targetX - dotPosX) * dotSmooth;
  dotPosY += (targetY - dotPosY) * dotSmooth;

 // 整数ピクセル座標に変換する
  int px = (int)round(dotPosX);
  int py = (int)round(dotPosY);

 // 念のためクランプをしてください
  if (px < 0) px = 0;
  if (px > 7) px = 7;
  if (py < 0) py = 0;
  if (py > 7) py = 7;

 // --- ドットを描く ---
  matrix.fillScreen(0);
  uint16_t color = matrix.Color(dotRed, dotGreen, dotBlue);
  matrix.drawPixel(px, py, color);
  matrix.show();

 // デバッグ
  Serial.print("AX="); Serial.print(ax_g, 3);
  Serial.print(" AY="); Serial.print(ay_g, 3);
  Serial.print(" AZ="); Serial.print(az_g, 3);
  Serial.print(" | UP=");  Serial.print(sideName(upSide));
  Serial.print(" | DOT="); Serial.print(sideName(dotSide));
  Serial.print(" | px=");  Serial.print(px);
  Serial.print(" py=");    Serial.println(py);

  delay(80);
}




必要かもしれないもの

リソースと参考文献

ファイル📁

フリッツィングファイル