This tutorial is part of: ESP32-S3 RGB LED ማትሪክስ
አስደሳች እና ተግባራዊ አፕሊኬሽኖችን ለመፍጠር የESP32-S3 RGB ማትሪክስ ሞጁልን በመጠቀም አሪፍ ፕሮጀክት። ወደ ሌሎች ቪዲዮዎች የሚወስዱ አገናኞች ከዚህ ጽሑፍ በታች ይገኛሉ።
ESP32-S3 RGB LED ማትሪክስ ፕሮጀክት 4 - ዘንበል ነጥብ
ፕሮጀክት 4 – ቲልት ዶት (ESP32-S3 RGB LED ማትሪክስን በማዘንበል ነጥቡን ያንቀሳቅሱ)
ፕሮጀክት 4 በESP32-S3 RGB LED ማትሪክስ ሞጁል ውስጥ የተሰራውን የእንቅስቃሴ ዳሳሽ ያስተዋውቃል። ነጥቡን በራስ-ሰር ከማንቀሳቀስ (እንደ ፕሮጀክት 1) ወይም ጽሑፍን ከማሸብለል (ፕሮጀክቶች 2 እና 3) ይልቅ፣ ይህ ፕሮጀክት ቦርዱን በማዘንበል ብቻ የነጥቡን ቦታ እንዲቆጣጠሩ ያስችልዎታል። ነጥቡ በሞጁሉ ጀርባ ላይ ካለው የQMI8658C አክስሌሮሜትር የቀጥታ ንባቦች ላይ በመመስረት በ8×8 RGB ማሳያ ላይ በተቀላጠፈ ሁኔታ ይንቀሳቀሳል።
በዚህ ተከታታይ ውስጥ ያሉት ስድስቱም ፕሮጀክቶች በአንድ የYouTube ቪዲዮ ውስጥ ተብራርተዋል። ተመሳሳዩ ቪዲዮ በዚህ ገጽ ላይ ተካቷል፣ ስለዚህ ቦርዱ ሲዘነበል ነጥቡ በእውነተኛ ጊዜ እንዴት እንደሚንቀሳቀስ በትክክል ማየት ይችላሉ። ለዚህ ፕሮጀክት የተሟላ ኮድ ከጽሑፉ በታች በራስ-ሰር ይጫናል፣ እና ለሞጁሉ የተባበሩት የግዢ አገናኞች ከኮድ ክፍሉ በታች ይታያሉ።


የESP32-S3 RGB LED ማትሪክስ ሞጁል አጠቃላይ እይታ
ይህ ፕሮጀክት የሚከተሉትን ያካተተውን የESP32-S3 RGB LED ማትሪክስ ሞጁል ይጠቀማል፦

- ESP32-S3 ማይክሮኮንትሮለር ከWi-Fi እና ብሉቱዝ ጋር
- 8×8 RGB LED ማትሪክስ (64 በተናጠል አድራሻ የሚያገኙ LEDs)
- QMI8658C አክስሌሮሜትር በጀርባ ላይ ለማዘንበል እና ለእንቅስቃሴ መለየት
- USB ወደብ ለፕሮግራም አወጣጥ እና ለኃይል
- Boot / Reset አዝራሮች
- ጥቅም ላይ ሊውሉ የሚችሉ GPIO ፒኖች ለወደፊት ማስፋፊያ
የQMI8658C ዳሳሽ X፣ Y እና Z የፍጥነት እና የአቅጣጫ እሴቶችን ያነባል፣ ይህም ቦርዱ እንዴት እንደተዘነበለ መሰረት በማድረግ ነጥቡ ወደ ላይ/ወደ ታች/ወደ ግራ/ወደ ቀኝ እንዲንቀሳቀስ ያስችላል።

በቪዲዮው ውስጥ የተካተቱ ፕሮጀክቶች (የጊዜ ምልክቶች)
- 00:00 – መግቢያ
- 02:01 – የESP32 ቦርዶችን መጫን
- 03:32 – ቤተ-መጻሕፍትን መጫን
- 05:32 – ፕሮጀክት 1፡ የሚንቀሳቀስ ነጥብ
- 11:11 – ፕሮጀክት 2፡ የጽሑፍ ማሸብለል
- 12:59 – ፕሮጀክት 3፡ HTTP ጽሑፍ
- 16:41 – ፕሮጀክት 4፡ ቲልት ዶት (ይህ ፕሮጀክት)
- 18:55 – ፕሮጀክት 5፡ ወደ ላይ ቀስት
- 20:02 – ፕሮጀክት 6፡ ዒላማ ጨዋታ
በቪዲዮው ውስጥ ያለውን የማዘንበል ማሳያ መመልከት በጣም ይመከራል፣ ምክንያቱም ነጥቡ ለቦርዱ አቅጣጫ በተቀላጠፈ ሁኔታ እንዴት ምላሽ እንደሚሰጥ ማየት ይችላሉ።

ESP32 ቦርዶችን በArduino IDE ውስጥ መጫን
ከዚህ ቀደም ማንኛውንም ፕሮጀክት ካጠናቀቁ፣ የቦርድ ድጋፉ አስቀድሞ ተጭኗል። አለበለዚያ፣ እነዚህን ደረጃዎች ይከተሉ፦
File > Preferencesይክፈቱ → የESP32 ቦርዶች URL ያክሉ።- ወደ
Tools > Board > Boards Manager…ይሂዱ እና ESP32 ይጫኑ። - የESP32-S3 ቦርድዎን በ
Tools > Boardስር ይምረጡ። - ትክክለኛውን COM ወደብ በ
Tools > Portስር ይምረጡ።
የሚፈለጉ ቤተ-መጻሕፍትን መጫን
ይህ ፕሮጀክት የሚከተሉትን ቤተ-መጻሕፍት ይፈልጋል፦
Adafruit NeoMatrixAdafruit NeoPixelAdafruit GFX LibraryQMI8658(የእንቅስቃሴ ዳሳሽ)
በቤተ-መጻሕፍት አስተዳዳሪ ውስጥ ይጫኗቸው፦
Sketch > Include Library > Manage Libraries…ይክፈቱ።- Adafruit NeoMatrix ይፈልጉ → ይጫኑ።
- Adafruit GFX እና Adafruit NeoPixel በራስ-ሰር እንዲጫኑ ይፍቀዱ።
- QMI8658 በተዘረዘረው ደራሲ ይፈልጉ → ይጫኑ።
ፕሮጀክት 4 እንዴት እንደሚሰራ
የQMI8658C ዳሳሽ በX፣ Y እና Z ዘንጎች ላይ የፍጥነት መረጃን ያለማቋረጥ ያቀርባል። ለዚህ ፕሮጀክት፣ ለመወሰን X እና Y ዘንጎችን ብቻ እንጠቀማለን፦
- ነጥቡ ወደ ግራ ወይም ወደ ቀኝ ምን ያህል እንደሚንቀሳቀስ (X ዘንግ)
- ነጥቡ ወደ ላይ ወይም ወደ ታች ምን ያህል እንደሚንቀሳቀስ (Y ዘንግ)
የዳሳሽ እሴቶቹ ከ0 እስከ 7 ባለው የመጋጠሚያ ክልል ውስጥ (ለ8×8 LED ማትሪክስ) ይቀረጻሉ። የነጥቡ ቦታ በሰከንድ ብዙ ጊዜ ይዘምናል፣ ይህም ሞጁሉን ሲያዘነብሉ ለስላሳ የመንሸራተት ውጤት ይሰጣል።
ፕሮጀክት 4 – የኮድ ቅንብሮች (ቲልት ዶት)
ከዚህ በታች በፕሮጀክቱ ኮድ አናት አጠገብ የሚገኙት በተጠቃሚ ሊስተካከሉ የሚችሉ ቅንብሮች ናቸው። ሙሉው ስኬች ከጽሑፉ በታች በራስ-ሰር ይታያል።
የማትሪክስ ፒን እና መጠን
// 8×8 RGB ማትሪክስ ውቅር
const int MATRIX_PIN = 14; // ለዚህ ቦርድ ቋሚ ፒን
const int MATRIX_WIDTH = 8;
const int MATRIX_HEIGHT = 8;
MATRIX_PINን በ14 ላይ ይተዉት። በቦርዱ ላይ ካለው ማትሪክስ ጋር በቋሚነት የተገናኘ ነው።
ብሩህነት
// አጠቃላይ ብሩህነት (0–255)
uint8_t matrixBrightness = 40;
አስፈላጊ ከሆነ ይጨምሩ፣ ነገር ግን በቅርብ ሲመለከቱ ከፍተኛ ብሩህነትን ያስወግዱ።
የነጥብ ቀለም
// የነጥብ ቀለም (R, G, B)
uint8_t dotRed = 0;
uint8_t dotGreen = 200; // ቀላል አረንጓዴ (ነባሪ)
uint8_t dotBlue = 0;
ማንኛውንም ቀለም ለመፍጠር እነዚህን እሴቶች ይቀይሩ። ምሳሌዎች፦
- ቀይ፡
(255, 0, 0) - ቢጫ፡
(255, 255, 0) - ነጭ፡
(255, 255, 255)
የእንቅስቃሴ ስሜታዊነት
ከፍተኛ ዝላይዎችን ለመከላከል፣ የአክስሌሮሜትር እሴቶች ብዙውን ጊዜ ይገደባሉ ወይም ይስተካከላሉ። የተለመደ ቅንብር ይህን ይመስላል፦
// ማዘንበል በእንቅስቃሴ ላይ ያለው ተጽዕኖ ምን ያህል ኃይለኛ እንደሆነ
float sensitivity = 4.0f; // ትልቅ = በማያ ገጽ ላይ ፈጣን እንቅስቃሴ
ነጥቡ በጣም በዝግታ ከተንቀሳቀሰ → እሴቱን ይጨምሩ። ነጥቡ በጣም በድንገት ከተንቀሳቀሰ → ይቀንሱት።
የማዘመን ፍጥነት (የማደስ መጠን)
በዝማኔዎች መካከል እንቅስቃሴን ለማለስለስ ትንሽ መዘግየት ማከል ይችላሉ፦
// በቦታ ዝማኔዎች መካከል መዘግየት (ሚሴኮንድ)
int refreshDelayMs = 20; // ዝቅተኛ = ለስላሳ እና ፈጣን ምላሽ
ከ10–30 ሚሴኮንድ መካከል ያሉ እሴቶች በጣም ፈጣን ምላሽ ይሰጣሉ።
ማጠቃለያ
ፕሮጀክት 4 የESP32-S3 አብሮ የተሰራውን QMI8658C አክስለሮሜትር በአካላዊ እንቅስቃሴ የLED ማትሪክስ እንዲቆጣጠሩ በማድረግ ህያው ያደርገዋል። የቦርዱ ትንሽ ዘንበል ነጥቡን ወደ ተመሳሳይ አቅጣጫ ያንቀሳቅሰዋል፣ ይህም ፕሮጀክቱን ለበለጠ የላቁ የ“Arrow Up” እና የ“Target Game” ፕሮጀክቶች ፍጹም መሰላል ያደርገዋል።
ሙሉው የTilt Dot ስኬች ከዚህ ጽሑፍ በታች (በራስ-ሰር) ተጭኗል። ለተሻለ ግንዛቤ፣ ቦርዱ ሲሽከረከር ነጥቡ እንዴት በተለሰለሰ ሁኔታ እንደሚንቀሳቀስ በሚታይበት ቪዲዮ ውስጥ የማዘንበል ማሳያውን ይመልከቱ። የESP32-S3 RGB LED ማትሪክስ ሞጁል ለመግዛት አገናኞች በኮድ ክፍሉ ስር ተካትተዋል።
This tutorial is part of: ESP32-S3 RGB LED ማትሪክስ
- ESP32-S3 RGB LED ማትሪክስ ፕሮጀክት 1- መሰረታዊ ነጥብ
- የESP32-S3 RGB LED ማትሪክስ ፕሮጀክት 2 - የሚንቀሳቀስ ጽሑፍ
- የESP32-S3 RGB LED ማትሪክስ ፕሮጀክት 3 - ከሞባይል ስልክ የሚመጣ ጽሑፍ
- ESP32-S3 RGB LED ማትሪክስ ፕሮጀክት 5 - ቀስት ሁልጊዜ ወደ ላይ
- የESP32-S3 RGB LED ማትሪክስ ፕሮጀክት 6 - ሲብል ጨዋታ
- ESP32-S3 RGB LED ማትሪክስ ዋይ-ፋይ + NTP የሰዓት ፕሮጀክት -1 መሰረታዊ ሰዓት
- የESP32-S3 RGB LED ማትሪክስ የበይነመረብ ሰዓት ፕሮጀክት - 2 ሰዓት ባለብዙ ቀለም ጊዜ እና ቀን ማሳያ
- የESP32-S3 RGB LED ማትሪክስ የበይነመረብ ሰዓት ፕሮጀክት - 3 የምሽት ቀለም ከቀን ጋር
- የESP32-S3 RGB LED ማትሪክስ የበይነመረብ ሰዓት ፕሮጀክት - 5 የቀስተ ደመና ቀለም
- የESP32-S3 RGB LED ማትሪክስ የበይነመረብ ሰዓት ፕሮጀክት - 4 የዘፈቀደ ቀለም
- ESP32-S3 RGB LED Matrix test for RGB, GRB setting
/*
Project 4: Tilt Dot – 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
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 -> dot on opposite side: USB↔OUSB, 34↔15
// false -> dot on same side as UP
bool useOppositeMapping = false;
// Dot color (0–255 each)
uint8_t dotRed = 0;
uint8_t dotGreen = 100;
uint8_t dotBlue = 0;
// Board sides
enum Side {
SIDE_CENTER = 0,
SIDE_USB,
SIDE_OUSB,
SIDE_15,
SIDE_34
};
// Smooth dot position (in pixel coordinates, but kept as float for easing)
float dotPosX = 3.0f; // start at center
float dotPosY = 3.0f;
// Smoothing factor: smaller = slower movement (0.1 very slow, 0.5 faster)
const float dotSmooth = 0.25f;
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 "?";
}
}
// Detect which side is UP using calibrated axes:
// +X = USB, -X = OUSB, +Y = 34, -Y = 15
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;
// 1) Prefer Y axis for 15 / 34 if it's clearly tilted
if (fabs(ay_g) >= tiltThreshY) {
if (ay_g > 0) {
return SIDE_15; // +Y = 34 up
} else {
return SIDE_34; // -Y = 15 up
}
}
// 2) Otherwise, check 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
}
}
// 3) If nothing is strongly tilted, just call it CENTER
return SIDE_CENTER;
}
// Map from UP side to where the dot should go
Side dotSideFromUpSide(Side upSide) {
switch (upSide) {
case SIDE_USB:
return useOppositeMapping ? SIDE_OUSB : SIDE_USB;
case SIDE_OUSB:
return useOppositeMapping ? SIDE_USB : SIDE_OUSB;
case SIDE_34:
return useOppositeMapping ? SIDE_15 : SIDE_34;
case SIDE_15:
return useOppositeMapping ? SIDE_34 : SIDE_15;
case SIDE_CENTER:
default:
return SIDE_CENTER;
}
}
// Convert dot side to matrix coordinates
void getDotPixel(Side dotSide, int &px, int &py) {
// Matrix (0,0) = top-left
// top center: (3,0) → USB
// bottom center: (3,7) → OUSB
// left center: (0,3) → 15
// right center: (7,3) → 34
// center: (3,3)
switch (dotSide) {
case SIDE_USB: px = 3; py = 0; break;
case SIDE_OUSB: px = 3; py = 7; break;
case SIDE_15: px = 0; py = 3; break;
case SIDE_34: px = 7; py = 3; break;
case SIDE_CENTER:
default: px = 3; py = 3; break;
}
}
void setup() {
Serial.begin(115200);
delay(500);
matrix.begin();
matrix.setBrightness(20);
matrix.fillScreen(0);
matrix.show();
// IMU: SDA=11, SCL=12 for 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 dotSide = dotSideFromUpSide(upSide);
int targetX, targetY;
getDotPixel(dotSide, targetX, targetY);
// --- Smooth movement toward target ---
dotPosX += (targetX - dotPosX) * dotSmooth;
dotPosY += (targetY - dotPosY) * dotSmooth;
// Convert to integer pixel coordinates
int px = (int)round(dotPosX);
int py = (int)round(dotPosY);
// Clamp just in case
if (px < 0) px = 0;
if (px > 7) px = 7;
if (py < 0) py = 0;
if (py > 7) py = 7;
// --- Draw dot ---
matrix.fillScreen(0);
uint16_t color = matrix.Color(dotRed, dotGreen, dotBlue);
matrix.drawPixel(px, py, color);
matrix.show();
// 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(" | DOT="); Serial.print(sideName(dotSide));
Serial.print(" | px="); Serial.print(px);
Serial.print(" py="); Serial.println(py);
delay(80);
}
እንደሚያስፈልግዎት ይችላል
-
አማዞን
-
ኢቤይ
-
አሊኤክስፕሬስPurchase ESP32-S3 RGB Matrix from AliExpresss.click.aliexpress.com
-
አሊኤክስፕሬስPurchase ESP32-S3 RGB Matrix from AliExpress (2)s.click.aliexpress.com
ምንጮች እና ምንጮች
-
ውስጥ🎨 Color picker Toolrobojax.com
ፋይሎች📁
ፍሪትዚንግ ፋይል
-
esp32-S3-supermini-tht fritzing part
esp32-S3-supermini-tht.fzpz0.02 MB