This tutorial is part of: ESP32-S3 RGB LED Matrix
Cool project to create for fun and practical applications using ESP32-S3 RGB Matrix module. Links to other videos are below this article.
د ESP32-S3 RGB LED میټرکس پروژه ۶ - د هدف لوبه
پروژه ۶ – لوبه هدف (تختې ټیلټ کړئ ترڅو دایرې ته ورسیږئ)
پروژه ۶ وروستی او خورا متقابل پروژه ده په دې ESP32-S3 RGB LED میټرکس لړۍ کې. د آنبورډ QMI8658C حرکت سینسر په کارولو سره، تاسو تختې ټیلټ کوئ ترڅو یو نقطه د ۸×۸ میټرکس شاوخوا حرکت وکړي. یوه ګرده "هدف سیمه" د نندارې په مینځ کې ناسته ده. کله چې ستاسو نقطه دایرې ته لمس کوي، رنګ بدلیږي او (په اختیاري توګه) یو بزر غږیږي. دا یوه ساده مګر په حیرانونکي ډول ساتیري توازن/همغږۍ لوبه رامینځته کوي.
ټول شپږ پروژې په یوه واحد YouTube ویډیو کې نندارې ته وړاندې شوي (په دې پاڼه کې ځای پر ځای شوي). د لوبې بشپړ کوډ په اتوماتيک ډول د دې مقالې لاندې بار شوی، او د ماډل لپاره د اړوند پیرود لینکونه د کوډ برخې لاندې ښکاري.

د ESP32-S3 RGB LED میټرکس ماډل عمومي کتنه
دا ماډل لاندې شیان لري:

- ESP32-S3 مایکروکنټرولر (Wi-Fi + BLE)
- ۸×۸ RGB LED میټرکس (۶۴ د رسېدو وړ LEDs)
- QMI8658C اکسلرومیټر د ټیلټ او سمت احساس لپاره
- USB-C بندر د بریښنا او پروګرام کولو لپاره
- بوټ / ری سیٹ تڼۍ
- د GPIO پنونو شتون د اضافو لکه بزر یا سینسرونو لپاره
د دې لوبې لپاره، اکسلرومیټر اړین دی—دا په دوامداره توګه د X/Y ټیلټ راپور ورکوي، چې نقطې ته اجازه ورکوي د تختې د زاویې پر بنسټ په اسانۍ سره حرکت وکړي. د دې پروژې ویډیو برخه په روښانه توګه ښیې چې څنګه نقطه ګلیږي او عکس العمل ښیې کله چې تاسو ماډل کیڼ/ښي/مخ/شا ته ټیلټ کوئ.:contentReference[oaicite:0]{index=0}

په ویډیو کې پوښل شوي پروژې (وختونه)
- 00:00 – پیژندنه
- 02:01 – د ESP32 بورډونو نصبول
- 03:32 – د کتابتونونو نصبول
- 05:32 – پروژه ۱: حرکت کوونکې نقطه
- 11:11 – پروژه ۲: متن سکرول
- 12:59 – پروژه ۳: HTTP متن
- 16:41 – پروژه ۴: ټیلټ نقطه
- 18:55 – پروژه ۵: پورته تیر
- 20:02 – پروژه ۶: لوبه هدف (دا پروژه)
د ویډیو دا برخه د نقطې حرکت او د دایرې کشف منطق دواړه په عمل کې ښیې، چې دا پوهیدل اسانه کوي چې همغږۍ څنګه چلند کوي.:contentReference[oaicite:1]{index=1}

په Arduino IDE کې د ESP32 بورډونو نصبول
که تاسو دمخه مخکینۍ پروژې بشپړې کړې وي، د بورډ نصبول ترسره شوي. په بل ډول لاندې تعقیب کړئ:
File > Preferences→ د ESP32 بورډ URL اضافه کړئ.Tools > Board > Boards Manager…→ "ESP32" نصب کړئ.- د
Tools > Boardلاندې د ESP32-S3 بورډ غوره کړئ. - د
Tools > Portلاندې سم COM بندر غوره کړئ.
د اړینو کتابتونونو نصبول
دا لوبه کاروي:
Adafruit NeoMatrixAdafruit NeoPixelAdafruit GFXQMI8658(د حرکت سینسر)
دوی د لاندې له لارې نصب کړئ:
Sketch > Include Library > Manage Libraries…- لټون: NeoMatrix → نصب کړئ
- انحصارونه نصب کړئ (GFX + NeoPixel)
- لټون او نصب کړئ QMI8658
د هدف لوبه څنګه کار کوي
د QMI8658C اکسلرومیټر د X او Y ټیلټ ارزښتونه چمتو کوي. دا د LED همغږیو (په دواړو لارښوونو کې ۰–۷) ته نقشه شوي. ستاسو نقطه د تختې د زاویې پر بنسټ په میټرکس کې حرکت کوي.
یوه دایره (یا حلقه) د "هدف سیمې" په توګه په نندارې کې رسم شوې. تاسو هرکله چې نقطه دایرې سره یو ځای شي یو "ضربه" ګټئ. په هغه شیبه کې:
- د هدف رنګ بدلیږي (تصادفي یا دمخه ټاکل شوی)
- یو اختیاري بزر غږیږي (که وصل وي)
څرنګه چې میټرکس کوچنی دی، دایره د ساده وړانګې چک په کارولو سره رسم شوې. لوبه په دوامداره توګه روانه ده، نو تاسو کولی شئ بیرته او مخ ته ټیلټ کړئ ترڅو دایرې ته په مکرر ډول ورشئ.
پروژه ۶ – د کوډ ترتیبات (د هدف لوبه)
لاندې اصلي کاروونکي-د بدلون وړ ترتیبات دي چې د سکیچ په سر کې موقعیت لري. بشپړ کوډ په اتوماتيک ډول د دې مقالې لاندې شامل دی.
د میټرکس تشکیلات
// د میټرکس تشکیلات
const int MATRIX_PIN = 14;
const int MATRIX_WIDTH = 8;
const int MATRIX_HEIGHT = 8;
د RGB میټرکس په کلکه سره GPIO 14 پورې تړلی دی—دا مه بدلوئ.
روښانتیا
uint8_t matrixBrightness = 40; // ۰–۲۵۵
د کورني استعمال لپاره، ۳۰–۶۰ مثالی دی.
د نقطې رنګ
// د نقطې رنګ (R, G, B)
uint8_t dotRed = 255;
uint8_t dotGreen = 255;
uint8_t dotBlue = 255;
دا هغه نقطه ده چې تاسو د تختې په ټیلټ کولو سره حرکت ورکوئ.
د دایرې رنګ (تصادفي یا ثابت)
// د دایرې (هدف) رنګ
uint8_t circleRed = 0;
uint8_t circleGreen = 0;
uint8_t circleBlue = 255;
// که ریښتیا وي، هر ځل چې نقطه ووهي یو نوی تصادفي رنګ غوره کړئ
bool randomCircleColor = true;
که تاسو ثابت رنګ غواړئ randomCircleColor = false; وټاکئ.
د دایرې وړانګه
// د هدف اندازه (وړانګه)
int targetRadius = 3; // ۳ په ۸×۸ میټرکس کې ښه فټ کیږي
لویې وړانګې لوبه اسانه کوي؛ کوچنۍ یې سخته کوي.
د ټیلټ حساسیت
// د ټیلټ نقشه کولو حساسیت
float tiltScale = 4.0f; // زیاتوالی = په سکرین کې ګړندی حرکت
که نقطه ډیر ګړندی حرکت وکړي یا ټوپ ووهي، دا شمېره کمه کړئ.
د بزر ترتیبات (اختیاري)
// د بوزر پن (اختیاري)
int buzzerPin = 6; // د بوزر مثبت قطب په پن 6 سره وصل کړئ، او منفي قطب په GND سره
bool useBuzzer = true; // د غږ غیر فعالولو لپاره false وټاکئ
که تاسو بوزر نه نښلوئ، په ساده ډول useBuzzer = false; وټاکئ
لنډیز
پروژه 6 د پخوانیو پروژو څخه زده شوي هرڅه سره یوځای کوي: د میټرکس انځورول، د اکسلرومیټر داخلول، د رنګ کنټرول، د حرکت نرموالی، او اختیاري غږ. د بورډ ټیلټ کول نقطه حرکت کوي، او دایرې ته لمس کول د هغې رنګ بدلوي او (په اختیاري توګه) یو بیپ رامینځته کوي. دا په یوه کمپیکٹ RGB ډسپلې کې د حرکت احساس کولو یوه ساتیرۍ بیلګه ده.
د "Target Game" بشپړ کوډ په اتوماتيک ډول د دې مقالې لاندې ښودل شوی. تاسو کولی شئ د ویډیو د پروژې 6 برخه هم وګورئ ترڅو وګورئ چې نقطه څنګه حرکت کوي او لمس څنګه کشف کیږي. که تاسو غواړئ خپله لوبه جوړه کړئ، د ESP32-S3 RGB LED میټرکس ماډل پیرودلو لپاره اړونده لینکونه د کوډ برخې لاندې ښکاري.
This tutorial is part of: ESP32-S3 RGB LED Matrix
- د ESP32-S3 RGB LED میټرکس پروژه ۱ - بنسټیز ډاټ
- د ESP32-S3 RGB LED میټرکس پروژه ۲ - سکرول کېدونکی متن
- د ESP32-S3 RGB LED میټرکس پروژه ۳ - د ګرځنده تلیفون څخه متن
- ESP32-S3 RGB LED میټرکس پروژه ۴ - ټیلټ ډاټ
- د ESP32-S3 RGB LED میټرکس پروژه ۵ - تل پورته تیر
- د ESP32-S3 RGB LED میټرکس وای-فای + NTP وخت ساعت پروژه -1 اساسي ساعت
- د ESP32-S3 RGB LED میټرکس انټرنیټ ساعت پروژه - ۲ ساعت څو رنګه وخت او نېټه ښودنه
- د ESP32-S3 RGB LED میټرکس انټرنیټ ساعت پروژه - ۳ د شپې رنګونه د نیټې سره
- د ESP32-S3 RGB LED میټرکس انټرنیټ ساعت پروژه - 5 د رینبو رنګ
- د ESP32-S3 RGB LED میټرکس انټرنیټ ساعت پروژه - ۴ تصادفي رنګونه
- ESP32-S3 RGB LED Matrix test for RGB, GRB setting
/*
Project 6: Tilt Circle Game – ESP32-S3 RGB LED Matrix (Waveshare)
This sketch reads tilt from the QMI8658C IMU and smoothly moves a dot
on the 8×8 RGB LED matrix based on board orientation.
▶️ Video Tutorial:
https://youtu.be/JKLuYrRcLMI
📚⬇️ Resources & Code Page:
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> // by Lahav Gahali
// -------- LED MATRIX SETUP --------
#define MATRIX_PIN 14
#define MATRIX_WIDTH 8
#define MATRIX_HEIGHT 8
// Buzzer pin – change this to your actual buzzer GPIO.
const int BUZZER_PIN = 6; // TODO: set to your buzzer pin
// Matrix brightness (0–255)
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 SETUP --------
QMI8658 imu;
// -------- GAME CONFIG --------
// How often the dot is allowed to move (ms).
// Bigger = slower movement.
const uint16_t MOVE_INTERVAL_MS = 150; // try 120–250
// How much tilt (m/s^2) before the dot moves.
// Increase if it feels too sensitive.
const float ACC_TILT_THRESHOLD = 2.0f; // about ~0.2 g
// Dot base color (RGB)
const uint8_t DOT_R = 255;
const uint8_t DOT_G = 255;
const uint8_t DOT_B = 255;
// Circle geometry (centered on 8x8)
const float CIRCLE_CENTER_X = (MATRIX_WIDTH - 1) / 2.0f; // 3.5
const float CIRCLE_CENTER_Y = (MATRIX_HEIGHT - 1) / 2.0f; // 3.5
const float CIRCLE_RADIUS = 3.0f;
const float CIRCLE_THICKNESS = 0.8f; // +- thickness around radius
// -------- GAME STATE --------
// Dot position on the 8x8 grid (0..7)
int dotX = 3;
int dotY = 3;
// Colors (16-bit NeoMatrix colors)
uint16_t dotColor;
uint16_t circleColor;
// To detect “just touched circle” vs “still on circle”
bool wasOnCircle = false;
// Timer for rate-limiting movement
unsigned long lastMoveTime = 0;
// -------- HELPER FUNCTIONS --------
// Classic NeoPixel color wheel (0-255 -> rainbow)
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);
}
}
// Is a given pixel approximately on the circle?
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);
}
// Draw circle + dot
void drawScene() {
matrix.fillScreen(0);
// Draw circle
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);
}
}
}
// Draw dot (on top)
matrix.drawPixel(dotX, dotY, dotColor);
matrix.show();
}
// Simple blocking beep (short)
void buzzOnce() {
digitalWrite(BUZZER_PIN, HIGH);
delay(40);
digitalWrite(BUZZER_PIN, LOW);
}
// Use accelerometer to decide dot movement
void updateDotFromTilt(float ax, float ay) {
unsigned long now = millis();
if (now - lastMoveTime < MOVE_INTERVAL_MS) {
return; // too soon, wait
}
int dx = 0;
int dy = 0;
// On this board, Y tilt feels like "left/right" on the matrix,
// and X tilt feels like "up/down" → so we swap.
// --- Horizontal movement from AY (tilt left/right) ---
if (ay > ACC_TILT_THRESHOLD) {
dx = 1; // tilt to the right → move dot to the right
} else if (ay < -ACC_TILT_THRESHOLD) {
dx = -1; // tilt to the left → move dot to the left
}
// --- Vertical movement from AX (tilt forward/back) ---
// This was inverted. We flip the signs:
// ax > threshold = tilt "forward" (away) → move dot UP (dy = -1)
// ax < -threshold = tilt "back" (toward)→ move dot DOWN(dy = 1)
if (ax > ACC_TILT_THRESHOLD) {
dy = -1; // was +1 before
} else if (ax < -ACC_TILT_THRESHOLD) {
dy = 1; // was -1 before
}
if (dx != 0 || dy != 0) {
dotX = constrain(dotX + dx, 0, MATRIX_WIDTH - 1);
dotY = constrain(dotY + dy, 0, MATRIX_HEIGHT - 1);
lastMoveTime = now;
}
}
// -------- SETUP & LOOP --------
void setup() {
Serial.begin(115200);
delay(100);
// Matrix init
matrix.begin();
matrix.setBrightness(MATRIX_BRIGHTNESS);
matrix.fillScreen(0);
matrix.show();
// Buzzer init
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
// IMU init
if (!imu.begin(11, 12)) {
Serial.println("Failed to initialize QMI8658!");
while (1) {
delay(100);
}
}
// Use m/s^2 and dps (optional, but nice)
imu.setAccelUnit_mps2(true);
imu.setGyroUnit_dps(true);
imu.setDisplayPrecision(3);
Serial.println("QMI8658 initialized.");
// Game initial state
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() {
// Read accelerometer
float ax, ay, az;
if (imu.readAccelMPS2(ax, ay, az)) {
// Debug if needed:
// Serial.print("AX: "); Serial.print(ax);
// Serial.print(" AY: "); Serial.print(ay);
// Serial.print(" AZ: "); Serial.println(az);
updateDotFromTilt(ax, ay);
}
// Check collision with circle
bool onCircle = isOnCircle(dotX, dotY);
if (onCircle && !wasOnCircle) {
// Just touched circle: change color + beep
circleColor = wheel(random(256));
buzzOnce();
}
wasOnCircle = onCircle;
// Redraw
drawScene();
// Small delay so we don’t hammer I2C too hard
delay(10);
}
Things you might need
-
Amazon
-
eBay
-
AliExpressPurchase ESP32-S3 RGB Matrix from AliExpresss.click.aliexpress.com
-
AliExpressPurchase ESP32-S3 RGB Matrix from AliExpress (2)s.click.aliexpress.com
Resources & references
-
Internal🎨 Color picker Toolrobojax.com
Files📁
Fritzing File
-
esp32-S3-supermini-tht fritzing part
esp32-S3-supermini-tht.fzpz0.02 MB