Search Code

Projet ESP32-S3 Matrice LED RVB 5 - Flèche toujours vers le haut

Projet ESP32-S3 Matrice LED RVB 5 - Flèche toujours vers le haut

Projɛ́ 5 – Flɛ́shɛ́ ezalí ntángo nyɔ́nsɔ na likoló (Indicateur ya orientation na QMI8658C)

Projɛ́ 5 esálelaka senseur ya mouvement QMI8658C mpo na koyéba orientation ya ESP32-S3 RGB LED Matrix mpe kolakisa ntángo nyɔ́nsɔ flɛ́shɛ́ oyo elingi likoló na relatíf na gravité. Ata okotúna ndenge nini na kozóngisa board—libándá ya USB na likoló, libándá ya OUSB na likoló, libándá “15”, to libándá “34”—flɛ́shɛ́ yangó ekokóma na yangó moko mpe ekopɛ́nsa epái na likoló ya nzéla ya nzoto.

Yango ezalí ndakisa ya makasi ya koyéba orientation na ntángo ya sɔ́lɔ́ na esáleleli ya accéléromètre oyo ezalí na kati. Baprojɛ́ nyɔ́nsɔ motóbá ya modile oyo ezalí kolakisa na vidéo mɔ̌kɔ́ ya YouTube, oyo ezalí mpe na lokásá loye. Kode ya mobimba ya Projɛ́ 5 ezalí komɛmɛlɔ́ na nsé ya lisolo, mpe bilínki ya affiliés ezalí komɔ́nɔ na nsé ya eténi ya kode.

Bokɛ́ngɛli ya lisangá ya ESP32-S3 RGB LED Matrix Module

Module ya ESP32-S3 RGB LED Matrix ezalí na bilɔ́kɔ biyike oyo esálelaka projɛ́ oyo ekokí kosɛ́nzɛlɛ:

  • Microcontrôleur ESP32-S3 — epɛ́saka Wi-Fi, BLE, mpe esálelaka logique ya LED/IMU.
  • Matrice ya LED RGB 8×8 — elakisaka flɛ́shɛ́ na borientation minei.
  • Accéléromètre QMI8658C — eyébaka kitéka, mouvement, mpe orientation.:contentReference[oaicite:0]{index=0}
  • Port USB-C mpo na énɛ́lɛ́zi mpe programmation na Arduino IDE.
  • Boutons Reset mpe Boot mpo na kotɔ́ndɔ sketches.
  • Bilínki ya GPIO oyo ezalí zingá-zingá ya board mpo na baprojɛ́ mosúsu.

Nzelá ya flɛ́shɛ́ eyebamaka mobimba na ba lectures ya accéléromètre. Ntángo board ezalí kozóngisama, QMI8658C eyébaka ba valeurs ya sika ya X/Y/Z, mpe sketch eponaka ndenge ya flɛ́shɛ́ (↑, ↓, ←, →) oyo esengeli kolakisa.

Baprojɛ́ oyo elakisamaki na Vidéo (Bantángo)

  • 00:00 – Bokɔti
  • 02:01 – Kotíya ba boards ya ESP32
  • 03:32 – Kotíya ba bibliothèques
  • 05:32 – Projɛ́ 1: Dot oyo ezalí kotambola
  • 11:11 – Projɛ́ 2: Texte oyo ezalí kopɛ́tɛ́nɛ
  • 12:59 – Projɛ́ 3: Texte ya HTTP
  • 16:41 – Projɛ́ 4: Dot ya kitéka
  • 18:55Projɛ́ 5: Flɛ́shɛ́ ezalí ntángo nyɔ́nsɔ na likoló (projɛ́ oyo)
  • 20:02 – Projɛ́ 6: Lido ya Target

Vidéo elakisaka polele ndenge flɛ́shɛ́ ebóngwanaka nzela na mbala moko kolandela ndenge module ezalí kozóngisama. Kotála eténi oyo ezalí ntína mingi mpo na kosɛ́nzɛlɛ.:contentReference[oaicite:1]{index=1}

Kotíya ba Boards ya ESP32 na Arduino IDE

Soki osílísaki projɛ́ nyɔ́nsɔ libosó, mise en place ya board esálámaki libosó. Sinɔ́:

  1. File > Preferences → Tíya URL ya board ya ESP32
  2. Tools > Board > Boards Manager… → Tíya “ESP32”
  3. Pɔ́na board ya ESP32-S3 na nsé ya Tools > Board
  4. Pɔ́na port ya USB COM oyo ezalí na nsé ya Tools > Port

Kotíya Ba Bibliothèques Oyo Esengeli

Projɛ́ 5 esálelaka:

  • Adafruit NeoMatrix
  • Adafruit NeoPixel
  • Adafruit GFX
  • QMI8658 (senseur ya mouvement)
  1. Sketch > Include Library > Manage Libraries…
  2. Luka: NeoMatrix → Tíya
  3. Tíya ba dépendances: NeoPixel + GFX
  4. Luka mpe tíya QMI8658 na mokomi na yangó

Ndenge Projɛ́ 5 Esálelaka

QMI8658C emɛtɛlaka gravité na ba axes X, Y, mpe Z. Na kolanda ba valeurs oyo, sketch eyébaka libándá ya nzoto ya board oyo ezalí na likoló:

  • Libándá ya USB na likoló
  • Libándá ya OUSB na likoló (libándá oyo ezalí na ngámbo ya USB)
  • Libándá “15” na likoló
  • Libándá “34” na likoló

Chaque orientation ekokani na ndenge ya flɛ́shɛ́ na matrice ya 8×8. Mapping yangó elandaka logique ya orientation oyo oyébisaki na ba sessions ya débogage libosó. Kozóngisama ya board ezalí kotángama ntángo nyɔ́nsɔ, mpe flɛ́shɛ́ ebóngwanaka mbala moko ntángo libándá ya likoló ebóngwani.

Projɛ́ 5 – Ba Paramètres ya Code (Flɛ́shɛ́ Ezalí Ntángo Nyɔ́nsɔ na Likoló)

Na nsé, tala ba valeurs oyo moto akoki kobóngola na eténi ya configuration. Kode ya mobimba ya projɛ́ ezalí komɔ́nɔ na nsé ya lisolo.

Configuration ya Matrice


// Configuration ya matrice
const int MATRIX_PIN    = 14;   // ebongisami mpo na module oyo
const int MATRIX_WIDTH  = 8;
const int MATRIX_HEIGHT = 8;

// Orientation oyo epɛndami: Origine na likoló-gauche, mode progressif
// (constructeur ya sɔ́lɔ́ ezalí na kati ya kode oyo emɛmɛlɔ́ na nsé)

Projɛ́ oyo esálelaka NEO_MATRIX_PROGRESSIVE mpo na kolakisa ete flɛ́shɛ́ elingi nzela ya sɔ́lɔ́ kolandela mouvement ya sɔ́lɔ́.

Bongɛ́lɛ́


uint8_t matrixBrightness = 40;   // 0–255

Okoki komatisa valeur oyo mpo na ba environnements oyo ezalí na pole mingi. Mpo na esáleleli ya kati ya ndáko, 30–60 ezalí kitɔ́kɔ.

Langi ya Flɛ́shɛ́


// Langi ya flɛ́shɛ́
uint8_t arrowRed   = 255;
uint8_t arrowGreen = 0;
uint8_t arrowBlue  = 0;

Bóngola ba valeurs oyo mpo na kobóngola langi ya flɛ́shɛ́. Na ndakisa:

  • Flɛ́shɛ́ ya vert: (0, 255, 0)
  • Flɛ́shɛ́ ya bleu: (0, 0, 255)
  • Flɛ́shɛ́ ya pembe: (255, 255, 255)

Sensibilité mpe Lissage

Mpo na kokima jitter, kode ezalí na logique ya lissage mpe ya seuil. Na ba paramètres, okoki komɔ́nɔ elɔ́kɔ lokola:


// Ajustement ya sensibilité / lissage
float tiltThreshold = 0.30f;   // bóngola soki flɛ́shɛ́ ebóngwanaka mpasi mingi
  • Soki moto na ngala na yo ebongwani mingi → matisa motindo.
  • Soki moto na ngala ezalaki na mbala mingi mpo na kobongwana → kitisa motindo.

Bililingi ya Moto na Ngala

Sketch yango ezali na bililingi ya bitmap ya moto na ngala mpo na:

  • ↑ likolo
  • ↓ na nsé
  • ← na loboko ya mwasi
  • → na loboko ya mobali

Esengeli te kobongola yango, kasi okoki kobongola bililingi na kati ya code soki olingi lolenge mosusu.

Lisele

Projet 5 elakisaki ndenge ESP32-S3 RGB LED Matrix mpe QMI8658C accelerometer esalaka elongo mpo na koyeba esika oyo ezali mpe kolakisa moto na ngala oyo elingaka kaka na likolo. Projet oyo ebandaki na Tilt Dot (Projet 4) mpe ezali kobongisa yo mpo na lisano ya suka oyo ezali na Projet 6.

Sketch mobimba ya “Moto na Ngala Ezala Ntango Nionso na Likolo” ezali na nsé ya lisolo oyo (ezali komema na auto). Kotala eteni ya video oyo ekokani na yango ezali malamu mingi mpo na komona ndenge moto na ngala eyanganaka mbala moko na mbala moko ntango board ezali kopivana. Soki olingi kotonga projet oyo na ndako, ba liens ya affiliate mpo na module ya ESP32-S3 RGB LED Matrix ezali na nsé ya eteni ya code.

Images

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 attached with buzzer to pin6 and GND
ESP32 S3 Matrix attached with buzzer to pin6 and GND
ESP32 S3 Matrix displaying red heart
ESP32 S3 Matrix displaying red heart
ESP32 S3 Matrix displaying green heart
ESP32 S3 Matrix displaying green heart
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
ESP32-S3-Mtrix - Alway Up
ESP32-S3-Mtrix - Alway Up
803-ESP32-S3 RGB LED Matrix Project 5 - Arrow always up
Langue: C++
/* 
  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);
}

Mokili na bisika

Fichiers📁

Fritzing File