Deze tutorial maakt deel uit van: ESP32-S3 RGB LED-matrix
Een gaaf project om te maken voor de lol en voor praktische toepassingen met de ESP32-S3 RGB-matrixmodule. Links naar andere video's vind je onderaan dit artikel.
ESP32-S3 RGB LED-matrixproject 6 - Cible-spel
Project 6 – Doelspel (Kantel het bord om de cirkel te raken)
Project 6 is het laatste en meest interactieve project in deze ESP32-S3 RGB LED-matrixserie. Met behulp van de ingebouwde QMI8658C-bewegingssensor kantel je het bord om een stip over de 8×8-matrix te bewegen. Een cirkelvormige “doelzone” bevindt zich in het midden van het display. Wanneer je stip de cirkel raakt, verandert de kleur en (optioneel) klinkt er een zoemer. Dit creëert een eenvoudig maar verrassend leuk balans-/coördinatiespel.
Alle zes projecten worden gedemonstreerd in één YouTube-video (ingebed op deze pagina). De volledige spelcode wordt automatisch onder dit artikel geladen, en affiliatelinks voor de module verschijnen onder het codegedeelte.

Overzicht van de ESP32-S3 RGB LED-matrixmodule
Deze module omvat:

- ESP32-S3-microcontroller (Wi-Fi + BLE)
- 8×8 RGB-LED-matrix (64 adresseerbare LED's)
- QMI8658C-versnellingsmeter voor kantel- en oriëntatiedetectie
- USB-C-poort voor voeding en programmeren
- Boot-/Reset-knoppen
- Beschikbare GPIO-pinnen voor uitbreidingen zoals zoemers of sensoren
Voor dit spel is de versnellingsmeter essentieel—deze rapporteert continu de X/Y-kanteling, waardoor de stip soepel beweegt op basis van de bordhoek. Het videogedeelte voor dit project laat duidelijk zien hoe de stip glijdt en reageert wanneer je de module links/rechts/vooruit/achteruit kantelt.:contentReference[oaicite:0]{index=0}

Projecten in de video (tijdstempels)
- 00:00 – Introductie
- 02:01 – ESP32-boards installeren
- 03:32 – Bibliotheken installeren
- 05:32 – Project 1: Bewegende stip
- 11:11 – Project 2: Tekst scrollen
- 12:59 – Project 3: HTTP-tekst
- 16:41 – Project 4: Kantelstip
- 18:55 – Project 5: Pijl omhoog
- 20:02 – Project 6: Doelspel (dit project)
Dit gedeelte van de video toont zowel de stipbeweging als de cirkeldetectielogica in actie, waardoor het gemakkelijker wordt om te begrijpen hoe de coördinaten zich gedragen.:contentReference[oaicite:1]{index=1}

ESP32-boards installeren in Arduino IDE
Als je de eerdere projecten al hebt voltooid, is de boardinstallatie klaar. Volg anders:
Bestand > Voorkeuren→ ESP32-board-URL toevoegen.Extra > Board > Boards Manager…→ “ESP32” installeren.- Selecteer het ESP32-S3-board onder
Extra > Board. - Selecteer de juiste COM-poort onder
Extra > Poort.
Vereiste bibliotheken installeren
Dit spel gebruikt:
Adafruit NeoMatrixAdafruit NeoPixelAdafruit GFXQMI8658(bewegingssensor)
Installeer ze via:
Schets > Bibliotheek gebruiken > Bibliotheken beheren…- Zoek: NeoMatrix → Installeren
- Installeer afhankelijkheden (GFX + NeoPixel)
- Zoek en installeer QMI8658
Hoe het doelspel werkt
De QMI8658C-versnellingsmeter levert X- en Y-kantelwaarden. Deze worden toegewezen aan LED-coördinaten (0–7 in beide richtingen). Je stip beweegt over de matrix op basis van de bordhoek.
Een cirkel (of ring) wordt op het display getekend als het “doelgebied.” Je scoort een “treffer” wanneer de stip de cirkel overlapt. Op dat moment:
- Verandert de doelkleur (willekeurig of vooraf gedefinieerd)
- Klinkt er optioneel een zoemer (indien aangesloten)
Omdat de matrix klein is, wordt de cirkel getekend met een eenvoudige straalcontrole. Het spel draait continu, zodat je heen en weer kunt kantelen om de cirkel herhaaldelijk te raken.
Project 6 – Code-instellingen (doelspel)
Hieronder staan de belangrijkste door de gebruiker aanpasbare instellingen bovenaan de schets. De volledige code wordt automatisch onder dit artikel opgenomen.
Matrixconfiguratie
// Matrixconfiguratie
const int MATRIX_PIN = 14;
const int MATRIX_WIDTH = 8;
const int MATRIX_HEIGHT = 8;
De RGB-matrix is vast aangesloten op GPIO 14—wijzig dit niet.
Helderheid
uint8_t matrixBrightness = 40; // 0–255
Voor binnengebruik is 30–60 ideaal.
Stipkleur
// Stipkleur (R, G, B)
uint8_t dotRed = 255;
uint8_t dotGreen = 255;
uint8_t dotBlue = 255;
Dit is de stip die je beweegt door het bord te kantelen.
Cirkelkleur (willekeurig of vast)
// Cirkel- (doel)kleur
uint8_t circleRed = 0;
uint8_t circleGreen = 0;
uint8_t circleBlue = 255;
// Indien waar, kies elke keer dat de stip raakt een nieuwe willekeurige kleur
bool randomCircleColor = true;
Stel randomCircleColor = false; in als je een vaste kleur wilt.
Cirkelstraal
// Doelgrootte (straal)
int targetRadius = 3; // 3 past goed op 8×8-matrix
Grotere stralen maken het spel gemakkelijker; kleinere maken het moeilijker.
Kantelgevoeligheid
// Gevoeligheid van kanteltoewijzing
float tiltScale = 4.0f; // verhogen = snellere beweging over het scherm
Als de stip te snel beweegt of springt, verlaag dit getal.
Zoemerinstellingen (optioneel)
// Buzzer-pin (optioneel)
int buzzerPin = 6; // verbind buzzer + met pin 6, – met GND
bool useBuzzer = true; // zet op false om geluid uit te schakelen
Als je geen buzzer aansluit, zet dan simpelweg useBuzzer = false;
Samenvatting
Project 6 combineert alles wat je in eerdere projecten hebt geleerd: matrix-tekenen, versnellingsmeter-invoer, kleurbeheer, bewegingssmoothing en optioneel geluid. Door het bord te kantelen beweegt de stip, en het raken van de cirkel verandert de kleur en (optioneel) activeert een pieptoon. Het is een leuke demonstratie van bewegingsdetectie op een compact RGB-display.
De volledige “Target Game”-code wordt automatisch onder dit artikel weergegeven. Je kunt ook het Project 6-gedeelte van de video bekijken om te zien hoe de stip beweegt en hoe treffers worden gedetecteerd. Als je je eigen spel wilt bouwen, vind je onder het codegedeelte affiliatelinks voor het kopen van de ESP32-S3 RGB LED Matrix-module.
Deze tutorial maakt deel uit van: ESP32-S3 RGB LED-matrix
- ESP32-S3 RGB LED-matrixproject 1- Basispunt
- ESP32-S3 RGB LED-matrixproject 2 - Scrollende tekst
- ESP32-S3 RGB LED-matrixproject 3 - Tekst vanaf mobiele telefoon
- ESP32-S3 RGB LED-matrixproject 4 - Kantelpunt
- ESP32-S3 RGB LED-matrixproject 5 - Pijl altijd omhoog
- ESP32-S3 RGB LED-matrix Wi-Fi + NTP-tijdklokproject -1 Basisklok
- ESP32-S3 RGB LED-matrix internetklokproject - 2 klokken multi-kleur tijd- en datumweergave
- ESP32-S3 RGB LED-matrix internetklokproject - 3 nachtkleuren met datum
- ESP32-S3 RGB LED-matrix internetklokproject - 5 Regenboogkleur
- ESP32-S3 RGB LED-matrix internetklokproject - 4 willekeurige kleuren
- 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);
}
Dingen die je misschien nodig hebt
-
Amazon
-
eBay
-
AliExpressPurchase ESP32-S3 RGB matrix from AliExpresss.click.aliexpress.com
-
AliExpressPurchase ESP32-S3 RGB matrix from AliExpress (2)s.click.aliexpress.com
Hulpmiddelen en referenties
-
Intern🎨 Color picker Toolrobojax.com
Bestanden📁
Fritzing-bestand
-
esp32-S3-supermini-tht fritzing part
esp32-S3-supermini-tht.fzpz0.02 MB