Search Code

Aikin Matrix LED RGB na ESP32-S3 6 - Wasan Cible

Aikin Matrix LED RGB na ESP32-S3 6 - Wasan Cible

Aikin 6 – Wasan Manufa (Karkatar da Allon don Buga Da'irar)

Aikin 6 shine na ƙarshe kuma mafi yawan mu'amala a cikin wannan jerin ESP32-S3 RGB LED Matrix. Ta amfani da na'urar motsi ta QMI8658C da ke cikin allo, kana karkatar da allon don matsar da digo a kusa da matrix 8×8. Wani “yankin manufa” mai madauwari yana zaune a tsakiyar nuni. Lokacin da digonka ya taɓa da'irar, launi yana canzawa kuma (zaɓin) ƙararrawa tana yin ƙara. Wannan yana haifar da wasa mai sauƙi amma mai ban sha'awa na daidaitawa/daidaitawa.

Dukkan ayyuka shida ana nuna su a cikin bidiyon YouTube guda ɗaya (wanda aka saka a wannan shafin). Cikakken lambar wasan ana loda shi ta atomatik a ƙasan wannan labarin, kuma hanyoyin sayan haɗin gwiwa don modul ɗin suna bayyana a ƙarƙashin sashin lambar.

Bayanin Modul ɗin ESP32-S3 RGB LED Matrix

Wannan modul ɗin ya haɗa da:

  • ESP32-S3 microcontroller (Wi-Fi + BLE)
  • 8×8 RGB LED matrix (LEDs 64 masu adireshi)
  • QMI8658C accelerometer don jin karkata da fuskantarwa
  • USB-C tashar don wuta da shirye-shirye
  • Boot / Reset maɓallai
  • Akwai GPIO pins don ƙari kamar ƙararrawa ko na'urori masu auna

Don wannan wasan, accelerometer yana da mahimmanci—yana ba da rahoton karkatar X/Y akai-akai, yana ba da damar digo ya motsa cikin sauƙi bisa kusurwar allo. Sashin bidiyo na wannan aikin yana nuna a sarari yadda digo ke zamewa da amsawa yayin da kake karkatar da modul ɗin hagu/dama/gaba/baya.:contentReference[oaicite:0]{index=0}

Ayyukan Da aka Rufe a Bidiyon (Lokutan)

  • 00:00 – Gabatarwa
  • 02:01 – Saka allunan ESP32
  • 03:32 – Saka ɗakunan karatu
  • 05:32 – Aiki 1: Motsa Digo
  • 11:11 – Aiki 2: Rubutu Mai Gudana
  • 12:59 – Aiki 3: Rubutun HTTP
  • 16:41 – Aiki 4: Digon Karkata
  • 18:55 – Aiki 5: Kibiya Sama
  • 20:02Aiki 6: Wasan Manufa (wannan aikin)

Wannan ɓangaren bidiyon yana nuna duka motsin digo da kuma dabaru na gano da'irar a aikace, yana sauƙaƙa fahimtar yadda haɗin gwiwar ke aiki.:contentReference[oaicite:1]{index=1}

Saka Allunan ESP32 a Arduino IDE

Idan ka riga ka kammala ayyukan da suka gabata, shigar da allo ya ƙare. In ba haka ba bi:

  1. File > Preferences → Ƙara URL ɗin allon ESP32.
  2. Tools > Board > Boards Manager… → Saka “ESP32”.
  3. Zaɓi allon ESP32-S3 a ƙarƙashin Tools > Board.
  4. Zaɓi tashar COM da ta dace a ƙarƙashin Tools > Port.

Saka Ɗakunan Karatu Da Ake Bukata

Wannan wasan yana amfani da:

  • Adafruit NeoMatrix
  • Adafruit NeoPixel
  • Adafruit GFX
  • QMI8658 (na'urar motsi)

Saka su ta:

  1. Sketch > Include Library > Manage Libraries…
  2. Bincika: NeoMatrix → Saka
  3. Saka abubuwan dogaro (GFX + NeoPixel)
  4. Bincika kuma saka QMI8658

Yadda Wasan Manufa Yake Aiki

QMI8658C accelerometer yana ba da ƙimar karkatar X da Y. Ana danganta waɗannan zuwa haɗin gwiwar LED (0–7 a duka hanyoyin). Digonka yana motsawa a kan matrix bisa kusurwar allo.

Ana zana da'ira (ko zobe) a kan nuni a matsayin “yankin manufa.” Kana samun “bugu” a duk lokacin da digo ya haɗu da da'irar. A wannan lokacin:

  • Launin manufa yana canzawa (bazuwar ko an riga an ƙayyade)
  • Ƙararrawa mai zaɓi tana yin ƙara (idan an haɗa)

Tun da matrix ɗin karami ne, ana zana da'irar ta amfani da duba radius mai sauƙi. Wasan yana gudana akai-akai, don haka kana iya karkata gaba da baya don buga da'irar akai-akai.

Aiki 6 – Saitunan Lambar (Wasan Manufa)

A ƙasa akwai manyan saitunan da mai amfani zai iya daidaita waɗanda ke saman sketch ɗin. Cikakken lambar an haɗa shi ta atomatik a ƙasan wannan labarin.

Tsarin Matrix


// Tsarin matrix
const int MATRIX_PIN    = 14;
const int MATRIX_WIDTH  = 8;
const int MATRIX_HEIGHT = 8;

RGB matrix ɗin an haɗa shi da waya zuwa GPIO 14—kada ka canza wannan.

Haskewa


uint8_t matrixBrightness = 40;   // 0–255

Don amfani a cikin gida, 30–60 ya fi dacewa.

Launin Digo


// Launin digo (R, G, B)
uint8_t dotRed   = 255;
uint8_t dotGreen = 255;
uint8_t dotBlue  = 255;

Wannan shine digon da kake motsawa ta hanyar karkatar da allon.

Launin Da'ira (Bazuwar ko Tsayayye)


// Launin da'ira (manufa)
uint8_t circleRed   = 0;
uint8_t circleGreen = 0;
uint8_t circleBlue  = 255;

// Idan gaskiya ne, zaɓi sabon launi bazuwar kowane lokacin da digo ya buga
bool randomCircleColor = true;

Saita randomCircleColor = false; idan kana son launi tsayayye.

Radius ɗin Da'ira


// Girman manufa (radius)
int targetRadius = 3;   // 3 ya dace da kyau akan matrix 8×8

Manyan radii suna sauƙaƙa wasan; ƙanana suna ƙara wahala.

Hankalin Karkata


// Hankalin taswirar karkata
float tiltScale = 4.0f;   // ƙara = saurin motsi a kan allo

Idan digo yana motsawa da sauri ko yana tsalle, rage wannan lambar.

Saitunan Ƙararrawa (Zaɓi)


// Fil ɗin buzzer (na zaɓi)
int buzzerPin = 6;      // haɗa buzzer + zuwa pin 6, – zuwa GND
bool useBuzzer = true;  // saita false don kashe sauti

Idan ba ka haɗa buzzer ba, kawai saita useBuzzer = false;

Taƙaitawa

Project 6 ya haɗa duk abin da aka koya daga ayyukan da suka gabata: zanen matrix, shigar da accelerometer, sarrafa launi, sassauta motsi, da sauti na zaɓi. Karkatar da allo yana motsa ɗigon, kuma buga da'irar yana canza launinsa kuma (na zaɓi) yana kunna ƙararrawa. Wannan nuni ne mai daɗi na gano motsi akan nunin RGB mai ƙarami.

Cikakken lambar “Wasannin Target” ana nuna shi ta atomatik a ƙasan wannan labarin. Kana iya kallon ɓangaren Project 6 na bidiyon don ganin yadda ɗigon ke motsawa da yadda ake gano bugu. Idan kana son gina wasanka, hanyoyin haɗin sayan modul ɗin ESP32-S3 RGB LED Matrix suna ƙarƙashin ɓangaren lambar.

Hotuna

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
Harshe: 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);
}

Abin da zaka iya bukata

Albarkatun da kuma shafukan da za a duba

Fayiloli📁

Fayil Fritzing