Code de recherche

Projet de matrice LED RGB ESP32-S3 5 - Flèche toujours vers le haut

Projet de matrice LED RGB ESP32-S3 5 - Flèche toujours vers le haut

Projet 5 - Flèche Toujours Vers le Haut (Indicateur d'Orientation utilisant le QMI8658C)

Le projet 5 utilise le capteur de mouvement QMI8658C pour détecter l'orientation de la matrice de LED RGB ESP32-S3 et afficher toujours une flèche pointant vers le HAUT par rapport à la gravité. Peu importe comment vous faites pivoter la carte - côté USB vers le haut, côté OUSB vers le haut, côté "15" ou côté "34" - la flèche se tourne automatiquement et pointe vers la direction physiquement vers le haut.

Ceci est une démonstration puissante de la détection d'orientation en temps réel utilisant l'accéléromètre intégré. Les six projets de ce module sont présentés dans une vidéo YouTube, qui est également intégrée sur cette page. Le code complet du projet 5 se charge automatiquement en dessous de l'article, et des liens d'affiliation apparaissent sous la section du code.

Aperçu du module de matrice LED RVB ESP32-S3

Le module matriciel à LED RGB ESP32-S3 comprend plusieurs composants qui rendent ce projet possible :

  • microcontrôleur ESP32-S3- fournit Wi-Fi, BLE, et exécute la logique LED/IMU.
  • matrice LED RGB 8×8- affiche la flèche dans l'une des quatre orientations.
  • Accéléromètre QMI8658C- détecte l'inclinaison, le mouvement et l'orientation.:contentReference[oaicite:0]{index=0}
  • Port USB-Cpour la puissance et la programmation dans l'IDE Arduino.
  • Boutons de réinitialisation et de démarragepour télécharger des croquis.
  • broches GPIOdisponible autour du conseil pour des projets supplémentaires.

La direction de la flèche est déterminée entièrement par les lectures de l'accéléromètre. Lorsque la planche est tournée, le QMI8658C détecte les nouvelles valeurs X/Y/Z, et le croquis choisit quel motif de flèche (↑, ↓, ←, →) doit être dessiné.

Projets couverts dans la vidéo (horodatages)

  • 00:00- Introduction
  • 02:01- Installation des cartes ESP32
  • 03:32- Installation des bibliothèques
  • 05:32- Projet 1 : Point en Mouvement
  • 11:11- Projet 2 : Défilement de texte
  • 12:59- Projet 3 : Texte HTTP
  • 16:41- Projet 4 : Tilt Dot
  • 18:55-Projet 5 : Flèche Toujours Vers le Haut (ce projet)
  • 20:02- Projet 6 : Jeu de cible

La vidéo montre clairement comment la flèche change de direction instantanément en fonction de l'orientation du module. Il est fortement recommandé de regarder ce segment. :contentReference[oaicite:1]{index=1}

Installation des cartes ESP32 dans l'IDE Arduino

Si vous avez terminé un projet antérieur, la configuration de la planche est déjà faite. Sinon :

  1. File > Preferences→ Ajouter l'URL de la carte ESP32
  2. Tools > Board > Boards Manager…→ Installer "ESP32"
  3. Sélectionnez la carte ESP32-S3 sousTools > Board
  4. Sélectionnez le port COM USB correct sousTools > Port

Installation des bibliothèques requises

Le projet 5 utilise :

  • Adafruit NeoMatrix
  • Adafruit NeoPixel
  • Adafruit GFX
  • QMI8658(capteur de mouvement)
  1. Sketch > Include Library > Manage Libraries…
  2. Recherche :NeoMatrix→ Installer
  3. Installer les dépendances :NeoPixel+GFX
  4. Rechercher et installerQMI8658par son auteur

Comment fonctionne le Projet 5

Le QMI8658C mesure la gravité sur les axes X, Y et Z. En comparant ces valeurs, le croquis détermine quel côté physique de la carte est orienté vers le haut :

  • Côté USB vers le haut
  • Côté OUSB vers le haut(opposé USB)
  • Côté "15" vers le haut
  • Côté "34" vers le haut

Chaque orientation correspond à un motif de flèches différent sur la matrice 8×8. La correspondance suit votre logique d'orientation confirmée lors des précédentes sessions de débogage. La rotation du tableau est lue en continu, et la flèche se met à jour dès que le côté supérieur change.

Projet 5 - Paramètres du code (Flèche toujours vers le haut)

Ci-dessous se trouvent les valeurs ajustables par l'utilisateur dans la zone de configuration. Le code complet du projet apparaît automatiquement sous l'article.

Configuration de la matrice


// Matrix configuration
const int MATRIX_PIN    = 14;   // fixed for this module
const int MATRIX_WIDTH  = 8;
const int MATRIX_HEIGHT = 8;

// Recommended orientation: Top-Left origin, progressive mode
// (actual constructor is inside the code loaded below)

Ce projet utiliseNEO_MATRICE_PROGRESSIVEmise en page pour s'assurer que la flèche pointe correctement en fonction du mouvement réel.

Luminosité


uint8_t matrixBrightness = 40;   // 0–255

Vous pouvez augmenter cette valeur pour des environnements plus lumineux. Pour un usage en intérieur, 30-60 est confortable.

Couleur de la flèche


// Arrow color
uint8_t arrowRed   = 255;
uint8_t arrowGreen = 0;
uint8_t arrowBlue  = 0;

Changez ces valeurs pour modifier la couleur de la flèche. Par exemple :

  • Flèche verte :(0, 255, 0)
  • Flèche bleue :(0, 0, 255)
  • Flèche blanche :(255, 255, 255)

Sensibilité et Lissage

Pour éviter les tremblements, le code inclut une logique de lissage et de seuil. Dans les paramètres, vous pouvez trouver quelque chose comme :


// Sensitivity / smoothing adjustment
float tiltThreshold = 0.30f;   // adjust if arrow changes too easily
  • Si votre flèche se retourne trop facilement →augmenterseuil.
  • Si la flèche est trop lente à changer →diminutionseuil.

Motifs de flèches

Le croquis inclut des motifs bitmap de flèches pour :

  • ↑ haut
  • ↓ bas
  • ← gauche
  • → droite

Vous n'avez pas besoin de modifier ceux-ci, mais vous pouvez changer les formes à l'intérieur du code si vous souhaitez un style différent.

Résumé

Le projet 5 démontre comment la matrice LED RGB ESP32-S3 et l'accéléromètre QMI8658C fonctionnent ensemble pour détecter l'orientation et afficher une flèche qui pointe toujours vers le haut. Ce projet s'appuie sur le Tilt Dot (projet 4) et vous prépare pour le jeu interactif final dans le projet 6.

Le croquis complet "Arrow Always Up" est disponible sous cet article (chargé automatiquement). Il est fortement recommandé de regarder la partie correspondante de la vidéo pour voir comment l'élément flèche réagit instantanément à la rotation de la planche. Si vous souhaitez réaliser ce projet à la maison, des liens d'affiliation pour le module de matrice LED RGB ESP32-S3 apparaissent sous la section de 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++
/*
 * Projet 5 : Flèche Toujours Vers le Haut - Matrice LED RGB ESP32-S3 (Waveshare)  
 * Cette esquisse lit l'inclinaison à partir de l'IMU QMI8658C et déplace en douceur un point sur la matrice LED RGB 8×8 en fonction de l'orientation de la carte.
 * 
 * ▶️ Tutoriel Vidéo :  
 * https://youtu.be/JKLuYrRcLMI
 * 
 * 📚⬇️ Ressources & Page de Code :  
 * 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> // par Lahav Gahali

 // -------- CONFIGURATION DE LA MATRICE LED --------
#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
);

 // -------- CONFIGURATION DE L'IMU QMI8658 --------
QMI8658 imu;
QMI8658_Data imuData;

 // -------- PARAMÈTRES UTILISATEUR --------

 // vrai -> la flèche pointe vers le côté opposé
 // USB↔OUSB, 34↔15
 // faux -> la flèche pointe du même côté qui est EN HAUT
bool useOppositeMapping = false;

 // Couleur de la flèche (0-255 chacun)
uint8_t dotRed   = 0;
uint8_t dotGreen = 150;
uint8_t dotBlue  = 0;

 // Côtés de la planche
enum Side {
  SIDE_CENTER = 0,
  SIDE_USB,
  SIDE_OUSB,
  SIDE_15,
  SIDE_34
};

 // Direction pour le dessin de flèches
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 "?";
  }
}

 // -------- DESSIN DE FLÈCHE (VOTRE CODE, INCHANGÉ) --------

 // Dessinez une flèche simple sur une matrice de 8x8 pointant dans la direction donnée.
void drawArrow(ArrowDir dir, uint16_t color) {
  matrix.fillScreen(0);

  switch (dir) {
    case ARROW_UP:
 // Pourboire
      matrix.drawPixel(3, 0, color);
      matrix.drawPixel(4, 0, color);
 // Deuxième rangée
      matrix.drawPixel(2, 1, color);
      matrix.drawPixel(3, 1, color);
      matrix.drawPixel(4, 1, color);
      matrix.drawPixel(5, 1, color);
 // Arbre
      matrix.drawLine(3, 2, 3, 6, color);
      matrix.drawLine(4, 2, 4, 6, color);
      break;

    case ARROW_DOWN:
 // Pourboire
      matrix.drawPixel(3, 7, color);
      matrix.drawPixel(4, 7, color);
 // Rang au-dessus du pourboire
      matrix.drawPixel(2, 6, color);
      matrix.drawPixel(3, 6, color);
      matrix.drawPixel(4, 6, color);
      matrix.drawPixel(5, 6, color);
 // Arbre
      matrix.drawLine(3, 1, 3, 5, color);
      matrix.drawLine(4, 1, 4, 5, color);
      break;

    case ARROW_LEFT:
 // Pourboire
      matrix.drawPixel(0, 3, color);
      matrix.drawPixel(0, 4, color);
 // Colonne après pourboire
      matrix.drawPixel(1, 2, color);
      matrix.drawPixel(1, 3, color);
      matrix.drawPixel(1, 4, color);
      matrix.drawPixel(1, 5, color);
 // Arbre
      matrix.drawLine(2, 3, 6, 3, color);
      matrix.drawLine(2, 4, 6, 4, color);
      break;

    case ARROW_RIGHT:
 // Pourboire
      matrix.drawPixel(7, 3, color);
      matrix.drawPixel(7, 4, color);
 // Colonne avant pourboire
      matrix.drawPixel(6, 2, color);
      matrix.drawPixel(6, 3, color);
      matrix.drawPixel(6, 4, color);
      matrix.drawPixel(6, 5, color);
 // Arbre
      matrix.drawLine(1, 3, 5, 3, color);
      matrix.drawLine(1, 4, 5, 4, color);
      break;

    case ARROW_CENTER:
    default:
 // Simple plus au centre
      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 → DÉTECTION LATÉRALE --------
 // Nous avons calibré plus tôt :
 // +X = USB, -X = OUSB
 // +Y = 15, -Y = 34 (après votre correction)

Side detectSideUp(float ax_g, float ay_g, float az_g) {
 // Détection de logement
  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;

 // Seuils pour dire "cet axe est vraiment incliné"
  const float tiltThreshY = 0.5f;
  const float tiltThreshX = 0.5f;

 // Préférez l'axe Y pour 15 / 34
  if (fabs(ay_g) >= tiltThreshY) {
    if (ay_g > 0) {
      return SIDE_34; // +Y = 34 vers le haut
    } else {
      return SIDE_15; // -Y = 15 vers le haut
    }
  }

 // Sinon, utilisez l'axe X pour USB / OUSB
  if (fabs(ax_g) >= tiltThreshX) {
    if (ax_g > 0) {
      return SIDE_USB; // +X = USB vers le haut
    } else {
      return SIDE_OUSB; // -X = OUSB vers le haut
    }
  }

 // Pas clairement incliné → traiter comme centre
  return SIDE_CENTER;
}

 // Carte de l'UP vers l'endroit où la flèche doit pointer.
Side arrowSideFromUpSide(Side upSide) {
  if (!useOppositeMapping) {
 // La flèche montre le côté qui est en HAUT.
    return upSide;
  }

 // La flèche montre le côté opposé.
  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;
  }
}

 // Convertir SIDE en 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;
  }
}

 // ---------------- CONFIGURATION & BOUCLE ----------------

void setup() {
  Serial.begin(115200);
  delay(500);

  matrix.begin();
  matrix.setBrightness(20);
  matrix.fillScreen(0);
  matrix.show();

 // IMU : SDA=11, SCL=12 sur 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);

 // Déboguer
  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);
}

Ce dont vous pourriez avoir besoin

Ressources et références

Fichiers📁

Fichier Fritzing