This tutorial is part of: ESP32-S3 RGB LED matrica
Kul projekat za kreiranje zabave i praktičnih aplikacija korištenjem ESP32-S3 RGB Matrix modula. Linkovi do drugih videa nalaze se ispod ovog članka.
ESP32-S3 RGB LED Matrix projekat 6 - Cible igra
Projekat 6 – Igra s metom (Naginji ploču da pogodiš krug)
Projekat 6 je posljednji i najinteraktivniji projekat u ovoj ESP32-S3 RGB LED matrici seriji. Koristeći ugrađeni QMI8658C senzor pokreta, naginješ ploču da pomjeriš tačku po 8×8 matrici. Kružna “ciljna zona” nalazi se u sredini ekrana. Kada tvoja tačka dodirne krug, boja se mijenja i (opciono) zujalica pišti. Ovo stvara jednostavnu, ali iznenađujuće zabavnu igru ravnoteže/koordinacije.
Svih šest projekata prikazano je u jednom YouTube videu (ugrađenom na ovoj stranici). Kompletan kod igre automatski se učitava ispod ovog članka, a affiliate linkovi za kupovinu modula pojavljuju se ispod sekcije s kodom.

Pregled ESP32-S3 RGB LED Matrix modula
Ovaj modul uključuje:

- ESP32-S3 mikrokontroler (Wi-Fi + BLE)
- 8×8 RGB LED matricu (64 adresabilnih LED dioda)
- QMI8658C akcelerometar za detekciju nagiba i orijentacije
- USB-C priključak za napajanje i programiranje
- Boot / Reset dugmad
- Dostupni GPIO pinovi za dodatke poput zujalica ili senzora
Za ovu igru, akcelerometar je neophodan—neprekidno izvještava X/Y nagib, omogućavajući tački da se glatko kreće na osnovu ugla ploče. Video sekcija za ovaj projekat jasno pokazuje kako tačka klizi i reaguje dok naginješ modul lijevo/desno/naprijed/nazad.

Projekti pokriveni u videu (Vremenske oznake)
- 00:00 – Uvod
- 02:01 – Instaliranje ESP32 ploča
- 03:32 – Instaliranje biblioteka
- 05:32 – Projekat 1: Pokretna tačka
- 11:11 – Projekat 2: Tekst koji se pomiče
- 12:59 – Projekat 3: HTTP tekst
- 16:41 – Projekat 4: Tačka s nagibom
- 18:55 – Projekat 5: Strelica gore
- 20:02 – Projekat 6: Igra s metom (ovaj projekat)
Ovaj dio videa prikazuje i kretanje tačke i logiku detekcije kruga u akciji, što olakšava razumijevanje kako se koordinate ponašaju.

Instaliranje ESP32 ploča u Arduino IDE
Ako si već završio ranije projekte, instalacija ploče je gotova. U suprotnom slijedi:
File > Preferences→ Dodaj ESP32 board URL.Tools > Board > Boards Manager…→ Instaliraj “ESP32”.- Odaberi ESP32-S3 ploču pod
Tools > Board. - Odaberi ispravan COM port pod
Tools > Port.
Instaliranje potrebnih biblioteka
Ova igra koristi:
Adafruit NeoMatrixAdafruit NeoPixelAdafruit GFXQMI8658(senzor pokreta)
Instaliraj ih putem:
Sketch > Include Library > Manage Libraries…- Pretraga: NeoMatrix → Instaliraj
- Instaliraj zavisnosti (GFX + NeoPixel)
- Pretraži i instaliraj QMI8658
Kako funkcioniše igra s metom
QMI8658C akcelerometar pruža X i Y vrijednosti nagiba. One se mapiraju na LED koordinate (0–7 u oba smjera). Tvoja tačka se kreće po matrici na osnovu ugla ploče.
Krug (ili prsten) se crta na ekranu kao “ciljno područje.” Pobjeđuješ “pogodak” kad god tačka preklopi krug. U tom trenutku:
- Boja mete se mijenja (nasumično ili unaprijed definirano)
- Opciona zujalica pišti (ako je povezana)
Pošto je matrica mala, krug se crta koristeći jednostavnu provjeru radijusa. Igra radi neprekidno, tako da možeš naginjati naprijed-nazad da bi više puta pogodio krug.
Projekat 6 – Postavke koda (Igra s metom)
Ispod su glavne postavke koje korisnik može podešavati, a nalaze se na vrhu skice. Kompletan kod automatski je uključen ispod ovog članka.
Konfiguracija matrice
// Konfiguracija matrice
const int MATRIX_PIN = 14;
const int MATRIX_WIDTH = 8;
const int MATRIX_HEIGHT = 8;
RGB matrica je fiksno povezana na GPIO 14—nemoj ovo mijenjati.
Svjetlina
uint8_t matrixBrightness = 40; // 0–255
Za upotrebu u zatvorenom prostoru, 30–60 je idealno.
Boja tačke
// Boja tačke (R, G, B)
uint8_t dotRed = 255;
uint8_t dotGreen = 255;
uint8_t dotBlue = 255;
Ovo je tačka koju pomjeraš naginjanjem ploče.
Boja kruga (nasumična ili fiksna)
// Boja kruga (mete)
uint8_t circleRed = 0;
uint8_t circleGreen = 0;
uint8_t circleBlue = 255;
// Ako je true, bira se nova nasumična boja svaki put kad tačka pogodi
bool randomCircleColor = true;
Postavi randomCircleColor = false; ako želiš fiksnu boju.
Radijus kruga
// Veličina mete (radijus)
int targetRadius = 3; // 3 dobro odgovara na 8×8 matrici
Veći radijusi čine igru lakšom; manji je čine težom.
Osjetljivost nagiba
// Osjetljivost mapiranja nagiba
float tiltScale = 4.0f; // povećanje = brže kretanje po ekranu
Ako se tačka kreće prebrzo ili skače, smanji ovaj broj.
Postavke zujalice (opciono)
// Pin za zujalicu (opcionalno)
int buzzerPin = 6; // spojite + zujalice na pin 6, – na GND
bool useBuzzer = true; // postavite false da isključite zvuk
Ako ne spojite zujalicu, jednostavno postavite useBuzzer = false;
Sažetak
Projekat 6 kombinuje sve naučeno iz ranijih projekata: crtanje matrice, unos sa akcelerometra, kontrolu boja, izglađivanje pokreta i opcionalni zvuk. Naginjanje ploče pomiče tačku, a udaranje u krug mijenja njenu boju i (opcionalno) pokreće zvučni signal. To je zabavna demonstracija detekcije pokreta na kompaktnom RGB ekranu.
Potpuni kod za “Target Game” automatski se prikazuje ispod ovog članka. Također možete pogledati dio videa o Projektu 6 da vidite kako se tačka pomiče i kako se detektuju pogoci. Ako želite napraviti vlastitu igru, affiliate linkovi za kupovinu ESP32-S3 RGB LED Matrix modula nalaze se ispod sekcije s kodom.
This tutorial is part of: ESP32-S3 RGB LED matrica
- ESP32-S3 RGB LED Matrix projekat 1 - Osnovna tačka
- ESP32-S3 RGB LED Matrix projekat 2 - Tekst koji se pomiče
- ESP32-S3 RGB LED Matrix projekat 3 - Tekst sa mobilnog telefona
- ESP32-S3 RGB LED Matrix projekat 4 - Tilt tačka
- ESP32-S3 RGB LED Matrica Projekat 5 - Strelica uvijek gore
- ESP32-S3 RGB LED matrica Wi-Fi + NTP sat vremena projekat -1 Osnovni sat
- ESP32-S3 RGB LED matrica Internet sat projekat - 2 sata višebojni prikaz vremena i datuma
- ESP32-S3 RGB LED matrica internet sat projekat - 3 noćne boje sa datumom
- ESP32-S3 RGB LED matrica internet sat projekat - 5 duginih boja
- ESP32-S3 RGB LED matrica internet sat projekat - 4 nasumične boje
- 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