Search Code

Mashruuca LED Matrix RGB ee ESP32-S3 6 - Ciyaarta Cible

Mashruuca LED Matrix RGB ee ESP32-S3 6 - Ciyaarta Cible

Mashruuc 6 – Ciyaarta Bartilka (U Jiirka Si aad Ugu Dhufatid Goobta)

Mashruuc 6 waa kan ugu dambeeyay uguna firfircoon ee taxanahan ESP32-S3 RGB LED Matrix. Adigoo isticmaalaya dareemaha dhaqdhaqaaqa ee QMI8658C ee ku jira, waxaad u jiirsataa saxanku si dhibic ugu wareegto 8×8 matrix-ka. Aag “bartilka” oo wareeg ah ayaa ku fadhiya dhexda shaashadda. Marka dhibicdaadu taabato goobta, midabku wuu isbeddelaa oo (ikhtiyaar ahaan) buzzer ayaa dhawaq ka soo saara. Tani waxay abuurtaa ciyaar dheellitirka/isku-dubbaridka oo fudud laakiin si la yaab leh u madadaalo leh.

Dhammaan lixda mashruuc waxaa lagu muujiyay hal fiidiyoow oo YouTube ah (oo ku dhex jira boggan). Koodhka ciyaarta oo dhammaystiran ayaa si toos ah hoos ugu shubmayaa maqaalkan, iyo xiriiriyeyaasha iibsashada ee module-ka ayaa hoos kaga hoos yaal qaybta koodhka.

Guudmarka Module-ka ESP32-S3 RGB LED Matrix

Module-kani wuxuu ku darayaa:

  • ESP32-S3 microcontroller (Wi-Fi + BLE)
  • 8×8 RGB LED matrix (64 LEDs oo la cinwaan karo)
  • QMI8658C accelerometer oo loogu talagalay dareenka jiirka iyo jihada
  • USB-C dekedda korontada iyo barnaamijyada
  • Boot / Reset badhamada
  • Diyaar ah GPIO pins oo loogu talagalay waxyaabaha lagu daro sida buzzer-rada ama dareemayaasha

Ciyaartan, accelerometer-ku waa lama huraan—wuxuu si joogto ah u soo sheegaa X/Y jiirka, taasoo u oggolaanaysa dhibicda inay si habsami leh u dhaqaaqdo iyadoo ku xiran xagasha saxanka. Qaybta fiidiyowga ee mashruucan waxay si cad u muujinaysaa sida dhibicdu u simbiririxdo oo uga falceliso markaad u jiirsato module-ka bidix/midig/hor/gadaal.:contentReference[oaicite:0]{index=0}

Mashruucyada Ka Qayb Qaatay Fiidiyowga (Waqtiyada)

  • 00:00 – Hordhac
  • 02:01 – Rakibaadda ESP32 boards
  • 03:32 – Rakibaadda maktabadaha
  • 05:32 – Mashruuc 1: Dhibicda Dhaqaaqaysa
  • 11:11 – Mashruuc 2: Qoraalka Gurguurta
  • 12:59 – Mashruuc 3: HTTP Qoraal
  • 16:41 – Mashruuc 4: Dhibicda Jiirka
  • 18:55 – Mashruuc 5: Fallaar Kor
  • 20:02Mashruuc 6: Ciyaarta Bartilka (mashruucan)

Qaybtan fiidiyowga waxay muujinaysaa dhaqdhaqaaqa dhibicda iyo macquulka helista goobta labadaba, taasoo ka dhigaysa mid fudud in la fahmo sida isku-duwayaashu u dhaqmaan.:contentReference[oaicite:1]{index=1}

Rakibaadda ESP32 Boards ee Arduino IDE

Haddii aad horay u dhammeysatay mashruucyadii hore, rakibaadda board-ka waa la dhammeeyay. Haddii kale raac:

  1. File > Preferences → Ku dar URL-ka board-ka ESP32.
  2. Tools > Board > Boards Manager… → Rakib “ESP32”.
  3. Dooro board-ka ESP32-S3 ee hoos yimaada Tools > Board.
  4. Dooro COM port-ka saxda ah ee hoos yimaada Tools > Port.

Rakibaadda Maktabadaha Loo Baahan Yahay

Ciyaartan waxay isticmaashaa:

  • Adafruit NeoMatrix
  • Adafruit NeoPixel
  • Adafruit GFX
  • QMI8658 (dareemaha dhaqdhaqaaqa)

Ku rakib iyaga:

  1. Sketch > Include Library > Manage Libraries…
  2. Raadi: NeoMatrix → Rakib
  3. Rakib waxyaabaha ku xiran (GFX + NeoPixel)
  4. Raadi oo rakib QMI8658

Sida Ciyaarta Bartilka U Shaqeyso

QMI8658C accelerometer-ku wuxuu bixiyaa qiimayaasha jiirka X iyo Y. Kuwaas waxaa loo qoondeeyay isku-duwayaasha LED (0–7 labada jiho). Dhibicdaadu waxay ku dhaqaaqdaa matrix-ka iyadoo ku xiran xagasha saxanka.

Goobo (ama giraan) ayaa lagu sawiraa shaashadda oo ah “aagga bartilka.” Waxaad ku guuleysataa “dhufasho” markasta oo dhibicdu ay isku dul saarto goobta. Markaas:

  • Midabka bartilka wuu isbeddelaa (random ama horay loo qoondeeyay)
  • Buzzer ikhtiyaari ah ayaa dhawaq ka soo saara (haddii lagu xiro)

Maaddaama matrix-ku uu yar yahay, goobta waxaa lagu sawiraa iyadoo la isticmaalayo hubin radius fudud. Ciyaartu si joogto ah ayay u socotaa, marka waxaad u jiirsan kartaa dib iyo gudub si aad goobta marar badan ugu dhufatid.

Mashruuc 6 – Dejinta Koodhka (Ciyaarta Bartilka)

Hoos waxaa ku yaal dejinta ugu weyn ee isticmaaluhu wax ka beddeli karo oo ku taal dusha qoraalka. Koodhka oo dhammaystiran ayaa si toos ah hoos ugu shubmayaa maqaalkan.

Qaabaynta Matrix-ka


// Qaabaynta Matrix-ka
const int MATRIX_PIN    = 14;
const int MATRIX_WIDTH  = 8;
const int MATRIX_HEIGHT = 8;

RGB matrix-ku wuxuu si toos ah ugu xiran yahay GPIO 14—ha beddelin tan.

Iftiinka


uint8_t matrixBrightness = 40;   // 0–255

Isticmaalka gudaha, 30–60 ayaa ku habboon.

Midabka Dhibicda


// Midabka dhibicda (R, G, B)
uint8_t dotRed   = 255;
uint8_t dotGreen = 255;
uint8_t dotBlue  = 255;

Tani waa dhibicda aad ku dhaqaaqdo adigoo u jiirsanaya saxanka.

Midabka Goobta (Random ama Go'an)


// Midabka goobta (bartilka)
uint8_t circleRed   = 0;
uint8_t circleGreen = 0;
uint8_t circleBlue  = 255;

// Haddii run yahay, dooro midab random cusub mar kasta oo dhibicdu dhufato
bool randomCircleColor = true;

Deji randomCircleColor = false; haddii aad rabto midab go'an.

Radius-ka Goobta


// Cabbirka bartilka (radius)
int targetRadius = 3;   // 3 wuxuu si fiican ugu habboon yahay 8×8 matrix-ka

Radius-yada waaweyn waxay ciyaarta ka dhigaan mid fudud; kuwa yar waxay ka dhigaan mid adag.

Xasaasiyadda Jiirka


// Xasaasiyadda qoondeynta jiirka
float tiltScale = 4.0f;   // kordhi = dhaqaaq degdeg ah oo shaashadda ah

Haddii dhibicdu si aad u degdeg ah u dhaqaaqdo ama ay boodbooddo, yaree lambarkan.

Dejinta Buzzer-ka (Ikhtiyaar)


// Buzzer pin (ikhtiyaar ah)
int buzzerPin = 6;      // ku xidh buzzer + ilaa pin 6, – ilaa GND
bool useBuzzer = true;  // dhig false si aad u damiso codka

Haddii aadan ku xidhin buzzer, si fudud u dhig useBuzzer = false;

Soo koobid

Mashruuca 6 wuxuu isku darayaa wax kasta oo laga bartay mashruucyadii hore: sawiridda matrix-ka, gelinta xawaare-cabbirka (accelerometer), xakamaynta midabka, jilcinta dhaqdhaqaaqa, iyo cod ikhtiyaari ah. Horyaalinta looxa ayaa dhaqaajinaysa dhibcaha, iyo ku dhufashada goobada ayaa beddesha midabkeeda iyo (ikhtiyaar ahaan) kicisa beep. Waa muujin xiiso leh oo ku saabsan dareenka dhaqdhaqaaqa ee bandhigga RGB ee isku-kooban.

Koodhka buuxa ee “Target Game” wuxuu si toos ah hoos ugu soo baxayaa maqaalkan. Waxaad sidoo kale daawan kartaa qaybta Mashruuca 6 ee fiidiyowga si aad u aragto sida dhibcuhu u dhaqaaqaan iyo sida ku dhufashada loo ogaado. Haddii aad rabto inaad dhisto ciyaar adiga kuu gaar ah, xiriiriyeyaasha la xiriira ee lagu iibsado module-ka ESP32-S3 RGB LED Matrix ayaa hoos kaaga muuqanaya qaybta koodhka.

Sawirro

ESP32 S3 Matrix
ESP32 S3 Matrix
ESP32 S3 Matrix  pin out
ESP32 S3 Matrix pin out
ESP32-S3_RGB_8x8_matrix-3
ESP32-S3_RGB_8x8_matrix-3
ESP32 S3 Matrix displaying rainbow heart 3
ESP32 S3 Matrix displaying rainbow heart 3
ESP32-S3_RGB_8x8_matrix1
ESP32-S3_RGB_8x8_matrix1
ESP32-S3_RGB_8x8_matrix-2
ESP32-S3_RGB_8x8_matrix-2
804-ESP32-S3 RGB LED Matrix Project 6 - Cible game
Luqadda: C++
/* 
  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);
}

Waad u baahan tahay

Kheyraadka & Tixraacyada

Faylasha📁

Faylka Fritzing