شِفر (کود) جستجو

پروژه ماتریس LED RGB ESP32-S3 4 - نقطه کج

پروژه ماتریس LED RGB ESP32-S3 4 - نقطه کج

پروژه ۴ - نقطه کج (حرکت نقطه با کج کردن ماتریس LED RGB ESP32-S3)

پروژه ۴ حساس(حس کننده) حرکتی را که در ماجیول ماتریس LED RGB ESP32-S3 تعبیه شده است، معرفی می‌کند. به جای اینکه نقطه به صورت خودکار حرکت کند (مانند پروژه ۱) یا متن پیمایش شود (پروژه‌های ۲ و ۳)، این پروژه به شما امکان می‌دهد موقعیت نقطه را تنها با کج کردن تخته کنترل کنید. نقطه به آرامی بر اساس خوانش‌های زنده از شتاب‌سنج QMI8658C در قسمت پشتی ماجیول، بر روی نمایشگر RGB ۸×۸ حرکت می‌کند.

تمام شش پروژه در این سری در یک ویدیوی یوتیوب نمایش داده شده‌اند. همان ویدیو در این صفحه درج شده است، بنابراین می‌توانید ببینید که نقطه به‌صورت زنده چگونه حرکت می‌کند در حالی که تخته کج می‌شود. شِفر (کود) کامل این پروژه به‌طور خودکار در زیر مقاله بارگذاری شده است و واصل‌های خرید وابسته برای ماجیول در زیر بخش شِفر (کود) ظاهر می‌شود.

بررسی ماجیول ماتریس LED RGB ESP32-S3

این پروژه از ماجیول ماتریس LED RGB ESP32-S3 استفاده می‌کند که شامل:

  • میکروکنترلر ESP32-S3با Wi-Fi و بلوتوث
  • ماتریس LED RGB ۸×۸(64 لامپ LED با آدرس‌دهی جداگانه)
  • شتاب سنج QMI8658Cدر پشت برای تشخیص زاویه و حرکت
  • پورت USBبرای برنامه‌نویسی و قدرت
  • دکمه‌های راه‌اندازی / بازنشانی
  • پایه‌های GPIO قابل استفادهبرای توسعه آینده

حساس(حس کننده) QMI8658C می‌خواندایکس,Y, andزمقادیر شتاب و جهت‌گیری، اجازه می‌دهد نقطه به بالا/پایین/چپ/راست حرکت کند بر اساس اینکه برد چگونه متمایل است.:contentReference[oaicite:0]{index=0}

پروژه‌های پوشش داده شده در ویدیو (زمان‌های مشخص)

  • ۰۰:۰۰- مقدمه
  • 02:01- نصب بوردهای ESP32
  • ۰۳:۳۲- نصب کتابخانه‌ها
  • ۰۵:۳۲- پروژه ۱: نقطه متحرک
  • ۱۱:۱۱- پروژه ۲: اسکرول متن
  • ۱۲:۵۹پروژه ۳: متن HTTP
  • ۱۶:۴۱-پروژه ۴: نقطه مایل (این پروژه)
  • ۱۸:۵۵- پروژه ۵: پیکان بالا
  • ۲۰:۰۲- پروژه ۶: بازی هدف

مشاهده ویدیو демонстрация کج شدن بسیار توصیه می‌شود، زیرا می‌توانید ببینید که نقطه چگونه به آرامی به جهت تخته واکنش نشان می‌دهد.:contentReference[oaicite:1]{index=1}

نصب بردهای ESP32 در Arduino IDE

اگر پروژه‌ای قبلی را کامل کرده‌اید، پشتیبانی بورد قبلاً نصب شده است. در غیر این صورت، مراحل زیر را دنبال کنید:

  1. باز کنیدFile > Preferences→ آدرس بوردهای ESP32 را اضافه کنید.
  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. جستجو برایآداگفٹ نیوماتریکس→ نصب کنید.
  3. اجازه نصب خودکار دهیدادافروت جی‌اف‌ایکسوآدافروت نئوپیکسل.
  4. جستجو برایQMI8658توسط نویسنده فهرست شده خود → نصب.:contentReference[oaicite:2]{index=2}

چگونه پروژه ۴ کار می‌کند

حساس(حس کننده) QMI8658C به‌طور مداوم داده‌های شتاب را در طول محورهای X، Y و Z فراهم می‌کند. برای این پروژه، ما فقط از محورهای X و Y برای تصمیم‌گیری استفاده می‌کنیم:

  • چقدر باید نقطه را به سمت چپ یا راست (محور X) جابجا کنیم؟
  • چقدر باید نقطه را بالا یا پایین ببریم (محور Y)

مقدارهای حساس(حس کننده) در یک دامنه مختصاتی از 0 تا 7 (برای ماتریس LED 8×8) نگاشت شده‌اند. موقعیت نقطه بارها در هر ثانیه به‌روزرسانی می‌شود و اثر لغزش ملایمی را هنگام کج کردن ماجیول ایجاد می‌کند.:contentReference[oaicite:3]{index=3}

پروژه ۴ - تنظیمات شِفر (کود) (نقطه مایل)

در زیر تنظیمات قابل ویرایش توسط کاربر که در نزدیکی بالای شِفر (کود) پروژه یافت می‌شود، آمده است. طرح کامل به‌طور خودکار زیر مقاله ظاهر می‌شود.

پایه و اندازه ماتریس


// 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_PINدر14این به طور مستقیم به ماتریس onboard متصل است.

روشنایی


// 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 شتاب‌سنج داخلی QMI8658C ESP32-S3 را به کار می‌گیرد و به شما اجازه می‌دهد که ماتریس LED را با حرکات فیزیکی کنترل کنید. یک مایل کوچک از برد، نقطه را به همان سمت حرکت می‌دهد و این پروژه را به سنگ بنایی مناسب برای پروژه‌های پیشرفته‌تر "فلش بالا" و "بازی هدف" تبدیل می‌کند.

اسکچ کامل Tilt Dot پایین این مقاله (به طور خودکار) بارگذاری شده است. برای درک بهتر، ویدیو نمایش شیب را تماشا کنید، جایی که می‌توانید ببینید نقطه چطور به نرمی حرکت می‌کند در حالی که تخته چرخانده می‌شود. واصل‌هایی برای خرید ماجیول ماتریس LED RGB ESP32-S3 در بخش شِفر (کود) گنجانده شده است.

تصاویر

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++
/*
 * پروژه ۴: نقطه مایل - ماتریس LED RGB ESP32-S3 (Waveshare)
 * 
 * این طرح انحراف را از IMU QMI8658C خوانده و به آرامی یک نقطه را بر اساس جهت‌گیری برد بر روی ماتریس LED RGB ۸×۸ حرکت می‌دهد.
 * 
 * ▶️ ویدیو آموزشی:
 * 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
);

 // -------- تنظیم IMU QMI8658 --------
QMI8658 imu;
QMI8658_Data imuData;

 // -------- تنظیمات کاربر --------

 // حقیقت -> نقطه در طرف مقابل: USB↔OUSB، 34↔15
 // کاذب -> نقطه در همان سمت با بالا
bool useOppositeMapping = false;

 // رنگ نقطه (۰-۲۵۵ هر کدام)
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 = یو اس بی، -X = او یو اس بی، +Y = ۳۴، -Y = ۱۵
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;

 // محور Y را برای ۱۵ / ۳۴ در صورتی که به وضوح کج باشد ترجیح دهید.
  if (fabs(ay_g) >= tiltThreshY) {
    if (ay_g > 0) {
      return SIDE_15; // +Y = ۳۴ بالا
    } else {
      return SIDE_34; // -Y = 15 بالا
    }
  }

 // ۲) در غیر این صورت، محور X را برای USB / OUSB بررسی کنید.
  if (fabs(ax_g) >= tiltThreshX) {
    if (ax_g > 0) {
      return SIDE_USB; // +X = USB بالا
    } else {
      return SIDE_OUSB; // -X = OUSB بالا
    }
  }

 // اگر هیچ چیزی به شدت کج نشده است، فقط آن را مرکز بنامید.
  return SIDE_CENTER;
}

 // نقشه‌ای از سمت بالا به جایی که نقطه باید برود
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) → او اس یو بی
 // چپ مرکز: (0,3) → 15
 // مرکز راست: (7,3) → 34
 // مرکز: (۳،۳)

  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=۱۱، SCL=۱۲ برای 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);
}




مواردی که ممکن است به آن‌ها نیاز داشته باشید

منابع و مراجع

فایل‌ها📁

فایل فریزینگ