Hierdie tutorialie is deel van: ESP32-S3 RGB LED-matriks
'n Koel projek om te skep vir prettige en praktiese toepassings met die ESP32-S3 RGB Matriksmodule. Skakels na ander video's is onder hierdie artikel.
ESP32-S3 RGB LED-matriksprojek 5 - Pyl altyd op
Projek 5 – Pyl Altyd Op (Oriëntasie-aanwyser met QMI8658C)
Projek 5 gebruik die QMI8658C-bewegingsensor om die oriëntasie van die ESP32-S3 RGB LED-matriks te bespeur en altyd 'n pyl opwaarts relatief tot swaartekrag aan te wys. Maak nie saak hoe jy die bord draai nie—USB-kant bo, OUSB-kant bo, kant “15”, of kant “34”—die pyl draai outomaties en wys na die fisies opwaartse rigting.
Dit is 'n kragtige demonstrasie van intydse oriëntasie-waarneming met behulp van die ingeboude versnellingsmeter. Al ses projekte vir hierdie module word in een YouTube-video gedemonstreer, wat ook op hierdie bladsy ingebed is. Die volledige kode vir Projek 5 laai outomaties onder die artikel, en geaffilieerde skakels verskyn onder die kode-afdeling.

ESP32-S3 RGB LED-matriksmodule-oorsig
Die ESP32-S3 RGB LED-matriksmodule bevat verskeie komponente wat hierdie projek moontlik maak:

- ESP32-S3-mikrobeheerder — verskaf Wi-Fi, BLE, en bestuur die LED/IMU-logika.
- 8×8 RGB LED-matriks — vertoon die pyl in enige van vier oriëntasies.
- QMI8658C-versnellingsmeter — bespeur kanteling, beweging en oriëntasie.:contentReference[oaicite:0]{index=0}
- USB-C-poort vir krag en programmering in Arduino IDE.
- Reset- en Boot-knoppies vir die oplaai van sketse.
- GPIO-penne beskikbaar rondom die bord vir bykomende projekte.
Die pylrigting word geheel en al bepaal deur die versnellingsmeterlesings. Wanneer die bord gedraai word, bespeur die QMI8658C die nuwe X/Y/Z-waardes, en die skets kies watter pylpatroon (↑, ↓, ←, →) geteken moet word.

Projekte Gedek in die Video (Tydstempels)
- 00:00 – Inleiding
- 02:01 – Installeer ESP32-borde
- 03:32 – Installeer biblioteke
- 05:32 – Projek 1: Bewegende Punt
- 11:11 – Projek 2: Teksrol
- 12:59 – Projek 3: HTTP-teks
- 16:41 – Projek 4: Kantelpunt
- 18:55 – Projek 5: Pyl Altyd Op (hierdie projek)
- 20:02 – Projek 6: Teiken-speletjie
Die video toon duidelik hoe die pyl onmiddellik van rigting verander op grond van hoe die module gedraai word. Dit word sterk aanbeveel om hierdie segment te kyk.:contentReference[oaicite:1]{index=1}

Installeer ESP32-borde in Arduino IDE
As jy enige vroeëre projek voltooi het, is die bordopstelling reeds gedoen. Andersins:
File > Preferences→ Voeg ESP32-bord-URL byTools > Board > Boards Manager…→ Installeer “ESP32”- Kies die ESP32-S3-bord onder
Tools > Board - Kies die korrekte USB COM-poort onder
Tools > Port
Installeer Vereiste Biblioteke
Projek 5 gebruik:
Adafruit NeoMatrixAdafruit NeoPixelAdafruit GFXQMI8658(bewegingsensor)
Sketch > Include Library > Manage Libraries…- Soek: NeoMatrix → Installeer
- Installeer afhanklikhede: NeoPixel + GFX
- Soek en installeer QMI8658 deur sy outeur
Hoe Projek 5 Werk
Die QMI8658C meet swaartekrag op X-, Y- en Z-asse. Deur hierdie waardes te vergelyk, bepaal die skets watter fisiese kant van die bord opwaarts wys:
- USB-kant bo
- OUSB-kant bo (teenoorgestelde van USB)
- Kant “15” bo
- Kant “34” bo
Elke oriëntasie stem ooreen met 'n ander pylpatroon op die 8×8-matriks. Die kartering volg jou bevestigde oriëntasielogika van vroeëre ontfoutingsessies. Die bord se rotasie word deurlopend gelees, en die pyl werk op sodra die opwaartse kant verander.
Projek 5 – Kodestellings (Pyl Altyd Op)
Hieronder is die gebruikersverstelbare waardes uit die konfigurasie-area. Die volledige projekkode verskyn outomaties onder die artikel.
Matrikskonfigurasie
// Matrikskonfigurasie
const int MATRIX_PIN = 14; // vas vir hierdie module
const int MATRIX_WIDTH = 8;
const int MATRIX_HEIGHT = 8;
// Aanbevole oriëntasie: Bo-linker oorsprong, progressiewe modus
// (werklike konstruktor is binne die kode wat hieronder gelaai word)
Hierdie projek gebruik NEO_MATRIX_PROGRESSIVE-uitleg om te verseker dat die pyl korrek wys op grond van werklike beweging.
Helderheid
uint8_t matrixBrightness = 40; // 0–255
Jy kan hierdie waarde verhoog vir helderder omgewings. Vir binnenshuise gebruik is 30–60 gemaklik.
Pylkleur
// Pylkleur
uint8_t arrowRed = 255;
uint8_t arrowGreen = 0;
uint8_t arrowBlue = 0;
Verander hierdie waardes om die pyl se kleur te wysig. Byvoorbeeld:
- Groen pyl:
(0, 255, 0) - Blou pyl:
(0, 0, 255) - Wit pyl:
(255, 255, 255)
Sensitiwiteit en Gladstryking
Om beweging te vermy, sluit die kode gladstrykings- en drempellogika in. In die instellings mag jy iets soos dit vind:
// Sensitiwiteit / gladstrykingsaanpassing
float tiltThreshold = 0.30f; // pas aan as pyl te maklik verander
- As jou pyl te maklik omdraai → verhoog drempel.
- As die pyl te stadig verander → verlaag drempel.
Pylpatrone
Die skets sluit pyl-bitmap-patrone in vir:
- ↑ op
- ↓ af
- ← links
- → regs
Jy hoef dit nie te wysig nie, maar jy kan die vorms in die kode verander as jy 'n ander styl wil hê.
Opsomming
Projek 5 demonstreer hoe die ESP32-S3 RGB LED-matriks en die QMI8658C-versnellingsmeter saamwerk om oriëntasie op te spoor en 'n pyl te vertoon wat altyd opwaarts wys. Hierdie projek bou voort op die Tilt Dot (Projek 4) en berei jou voor vir die finale interaktiewe speletjie in Projek 6.
Die volledige “Pyl Altyd Op”-skets is beskikbaar onder hierdie artikel (outomaties gelaai). Dit word sterk aanbeveel om die ooreenstemmende deel van die video te kyk om te sien hoe onmiddellik die pyl op bordrotasie reageer. As jy hierdie projek by die huis wil bou, verskyn affiliasieskakels vir die ESP32-S3 RGB LED-matriksmodule onder die kode-afdeling.
Beelde
Hierdie handleiding is deel van: ESP32-S3 RGB LED-matriks
- ESP32-S3 RGB LED-matriksprojek 1- Basiese Punt
- ESP32-S3 RGB LED-matriksprojek 2 - Roltelende teks
- ESP32-S3 RGB LED-matriksprojek 3 - Teks vanaf selfoon
- ESP32-S3 RGB LED-matriksprojek 4 - Kantelkolletjie
- ESP32-S3 RGB LED-matriksprojek 6 - Cible-speletjie
- ESP32-S3 RGB LED-matriks Wi-Fi + NTP-tydklokprojek -1 Basiese klok
- ESP32-S3 RGB LED-matriks Internet-klokprojek - 2 Klok multi-kleur Tyd & Datum Vertoning
- ESP32-S3 RGB LED-matriks-internetklokprojek - 3 Nagkleure met Datum
- ESP32-S3 RGB LED-matriks-internetklokprojek - 5 Reënboogkleur
- ESP32-S3 RGB LED-matriks-internetklokprojek - 4 Ewekansige kleure
- ESP32-S3 RGB LED Matrix test for RGB, GRB setting
/*
Project 5: Arrow Always Up – 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/RJT833
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
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(
MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_PIN,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
NEO_MATRIX_ROWS + NEO_MATRIX_PROGRESSIVE,
NEO_RGB + NEO_KHZ800
);
// -------- QMI8658 IMU SETUP --------
QMI8658 imu;
QMI8658_Data imuData;
// -------- USER SETTINGS --------
// true -> arrow points to opposite side
// USB↔OUSB, 34↔15
// false -> arrow points to the same side that is UP
bool useOppositeMapping = false;
// Arrow color (0–255 each)
uint8_t dotRed = 0;
uint8_t dotGreen = 150;
uint8_t dotBlue = 0;
// Board sides
enum Side {
SIDE_CENTER = 0,
SIDE_USB,
SIDE_OUSB,
SIDE_15,
SIDE_34
};
// Direction for arrow drawing
enum ArrowDir {
ARROW_CENTER,
ARROW_UP,
ARROW_DOWN,
ARROW_LEFT,
ARROW_RIGHT
};
bool isFlat = false;
const char* sideName(Side s) {
switch (s) {
case SIDE_CENTER: return "CENTER";
case SIDE_USB: return "USB";
case SIDE_OUSB: return "OUSB";
case SIDE_15: return "15";
case SIDE_34: return "34";
default: return "?";
}
}
// -------- ARROW DRAWING (YOUR CODE, UNCHANGED) --------
// Draw a simple arrow on 8x8 matrix pointing in the given direction
void drawArrow(ArrowDir dir, uint16_t color) {
matrix.fillScreen(0);
switch (dir) {
case ARROW_UP:
// Tip
matrix.drawPixel(3, 0, color);
matrix.drawPixel(4, 0, color);
// Second row
matrix.drawPixel(2, 1, color);
matrix.drawPixel(3, 1, color);
matrix.drawPixel(4, 1, color);
matrix.drawPixel(5, 1, color);
// Shaft
matrix.drawLine(3, 2, 3, 6, color);
matrix.drawLine(4, 2, 4, 6, color);
break;
case ARROW_DOWN:
// Tip
matrix.drawPixel(3, 7, color);
matrix.drawPixel(4, 7, color);
// Row above tip
matrix.drawPixel(2, 6, color);
matrix.drawPixel(3, 6, color);
matrix.drawPixel(4, 6, color);
matrix.drawPixel(5, 6, color);
// Shaft
matrix.drawLine(3, 1, 3, 5, color);
matrix.drawLine(4, 1, 4, 5, color);
break;
case ARROW_LEFT:
// Tip
matrix.drawPixel(0, 3, color);
matrix.drawPixel(0, 4, color);
// Column after tip
matrix.drawPixel(1, 2, color);
matrix.drawPixel(1, 3, color);
matrix.drawPixel(1, 4, color);
matrix.drawPixel(1, 5, color);
// Shaft
matrix.drawLine(2, 3, 6, 3, color);
matrix.drawLine(2, 4, 6, 4, color);
break;
case ARROW_RIGHT:
// Tip
matrix.drawPixel(7, 3, color);
matrix.drawPixel(7, 4, color);
// Column before tip
matrix.drawPixel(6, 2, color);
matrix.drawPixel(6, 3, color);
matrix.drawPixel(6, 4, color);
matrix.drawPixel(6, 5, color);
// Shaft
matrix.drawLine(1, 3, 5, 3, color);
matrix.drawLine(1, 4, 5, 4, color);
break;
case ARROW_CENTER:
default:
// Simple plus in the center
matrix.drawLine(3, 3, 4, 3, color);
matrix.drawLine(3, 4, 4, 4, color);
matrix.drawLine(3, 3, 3, 4, color);
matrix.drawLine(4, 3, 4, 4, color);
break;
}
matrix.show();
}
// -------- IMU → SIDE DETECTION --------
// We calibrated earlier:
// +X = USB, -X = OUSB
// +Y = 15, -Y = 34 (after your correction)
Side detectSideUp(float ax_g, float ay_g, float az_g) {
// Flat detection
const float flatThreshXY = 0.15f;
const float flatThreshZ = 0.15f;
if (fabs(ax_g) < flatThreshXY &&
fabs(ay_g) < flatThreshXY &&
fabs(az_g - 1.0f) < flatThreshZ) {
isFlat = true;
return SIDE_CENTER;
}
isFlat = false;
// Thresholds to say "this axis is really tilted"
const float tiltThreshY = 0.5f;
const float tiltThreshX = 0.5f;
// Prefer Y axis for 15 / 34
if (fabs(ay_g) >= tiltThreshY) {
if (ay_g > 0) {
return SIDE_34; // +Y = 34 up
} else {
return SIDE_15; // -Y = 15 up
}
}
// Otherwise, use X axis for USB / OUSB
if (fabs(ax_g) >= tiltThreshX) {
if (ax_g > 0) {
return SIDE_USB; // +X = USB up
} else {
return SIDE_OUSB; // -X = OUSB up
}
}
// Not clearly tilted → treat as center
return SIDE_CENTER;
}
// Map from UP side to where the arrow should point
Side arrowSideFromUpSide(Side upSide) {
if (!useOppositeMapping) {
// Arrow shows the side that is UP
return upSide;
}
// Arrow shows the opposite side
switch (upSide) {
case SIDE_USB: return SIDE_OUSB;
case SIDE_OUSB: return SIDE_USB;
case SIDE_15: return SIDE_34;
case SIDE_34: return SIDE_15;
case SIDE_CENTER:
default: return SIDE_CENTER;
}
}
// Convert SIDE to ArrowDir
ArrowDir arrowDirFromSide(Side s) {
switch (s) {
case SIDE_USB: return ARROW_UP;
case SIDE_OUSB: return ARROW_DOWN;
case SIDE_15: return ARROW_LEFT;
case SIDE_34: return ARROW_RIGHT;
case SIDE_CENTER:
default: return ARROW_CENTER;
}
}
// ---------------- SETUP & LOOP ----------------
void setup() {
Serial.begin(115200);
delay(500);
matrix.begin();
matrix.setBrightness(20);
matrix.fillScreen(0);
matrix.show();
// IMU: SDA=11, SCL=12 on ESP32-S3-Matrix
if (!imu.begin(11, 12)) {
Serial.println("Failed to initialize QMI8658!");
while (1) { delay(1000); }
}
imu.setAccelUnit_mg(true);
imu.setGyroUnit_dps(true);
imu.setDisplayPrecision(4);
Serial.print("QMI8658 initialized. useOppositeMapping = ");
Serial.println(useOppositeMapping ? "TRUE" : "FALSE");
}
void loop() {
if (!imu.readSensorData(imuData)) {
return;
}
float ax_g = imuData.accelX / 1000.0f;
float ay_g = imuData.accelY / 1000.0f;
float az_g = imuData.accelZ / 1000.0f;
Side upSide = detectSideUp(ax_g, ay_g, az_g);
Side arrowSide = arrowSideFromUpSide(upSide);
ArrowDir dir = arrowDirFromSide(arrowSide);
uint16_t color = matrix.Color(dotRed, dotGreen, dotBlue);
drawArrow(dir, color);
// Debug
Serial.print("AX="); Serial.print(ax_g, 3);
Serial.print(" AY="); Serial.print(ay_g, 3);
Serial.print(" AZ="); Serial.print(az_g, 3);
Serial.print(" | UP="); Serial.print(sideName(upSide));
Serial.print(" | ARROW="); Serial.println(sideName(arrowSide));
delay(80);
}
Goedere wat jy dalk nodig het
-
Amazon
-
eBay
-
AliExpressPurchase ESP32-S3 RGB Matrix from AliExpresss.click.aliexpress.com
-
AliExpressPurchase ESP32-S3 RGB Matrix from AliExpress (2)s.click.aliexpress.com
Hulpbronne en verwysings
-
Internaal🎨 Color picker Toolrobojax.com
Lêers📁
Fritzing-lêer
-
esp32-S3-supermini-tht fritzing part
esp32-S3-supermini-tht.fzpz0.02 MB