This tutorial is part of: Matrix ya LED ya ESP32-S3 RGB
Mradi mzuri wa kuunda kwa ajili ya matumizi ya kufurahisha na ya vitendo kwa kutumia moduli ya ESP32-S3 RGB Matrix. Viungo vya video zingine viko chini ya makala haya.
Mradi wa Matrix ya LED ya RGB ya ESP32-S3 5 - Mshale daima juu
Mradi 5 – Mshale Daima Juu (Kiashiria cha Mwelekeo kwa kutumia QMI8658C)
Mradi wa 5 unatumia kihisi cha mwendo cha QMI8658C kutambua mwelekeo wa ESP32-S3 RGB LED Matrix na kuonyesha daima mshale unaoelekea JUU kuhusiana na mvuto. Haijalishi unazungusha bodi vipi—upande wa USB juu, upande wa OUSB juu, upande “15”, au upande “34”—mshale hujigeuza kiotomatiki na kuelekea upande wa kimwili ulio juu.
Hii ni maonyesho yenye nguvu ya kuhisi mwelekeo kwa wakati halisi kwa kutumia kipima mwendo kilicho ndani. Miradi yote sita ya moduli hii inaonyeshwa katika video moja ya YouTube, ambayo pia imepachikwa kwenye ukurasa huu. Msimbo kamili wa Mradi wa 5 hupakia kiotomatiki chini ya makala, na viungo vya washirika vinaonekana chini ya sehemu ya msimbo.

Muhtasari wa Moduli ya ESP32-S3 RGB LED Matrix
Moduli ya ESP32-S3 RGB LED Matrix inajumuisha vipengele kadhaa vinavyowezesha mradi huu:

- Kidhibiti kidogo cha ESP32-S3 — hutoa Wi-Fi, BLE, na huendesha mantiki ya LED/IMU.
- Matrix ya LED ya RGB 8×8 — huonyesha mshale katika mojawapo ya mielekeo minne.
- Kipima mwendo cha QMI8658C — hutambua mwinamo, mwendo, na mwelekeo.:contentReference[oaicite:0]{index=0}
- Bandari ya USB-C kwa ajili ya nishati na upangaji katika Arduino IDE.
- Vifungo vya Reset na Boot kwa ajili ya kupakia michoro.
- Pini za GPIO zinazopatikana kuzunguka bodi kwa ajili ya miradi ya ziada.
Mwelekeo wa mshale huamuliwa kabisa na usomaji wa kipima mwendo. Bodi inapozungushwa, QMI8658C huhisi thamani mpya za X/Y/Z, na mchoro huchagua muundo gani wa mshale (↑, ↓, ←, →) unapaswa kuchorwa.

Miradi Iliyoshughulikiwa kwenye Video (Vidhibiti vya Muda)
- 00:00 – Utangulizi
- 02:01 – Kusakinisha bodi za ESP32
- 03:32 – Kusakinisha maktaba
- 05:32 – Mradi 1: Nukta Inayosonga
- 11:11 – Mradi 2: Kusogeza Maandishi
- 12:59 – Mradi 3: Maandishi ya HTTP
- 16:41 – Mradi 4: Nukta ya Mwinamo
- 18:55 – Mradi 5: Mshale Daima Juu (mradi huu)
- 20:02 – Mradi 6: Mchezo wa Shabaha
Video inaonyesha wazi jinsi mshale unavyobadilisha mwelekeo papo hapo kulingana na jinsi moduli inavyogeuzwa. Kutazama sehemu hii kunapendekezwa sana.:contentReference[oaicite:1]{index=1}

Kusakinisha Bodi za ESP32 katika Arduino IDE
Ikiwa umekamilisha mradi wowote wa awali, usanidi wa bodi tayari umefanyika. Vinginevyo:
File > Preferences→ Ongeza URL ya bodi ya ESP32Tools > Board > Boards Manager…→ Sakinisha “ESP32”- Chagua bodi ya ESP32-S3 chini ya
Tools > Board - Chagua bandari sahihi ya USB COM chini ya
Tools > Port
Kusakinisha Maktaba Zinazohitajika
Mradi wa 5 unatumia:
Adafruit NeoMatrixAdafruit NeoPixelAdafruit GFXQMI8658(kihisi cha mwendo)
Sketch > Include Library > Manage Libraries…- Tafuta: NeoMatrix → Sakinisha
- Sakinisha vitegemezi: NeoPixel + GFX
- Tafuta na usakinishe QMI8658 na mwandishi wake
Jinsi Mradi wa 5 Unavyofanya Kazi
QMI8658C hupima mvuto kwenye shoka za X, Y, na Z. Kwa kulinganisha thamani hizi, mchoro huamua ni upande gani wa kimwili wa bodi unatazama juu:
- Upande wa USB juu
- Upande wa OUSB juu (kinyume cha USB)
- Upande “15” juu
- Upande “34” juu
Kila mwelekeo unalingana na muundo tofauti wa mshale kwenye matrix ya 8×8. Ulinganishaji unafuata mantiki yako ya mwelekeo iliyothibitishwa kutoka kwa vikao vya awali vya utatuzi. Mzunguko wa bodi husomwa kila mara, na mshale husasishwa mara tu upande wa juu unapobadilika.
Mradi 5 – Mipangilio ya Msimbo (Mshale Daima Juu)
Hapo chini ni thamani zinazoweza kubadilishwa na mtumiaji kutoka eneo la usanidi. Msimbo kamili wa mradi unaonekana kiotomatiki chini ya makala.
Usanidi wa Matrix
// Usanidi wa Matrix
const int MATRIX_PIN = 14; // imewekwa kwa moduli hii
const int MATRIX_WIDTH = 8;
const int MATRIX_HEIGHT = 8;
// Mwelekeo unaopendekezwa: Asili ya Juu-Kushoto, hali ya mfululizo
// (jeni halisi iko ndani ya msimbo uliopakiwa hapa chini)
Mradi huu unatumia mpangilio wa NEO_MATRIX_PROGRESSIVE ili kuhakikisha mshale unaelekeza kwa usahihi kulingana na mwendo halisi.
Mwangaza
uint8_t matrixBrightness = 40; // 0–255
Unaweza kuongeza thamani hii kwa mazingira yenye mwanga zaidi. Kwa matumizi ya ndani, 30–60 ni vizuri.
Rangi ya Mshale
// Rangi ya mshale
uint8_t arrowRed = 255;
uint8_t arrowGreen = 0;
uint8_t arrowBlue = 0;
Badilisha thamani hizi ili kubadilisha rangi ya mshale. Kwa mfano:
- Mshale wa kijani:
(0, 255, 0) - Mshale wa bluu:
(0, 0, 255) - Mshale mweupe:
(255, 255, 255)
Usikivu na Urekebishaji
Ili kuepuka kutetemeka, msimbo unajumuisha mantiki ya urekebishaji na kizingiti. Katika mipangilio unaweza kupata kitu kama:
// Marekebisho ya usikivu / urekebishaji
float tiltThreshold = 0.30f; // rekebisha ikiwa mshale unabadilika kwa urahisi sana
- Iki mshale wako unapinduka kwa urahisi sana → ongeza kiwango cha kizingiti.
- Ikiwa mshale unachelewa kubadilika → punguza kiwango cha kizingiti.
Miundo ya Mishale
Mchoro huu unajumuisha miundo ya bitmap ya mishale kwa:
- ↑ juu
- ↓ chini
- ← kushoto
- → kulia
Huna haja ya kurekebisha hizi, lakini unaweza kubadilisha maumbo ndani ya msimbo ikiwa unataka mtindo tofauti.
Muhtasari
Mradi wa 5 unaonyesha jinsi ESP32-S3 RGB LED Matrix na QMI8658C accelerometer zinavyofanya kazi pamoja kutambua mwelekeo na kuonyesha mshale unaoelekea juu kila wakati. Mradi huu unajengwa juu ya Tilt Dot (Mradi wa 4) na unakutayarisha kwa mchezo wa mwisho wa kuingiliana katika Mradi wa 6.
Mchoro kamili wa “Arrow Always Up” unapatikana chini ya makala hii (umepakiwa kiotomatiki). Kutazama sehemu inayolingana ya video kunapendekezwa sana ili kuona jinsi mshale unavyojibu mara moja kwa mzunguko wa bodi. Ikiwa unataka kujenga mradi huu nyumbani, viungo vya ushirika vya moduli ya ESP32-S3 RGB LED Matrix vinaonekana chini ya sehemu ya msimbo.
Bilder
This tutorial is part of: Matrix ya LED ya ESP32-S3 RGB
- Mradi wa Matrix ya LED ya RGB ya ESP32-S3 1- Nukta ya Msingi
- Mradi wa Matrix ya LED ya RGB ya ESP32-S3 2 - Maandishi Yanayotembea
- Mradi wa ESP32-S3 RGB LED Matrix 3 - Maandishi kutoka kwa simu ya mkononi
- Mradi wa ESP32-S3 RGB LED Matrix 4 - Nukta ya kuinamia
- Mchezo wa Cible wa Mradi wa Matrix ya LED ya RGB ya ESP32-S3 6
- Mradi wa Saa ya Matrix ya LED ya RGB ya ESP32-S3 Wi-Fi + NTP -1 Saa ya Msingi
- Mradi wa Saa ya Mtandao ya Matrix ya LED ya RGB ya ESP32-S3 - Saa 2 za rangi nyingi za Kuonyesha Muda na Tarehe
- Mradi wa Saa ya Mtandao ya Matrix ya LED ya RGB ya ESP32-S3 - Rangi 3 za Usiku na Tarehe
- Mradi wa Saa ya Mtandao ya Matrix ya LED ya RGB ya ESP32-S3 - Rangi 5 za Upinde wa mvua
- Mradi wa Saa ya Mtandao ya Matrix ya LED ya RGB ya ESP32-S3 - Rangi 4 za Nasibu
- 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);
}
Tänker att du kanske behöver
-
Amazon
-
eBay
-
AliExpressPurchase ESP32-S3 RGB Matrix from AliExpresss.click.aliexpress.com
-
AliExpressPurchase ESP32-S3 RGB Matrix from AliExpress (2)s.click.aliexpress.com
Resurser och referenser
-
Interna🎨 Color picker Toolrobojax.com
Filer📁
Fritzing-fil
-
esp32-S3-supermini-tht fritzing part
esp32-S3-supermini-tht.fzpz0.02 MB