Code de recherche

Projet de matrice LED RGB ESP32-S3 4 - Point incliné

Projet de matrice LED RGB ESP32-S3 4 - Point incliné

Projet 4 - Tilt Dot (Déplacer le point en inclinant la matrice LED RGB ESP32-S3)

Le projet 4 introduit le capteur de mouvement intégré au module de matrice LED RGB ESP32-S3. Au lieu de déplacer le point automatiquement (comme dans le projet 1) ou de faire défiler du texte (projets 2 et 3), ce projet vous permet de contrôler la position du point simplement en inclinant la carte. Le point se déplace en douceur sur l'affichage RGB 8×8 en fonction des lectures en temps réel du capteur d'accélération QMI8658C à l'arrière du module.

Tous les six projets de cette série sont démontrés dans une vidéo YouTube. La même vidéo est intégrée sur cette page, vous pouvez donc voir exactement comment le point se déplace en temps réel alors que le tableau s'incline. Le code complet pour ce projet est chargé automatiquement sous l'article, et les liens d'achat affiliés pour le module apparaissent sous la section du code.

Aperçu du module matrice LED RGB ESP32-S3

Ce projet utilise le module matrice LED RVB ESP32-S3, qui comprend :

  • microcontrôleur ESP32-S3avec Wi-Fi et Bluetooth
  • matrice LED RGB 8×8(64 LEDs adressables individuellement)
  • QMI8658C accéléromètreà l'arrière pour la détection d'inclinaison et de mouvement
  • port USBpour la programmation et l'énergie
  • Boutons de démarrage / de réinitialisation
  • Broches GPIO utilisablespour une future expansion

Le capteur QMI8658C litX,Y, etZvaleurs d'accélération et d'orientation, permettant au point de se déplacer vers le haut/bas/gauche/droite en fonction de l'inclinaison de la planche.:contentReference[oaicite:0]{index=0}

Projets couverts dans la vidéo (horodatages)

  • 00:00- Introduction
  • 02:01- Installation des cartes ESP32
  • 03:32- Installer 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 (ce projet)
  • 18:55- Projet 5 : Flèche vers le haut
  • 20:02- Projet 6 : Jeu de Cible

Il est fortement recommandé de regarder la démonstration d'inclinaison dans la vidéo, car vous pouvez voir comment le point réagit en douceur à l'orientation de la planche.:contentReference[oaicite:1]{index=1}

Installer les cartes ESP32 dans l'IDE Arduino

Si vous avez terminé un projet antérieur, le support de la carte est déjà installé. Sinon, suivez ces étapes :

  1. OuvrirFile > Preferences→ Ajouter l'URL des cartes ESP32.
  2. Aller àTools > Board > Boards Manager…et installerESP32.
  3. Sélectionnez votre carte ESP32-S3 sousTools > Board.
  4. Sélectionnez le port COM correct sousTools > Port.

Installation des bibliothèques requises

Ce projet nécessite les bibliothèques suivantes :

  • Adafruit NeoMatrix
  • Adafruit NeoPixel
  • Adafruit GFX Library
  • QMI8658(capteur de mouvement)

Installez-les dans le Gestionnaire de bibliothèques :

  1. OuvrirSketch > Include Library > Manage Libraries….
  2. Rechercher pourAdafruit NeoMatrix→ Installer.
  3. Autoriser l'installation automatique deAdafruit GFXetAdafruit NeoPixel.
  4. Rechercher pourQMI8658par son auteur référencé → Installer.:contentReference[oaicite:2]{index=2}

Comment fonctionne le Projet 4

Le capteur QMI8658C fournit en continu des données d'accélération le long des axes X, Y et Z. Pour ce projet, nous n'utilisons que les axes X et Y pour décider :

  • Quelle distance déplacer le point vers la gauche ou la droite (axe X)
  • De combien déplacer le point vers le haut ou vers le bas (axe Y)

Les valeurs du capteur sont mappées dans une plage de coordonnées de 0 à 7 (pour la matrice LED 8×8). La position du point se met à jour plusieurs fois par seconde, donnant un effet de glissement fluide lorsque vous inclinez le module.:contentReference[oaicite:3]{index=3}

Projet 4 - Paramètres de code (Tilt Dot)

Ci-dessous se trouvent les paramètres modifiables par l'utilisateur, situés près du haut du code du projet. Le croquis complet apparaît automatiquement en dessous de l'article.

Taille et épingle de matrice


// 8×8 RGB matrix configuration
const int MATRIX_PIN    = 14;   // fixed pin for this board
const int MATRIX_WIDTH  = 8;
const int MATRIX_HEIGHT = 8;

LaisserMATRIX_PINà14Il est câblé directement à la matrice intégrée.

Luminosité


// Overall brightness (0–255)
uint8_t matrixBrightness = 40;

Augmentez si nécessaire, mais évitez une luminosité extrême lors de la lecture de près.

Couleur du point


// Dot color (R, G, B)
uint8_t dotRed   = 0;
uint8_t dotGreen = 200;   // light green (default)
uint8_t dotBlue  = 0;

Changez ces valeurs pour créer n'importe quelle couleur. Exemples :

  • Rouge:(255, 0, 0)
  • Jaune:(255, 255, 0)
  • Blanc:(255, 255, 255)

Sensibilité au mouvement

Pour éviter des sauts extrêmes, les valeurs de l'accéléromètre sont généralement limitées ou mises à l'échelle. Un réglage typique ressemble à :


// How aggressively tilt affects movement
float sensitivity = 4.0f;   // larger = faster movement across screen

Si le point bouge trop lentement → augmentez la valeur. Si le point bouge trop brusquement → diminuisez-la.

Vitesse de mise à jour (Taux de rafraîchissement)

Vous pouvez ajouter un petit délai entre les mises à jour pour lisser le mouvement :


// Delay between position updates (ms)
int refreshDelayMs = 20;   // lower = smoother and faster response

Des valeurs entre 10 et 30 ms se sentent très réactives.

Résumé

Le projet 4 donne vie à l'accéléromètre QMI8658C intégré de l'ESP32-S3 en vous permettant de contrôler la matrice LED par le mouvement physique. Une légère inclinaison de la carte déplace le point dans la même direction, faisant de ce projet une excellente étape vers les projets plus avancés "Flèche vers le haut" et "Jeu de cible".

Le croquis complet de Tilt Dot est chargé en dessous de cet article (automatiquement). Pour mieux comprendre, regardez la démonstration de tilt dans la vidéo, où vous pouvez voir à quel point le point se déplace en douceur lorsque la planche est tournée. Des liens pour acheter le module matrice LED RGB ESP32-S3 sont inclus sous la section du 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 displaying rainbow heart
ESP32 S3 Matrix displaying rainbow heart
ESP32-S3_RGB_8x8_matrix1
ESP32-S3_RGB_8x8_matrix1
ESP32-S3_RGB_8x8_matrix-2
ESP32-S3_RGB_8x8_matrix-2
802-ESP32-S3 RGB LED Matrix Project 4 - Tilt dot
Langue: C++
/*
 * Projet 4 : Tilt Dot - Matrice LED RVB ESP32-S3 (Waveshare)
 * 
 * Ce sketch lit l'inclinaison du QMI8658C IMU et déplace en douceur un point sur la matrice LED RVB 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 D'UTILISATEUR --------

 // vrai -> point de l'autre côté : USB↔OUSB, 34↔15
 // faux -> point du même côté que HAUT
bool useOppositeMapping = false;

 // Couleur des points (0-255 chacun)
uint8_t dotRed   = 0;
uint8_t dotGreen = 100;
uint8_t dotBlue  = 0;

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

 // Position du point lisse (en coordonnées pixels, mais conservée en tant que flottant pour l'adoucissement)
float dotPosX = 3.0f; // commencer au centre
float dotPosY = 3.0f;

 // Facteur de lissage : plus petit = mouvement plus lent (0,1 très lent, 0,5 plus rapide)
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 "?";
  }
}

 // Détecter quel côté est vers le HAUT en utilisant des axes calibrés :
 // +X = USB, -X = OUSB, +Y = 34, -Y = 15
Side detectSideUp(float ax_g, float ay_g, float az_g) {
 // Détection de surface
  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;

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

 // 2) Sinon, vérifiez 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
    }
  }

 // 3) Si rien n'est fortement incliné, appelez-le simplement CENTRE.
  return SIDE_CENTER;
}

 // Carte de la partie supérieure vers l'endroit où le point doit aller.
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;
  }
}

 // Convertir les coordonnées du point en coordonnées de matrice
void getDotPixel(Side dotSide, int &px, int &py) {
 // Matrice (0,0) = coin supérieur gauche
 // centre supérieur : (3,0) → USB
 // bas centre : (3,7) → OUSB
 // centre gauche : (0,3) → 15
 // centre droit : (7,3) → 34
 // centre : (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 pour 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);

 // --- Mouvement fluide vers la cible ---
  dotPosX += (targetX - dotPosX) * dotSmooth;
  dotPosY += (targetY - dotPosY) * dotSmooth;

 // Convertir en coordonnées de pixels entiers
  int px = (int)round(dotPosX);
  int py = (int)round(dotPosY);

 // Pince juste au cas où
  if (px < 0) px = 0;
  if (px > 7) px = 7;
  if (py < 0) py = 0;
  if (py > 7) py = 7;

 // --- Dessiner un point ---
  matrix.fillScreen(0);
  uint16_t color = matrix.Color(dotRed, dotGreen, dotBlue);
  matrix.drawPixel(px, py, color);
  matrix.show();

 // 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(" | DOT="); Serial.print(sideName(dotSide));
  Serial.print(" | px=");  Serial.print(px);
  Serial.print(" py=");    Serial.println(py);

  delay(80);
}




Ce dont vous pourriez avoir besoin

Ressources et références

Fichiers📁

Fichier Fritzing