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

پروژه ماتریس LED RGB ESP32-S3 6 - بازی Cible

پروژه ماتریس LED RGB ESP32-S3 6 - بازی Cible

پروژه 6 - بازی هدف (تخت را کج کنید تا دایره را بزنید)

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

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

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

این ماجیول شامل:

  • میکروکنترلر ESP32-S3(Wi-Fi + BLE)
  • ماتریس LED RGB ۸×۸(۶۴ LED قابل آدرس‌دهی)
  • شتاب‌سنج QMI8658Cبرای حس کردن زاویه و انحراف
  • یواس‌بی-Cپورت برای قدرت و برنامه‌نویسی
  • راه‌اندازی مجدد / بازنشانیدکمه‌ها
  • موجودپایه‌های GPIOبرای افزودنی‌هایی مانند زنگ‌ها یا حسگرها

برای این بازی، شتاب‌سنج ضروری است - به طور مداوم شیب X/Y را گزارش می‌کند و به نقطه اجازه می‌دهد تا نرم و بدون مشکل بر اساس زاویه تخته حرکت کند. بخش ویدیویی این پروژه به وضوح نشان می‌دهد که چگونه نقطه به آرامی حرکت می‌کند و واکنش نشان می‌دهد زمانی که ماجیول را به چپ/راست/جلو/عقب مایل می‌کنید.:contentReference[oaicite:0]{index=0}

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

  • ۰۰:۰۰- مقدمه
  • ۰۰:۰۲- نصب بردهای ESP32
  • ۰۳:۳۲- نصب کتابخانه‌ها
  • ۰۵:۳۲- پروژه ۱: نقطه متحرک
  • ۱۱:۱۱- پروژه ۲: پیمایش متن
  • ۱۲:۵۹- پروژه 3: متن 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
  • QMI8658(حساس(حس کننده) حرکتی)

آنها را از طریق نصب کنید:

  1. Sketch > Include Library > Manage Libraries…
  2. جستجو:نئو ماتریکس→ نصب
  3. نصب وابستگی‌ها (GFX+نیوپیکسل)
  4. جستجو و نصبQMI8658

طرز کار بازی هدف

شتاب‌سنج QMI8658C مقادیر کج‌شدگی X و Y را ارائه می‌دهد. این مقادیر به مختصات LED (۰-۷ در هر دو جهت) نگاشته شده‌اند. نقطه شما بر اساس زاویه برد، در ماتریس حرکت می‌کند.

یک دایره (یا حلقه) بر روی نمایشگر به عنوان "منطقه هدف" ترسیم شده است. هر زمان که نقطه با دایره همپوشانی داشته باشد، شما یک "ضربه" برنده می‌شوید. در آن لحظه:

  • رنگ هدف تغییر می‌کند (تصادفی یا از قبل تعیین‌شده)
  • یک زنگ اختیاری بیپ می‌زند (در صورت اتصال)

از آنجایی که ماتریس کوچک است، دایره با استفاده از یک بررسی ساده شعاع ترسیم می‌شود. بازی به طور مداوم اجرا می‌شود، بنابراین می‌توانید به جلو و عقب مایل شوید تا به طور مکرر دایره را ضربه بزنید.

پروژه ۶ - تنظیمات شِفر (کود) (بازی هدف)

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

پیکربندی ماتریس


// Matrix configuration
const int MATRIX_PIN    = 14;
const int MATRIX_WIDTH  = 8;
const int MATRIX_HEIGHT = 8;

ماتریس RGB به GPIO 14 متصل است - این را تغییر ندهید.

درخشندگی


uint8_t matrixBrightness = 40;   // 0–255

برای استفاده در داخل ساختمان، ۳۰-۶۰ ایده‌آل است.

رنگ نقطه


// Dot color (R, G, B)
uint8_t dotRed   = 255;
uint8_t dotGreen = 255;
uint8_t dotBlue  = 255;

این نقطه‌ای است که با کج کردن تخته جابه‌جا می‌کنید.

رنگ دایره (تصادفی یا ثابت)


// Circle (target) color
uint8_t circleRed   = 0;
uint8_t circleGreen = 0;
uint8_t circleBlue  = 255;

// If true, choose a new random color each time the dot hits
bool randomCircleColor = true;

تنظیمrandomCircleColor = false;اگر شما یک رنگ ثابت می‌خواهید.

شعاع دایره


// Target size (radius)
int targetRadius = 3;   // 3 fits well on 8×8 matrix

شعاع‌های بزرگ‌تر بازی را آسان‌تر می‌کنند؛ در حالی که شعاع‌های کوچک‌تر آن را سخت‌تر می‌کنند.

حساسیت کج شدن


// Sensitivity of tilt mapping
float tiltScale = 4.0f;   // increase = faster movement across screen

اگر نقطه خیلی سریع حرکت کند یا بپرد، این عدد را کاهش دهید.

تنظیمات بوق (اختیاری)


// Buzzer pin (optional)
int buzzerPin = 6;      // connect buzzer + to pin 6, – to GND
bool useBuzzer = true;  // set false to disable sound

اگر یک زنگ وصل نکنید، به سادگی تنظیم کنیدuseBuzzer = false;

خلاصه

پروژه ۶ همه چیزهایی که از پروژه‌های قبلی آموخته شده را ترکیب می‌کند: طراحی ماتریسی، ورودی شتاب‌سنج، کنترل رنگ، نرم کردن حرکت و صدای اختیاری. کج کردن بورد نقطه را حرکت می‌دهد و ضربه به دایره، رنگ آن را تغییر می‌دهد و (اختیاری) یک بیپ ایجاد می‌کند. این یک نمایش سرگرم‌کننده از حساس(حس کننده) حرکت در یک نمایشگر RGB جمع و جور است.

شِفر (کود) کامل "بازی هدف" به طور خودکار زیر این مقاله نمایش داده می‌شود. شما همچنین می‌توانید بخش پروژه 6 این ویدئو را تماشا کنید تا ببینید نقطه چگونه حرکت می‌کند و چطور برخوردها شناسایی می‌شوند. اگر می‌خواهید بازی خود را بسازید، واصل‌های وابسته برای خرید ماجیول 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 3
ESP32 S3 Matrix displaying rainbow heart 3
ESP32-S3_RGB_8x8_matrix1
ESP32-S3_RGB_8x8_matrix1
ESP32-S3_RGB_8x8_matrix-2
ESP32-S3_RGB_8x8_matrix-2
804-ESP32-S3 RGB LED Matrix Project 6 - Cible game
زبان: 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

 // پایه بوزر - این را به GPIO بوزر واقعی خود تغییر دهید.
const int BUZZER_PIN = 6; // TODO: شماره پایه زنگ سر خود را تنظیم کنید

 // درخشندگی ماتریس (۰-۲۵۵)
const uint8_t MATRIX_BRIGHTNESS = 10;

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

 // -------- راه‌اندازی IMU --------
QMI8658 imu;

 // -------- پیکربندی بازی --------

 // تعداد دفعاتی که نقطه مجاز به حرکت است (میلی‌ثانیه).
 // بزرگ‌تر = حرکت کندتر.
const uint16_t MOVE_INTERVAL_MS = 150; // تلاش کنید ۱۲۰-۲۵۰

 // چقدر شیب (متر بر ثانیه مربع) قبل از اینکه نقطه حرکت کند.
 // اگر احساس می‌کنید خیلی حساس است، افزایش دهید.
const float ACC_TILT_THRESHOLD = 2.0f; // حدود ~0.2 گرم

 // رنگ پایه دات (RGB)
const uint8_t DOT_R = 255;
const uint8_t DOT_G = 255;
const uint8_t DOT_B = 255;


 // هندسه دایره (تمرکز بر روی 8x8)
const float CIRCLE_CENTER_X = (MATRIX_WIDTH - 1) / 2.0f; // ۳.۵
const float CIRCLE_CENTER_Y = (MATRIX_HEIGHT - 1) / 2.0f; // ۳.۵
const float CIRCLE_RADIUS   = 3.0f;
const float CIRCLE_THICKNESS = 0.8f; // ضخامت در اطراف شعاع

 // -------- وضعیت بازی --------

 // موقعیت نقطه در شبکه ۸x۸ (۰..۷)
int dotX = 3;
int dotY = 3;

 // رنگ‌ها (رنگ‌های 16 بیتی NeoMatrix)
uint16_t dotColor;
uint16_t circleColor;

 // برای تشخیص "فقط لمس شده دایره" در مقابل "هنوز بر روی دایره"
bool wasOnCircle = false;

 // تایمر برای محدود کردن حرکت
unsigned long lastMoveTime = 0;

 // -------- توابع کمکی --------

 // چرخ رنگ نئوپیکسل کلاسیک (۰-۲۵۵ -> رنگین‌کمان)
uint16_t wheel(byte pos) {
  if (pos < 85) {
    return matrix.Color(pos * 3, 255 - pos * 3, 0);
  } else if (pos < 170) {
    pos -= 85;
    return matrix.Color(255 - pos * 3, 0, pos * 3);
  } else {
    pos -= 170;
    return matrix.Color(0, pos * 3, 255 - pos * 3);
  }
}

 // آیا یک پیکسل مشخص تقریباً روی دایره است؟
bool isOnCircle(int x, int y) {
  float dx = x - CIRCLE_CENTER_X;
  float dy = y - CIRCLE_CENTER_Y;
  float d2 = dx * dx + dy * dy;

  float rMin = CIRCLE_RADIUS - CIRCLE_THICKNESS;
  float rMax = CIRCLE_RADIUS + CIRCLE_THICKNESS;

  return (d2 >= rMin * rMin) && (d2 <= rMax * rMax);
}

 // دایره + نقطه بکشید
void drawScene() {
  matrix.fillScreen(0);

 // دایره بکشید
  for (int y = 0; y < MATRIX_HEIGHT; y++) {
    for (int x = 0; x < MATRIX_WIDTH; x++) {
      if (isOnCircle(x, y)) {
        matrix.drawPixel(x, y, circleColor);
      }
    }
  }

 // نقطه بکشید (بالا)
  matrix.drawPixel(dotX, dotY, dotColor);

  matrix.show();
}

 // بوق مسدود ساده (کوتاه)
void buzzOnce() {
  digitalWrite(BUZZER_PIN, HIGH);
  delay(40);
  digitalWrite(BUZZER_PIN, LOW);
}

 // از شتاب‌سنج برای تعیین حرکت نقطه استفاده کنید
void updateDotFromTilt(float ax, float ay) {
  unsigned long now = millis();
  if (now - lastMoveTime < MOVE_INTERVAL_MS) {
    return; // بیش از حد زود است، صبر کن
  }

  int dx = 0;
  int dy = 0;

 // در این تخته، زاویه Y به نظر می‌رسد که مانند "چپ/راست" در ماتریس باشد،
 // و زاویه X حس می‌کند که "بالا/پایین" → بنابراین ما تعویض می‌کنیم.

 // --- حرکت افقی از AY (چرخش به چپ/راست) ---
  if (ay > ACC_TILT_THRESHOLD) {
    dx = 1; // به سمت راست کج کن → نقطه را به سمت راست حرکت بده
  } else if (ay < -ACC_TILT_THRESHOLD) {
    dx = -1; // به سمت چپ کج کن → نقطه را به سمت چپ حرکت بده
  }

 // --- حرکت عمودی از AX (تکانه به جلو/عقب) ---
 // این معکوس شد. ما علامت‌ها را برعکس می‌کنیم:
 // ax > آستانه = شیب "به جلو" (به عقب) → حرکت نقطه به بالا (dy = -1)
 // ax < -threshold = کج "به عقب" (سمت)→ حرکت نقطه DOWN(dy = 1)
  if (ax > ACC_TILT_THRESHOLD) {
    dy = -1; // قبل +1 بود
  } else if (ax < -ACC_TILT_THRESHOLD) {
    dy = 1; // قبل -1 بود
  }

  if (dx != 0 || dy != 0) {
    dotX = constrain(dotX + dx, 0, MATRIX_WIDTH  - 1);
    dotY = constrain(dotY + dy, 0, MATRIX_HEIGHT - 1);
    lastMoveTime = now;
  }
}


 // -------- راه‌اندازی و حلقه --------

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

 // ماتریس اولیه
  matrix.begin();
  matrix.setBrightness(MATRIX_BRIGHTNESS);
  matrix.fillScreen(0);
  matrix.show();

 // بوق اولیه
  pinMode(BUZZER_PIN, OUTPUT);
  digitalWrite(BUZZER_PIN, LOW);

 // مقدمه IMU
if (!imu.begin(11, 12)) {
    Serial.println("Failed to initialize QMI8658!");
    while (1) {
      delay(100);
    }
  }

 // از m/s^2 و dps (اختیاری، اما خوب است) استفاده کنید
  imu.setAccelUnit_mps2(true);
  imu.setGyroUnit_dps(true);
  imu.setDisplayPrecision(3);

  Serial.println("QMI8658 initialized.");

 // وضعیت اولیه بازی
  randomSeed((uint32_t)micros());

  dotX = MATRIX_WIDTH  / 2;
  dotY = MATRIX_HEIGHT / 2;

  dotColor    = matrix.Color(DOT_R, DOT_G, DOT_B);
  circleColor = wheel(random(256));

  drawScene();
}

void loop() {
 // شتاب‌سنج را بخوانید
  float ax, ay, az;
  if (imu.readAccelMPS2(ax, ay, az)) {
 // در صورت نیاز اشکال‌زدایی کنید:
 // سریال.print("AX: "); سریال.print(ax);
 // Serial.print(" AY: "); Serial.print(ay);
 //  AZ:  az;

    updateDotFromTilt(ax, ay);
  }

 // بررسی برخورد با دایره
  bool onCircle = isOnCircle(dotX, dotY);
  if (onCircle && !wasOnCircle) {
 // فقط دایره را لمس کرد: تغییر رنگ + بوق
    circleColor = wheel(random(256));
    buzzOnce();
  }
  wasOnCircle = onCircle;

 // بازطراحی
  drawScene();

 // تأخیر کوچک تا زیاد به I2C فشار نیاوریم
  delay(10);
}

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

منابع و مراجع

فایل‌ها📁

فایل فریزینگ