Ten poradnik jest częścią: Matryca LED RGB ESP32-S3
Fajny projekt do stworzenia dla zabawy i praktycznych zastosowań z wykorzystaniem modułu matrycy RGB ESP32-S3. Linki do innych filmów znajdują się poniżej tego artykułu.
Projekt ESP32-S3 z matrycą LED RGB 6 - gra w cel
Projekt 6 – Gra w cel (Przechyl płytkę, aby trafić w okrąg)
Projekt 6 to ostatni i najbardziej interaktywny projekt w tej serii o macierzy LED RGB ESP32-S3. Korzystając z wbudowanego czujnika ruchu QMI8658C, przechylasz płytkę, aby przesuwać kropkę po macierzy 8×8. Okrągła „strefa celu” znajduje się na środku wyświetlacza. Gdy Twoja kropka dotknie okręgu, kolor się zmienia i (opcjonalnie) brzęczyk wydaje dźwięk. Tworzy to prostą, ale zaskakująco zabawną grę zręcznościowo-koordynacyjną.
Wszystkie sześć projektów jest zaprezentowanych w jednym filmie na YouTube (osadzonym na tej stronie). Kompletny kod gry jest ładowany automatycznie poniżej tego artykułu, a linki partnerskie do zakupu modułu znajdują się pod sekcją z kodem.

Przegląd modułu macierzy LED RGB ESP32-S3
Ten moduł zawiera:

- Mikrokontroler ESP32-S3 (Wi-Fi + BLE)
- Macierz LED RGB 8×8 (64 adresowalne diody LED)
- Akcelerometr QMI8658C do wykrywania przechyłu i orientacji
- Port USB-C do zasilania i programowania
- Przyciski Boot / Reset
- Dostępne piny GPIO do dodatków, takich jak brzęczyki lub czujniki
W tej grze akcelerometr jest niezbędny—w sposób ciągły raportuje przechył X/Y, umożliwiając płynne poruszanie się kropki w zależności od kąta płytki. Sekcja wideo dla tego projektu wyraźnie pokazuje, jak kropka ślizga się i reaguje podczas przechylania modułu w lewo/prawo/przód/tył.

Projekty omówione w filmie (znaczniki czasu)
- 00:00 – Wprowadzenie
- 02:01 – Instalacja płytek ESP32
- 03:32 – Instalacja bibliotek
- 05:32 – Projekt 1: Poruszająca się kropka
- 11:11 – Projekt 2: Przewijanie tekstu
- 12:59 – Projekt 3: Tekst HTTP
- 16:41 – Projekt 4: Kropka przechyłu
- 18:55 – Projekt 5: Strzałka w górę
- 20:02 – Projekt 6: Gra w cel (ten projekt)
Ta część filmu pokazuje zarówno ruch kropki, jak i logikę wykrywania okręgu w działaniu, co ułatwia zrozumienie, jak zachowują się współrzędne.

Instalacja płytek ESP32 w Arduino IDE
Jeśli ukończyłeś już wcześniejsze projekty, instalacja płytek jest zakończona. W przeciwnym razie postępuj zgodnie z instrukcją:
Plik > Preferencje→ Dodaj adres URL płytek ESP32.Narzędzia > Płytka > Menedżer płytek…→ Zainstaluj „ESP32”.- Wybierz płytkę ESP32-S3 w
Narzędzia > Płytka. - Wybierz właściwy port COM w
Narzędzia > Port.
Instalacja wymaganych bibliotek
Ta gra używa:
Adafruit NeoMatrixAdafruit NeoPixelAdafruit GFXQMI8658(czujnik ruchu)
Zainstaluj je przez:
Szkic > Dołącz bibliotekę > Zarządzaj bibliotekami…- Szukaj: NeoMatrix → Zainstaluj
- Zainstaluj zależności (GFX + NeoPixel)
- Wyszukaj i zainstaluj QMI8658
Jak działa gra w cel
Akcelerometr QMI8658C dostarcza wartości przechyłu X i Y. Są one mapowane na współrzędne LED (0–7 w obu kierunkach). Twoja kropka porusza się po macierzy w zależności od kąta płytki.
Okrąg (lub pierścień) jest rysowany na wyświetlaczu jako „obszar celu”. Osiągasz „trafienie”, gdy kropka nakłada się na okrąg. W tym momencie:
- Kolor celu się zmienia (losowy lub zdefiniowany)
- Opcjonalny brzęczyk wydaje dźwięk (jeśli jest podłączony)
Ponieważ macierz jest mała, okrąg jest rysowany za pomocą prostego sprawdzenia promienia. Gra działa w sposób ciągły, więc możesz przechylać płytkę w przód i w tył, aby wielokrotnie trafiać w okrąg.
Projekt 6 – Ustawienia kodu (gra w cel)
Poniżej znajdują się główne ustawienia regulowane przez użytkownika, znajdujące się na górze szkicu. Pełny kod jest automatycznie dołączony poniżej tego artykułu.
Konfiguracja macierzy
// Konfiguracja macierzy
const int MATRIX_PIN = 14;
const int MATRIX_WIDTH = 8;
const int MATRIX_HEIGHT = 8;
Macierz RGB jest trwale podłączona do GPIO 14—nie zmieniaj tego.
Jasność
uint8_t matrixBrightness = 40; // 0–255
Do użytku w pomieszczeniach idealna wartość to 30–60.
Kolor kropki
// Kolor kropki (R, G, B)
uint8_t dotRed = 255;
uint8_t dotGreen = 255;
uint8_t dotBlue = 255;
To jest kropka, którą przesuwasz, przechylając płytkę.
Kolor okręgu (losowy lub stały)
// Kolor okręgu (celu)
uint8_t circleRed = 0;
uint8_t circleGreen = 0;
uint8_t circleBlue = 255;
// Jeśli true, wybierz nowy losowy kolor za każdym razem, gdy kropka trafi
bool randomCircleColor = true;
Ustaw randomCircleColor = false;, jeśli chcesz mieć stały kolor.
Promień okręgu
// Rozmiar celu (promień)
int targetRadius = 3; // 3 dobrze pasuje do macierzy 8×8
Większe promienie ułatwiają grę; mniejsze ją utrudniają.
Czułość przechyłu
// Czułość mapowania przechyłu
float tiltScale = 4.0f; // zwiększenie = szybszy ruch po ekranie
Jeśli kropka porusza się zbyt szybko lub skacze, zmniejsz tę liczbę.
Ustawienia brzęczyka (opcjonalne)
// Pin buzzera (opcjonalnie)
int buzzerPin = 6; // podłącz buzzer + do pinu 6, – do GND
bool useBuzzer = true; // ustaw false, aby wyłączyć dźwięk
Jeśli nie podłączasz buzzera, po prostu ustaw useBuzzer = false;
Podsumowanie
Projekt 6 łączy wszystko, czego nauczyłeś się z wcześniejszych projektów: rysowanie na macierzy, odczyt z akcelerometru, kontrolę kolorów, wygładzanie ruchu i opcjonalny dźwięk. Przechylanie płytki przesuwa kropkę, a trafienie w okrąg zmienia jego kolor i (opcjonalnie) wyzwala sygnał dźwiękowy. To zabawna demonstracja wykrywania ruchu na kompaktowym wyświetlaczu RGB.
Pełny kod gry „Target Game” jest wyświetlany automatycznie poniżej tego artykułu. Możesz również obejrzeć część wideo dotyczącą Projektu 6, aby zobaczyć, jak porusza się kropka i jak wykrywane są trafienia. Jeśli chcesz zbudować własną grę, linki partnerskie do zakupu modułu ESP32-S3 RGB LED Matrix znajdują się poniżej sekcji z kodem.
Ten poradnik jest częścią: Matryca LED RGB ESP32-S3
- Projekt matrycy LED RGB ESP32-S3 1 – podstawowa kropka
- Projekt matrycy LED RGB ESP32-S3 2 - Przewijany tekst
- Projekt ESP32-S3 z matrycą LED RGB 3 - Tekst z telefonu komórkowego
- Projekt ESP32-S3 z matrycą LED RGB 4 - Punkt przechyłu
- Projekt matrycy LED RGB ESP32-S3 5 - Strzałka zawsze w górę
- Projekt zegara czasu Wi-Fi + NTP z matrycą LED RGB ESP32-S3 -1 Zegar podstawowy
- Projekt zegara internetowego z matrycą LED RGB ESP32-S3 - 2 zegary wielokolorowe z wyświetlaniem czasu i daty
- Projekt zegara internetowego z matrycą LED RGB ESP32-S3 - 3 kolory nocne z datą
- Projekt zegara internetowego z matrycą LED RGB ESP32-S3 - 5 kolorów tęczy
- Projekt zegara internetowego z matrycą LED RGB ESP32-S3 - 4 losowe kolory
- 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);
}
Rzeczy, których możesz potrzebować
-
Amazon
-
Allegro
-
AliExpressPurchase ESP32-S3 RGB Matrix from AliExpresss.click.aliexpress.com
-
AliExpressPurchase ESP32-S3 RGB Matrix from AliExpress (2)s.click.aliexpress.com
Zasoby i odniesienia
-
Wewnętrzny🎨 Color picker Toolrobojax.com
Pliki📁
Plik Fritzing
-
esp32-S3-supermini-tht fritzing part
esp32-S3-supermini-tht.fzpz0.02 MB