Suchcode

ESP32-S3 RGB-LED-Matrix-Projekt 5 - Pfeil immer nach oben

ESP32-S3 RGB-LED-Matrix-Projekt 5 - Pfeil immer nach oben

Projekt 5 - Pfeil Immer Nach Oben (Orientierungsanzeige mit QMI8658C)

Projekt 5 verwendet den Bewegungssensor QMI8658C, um die Ausrichtung der ESP32-S3 RGB-LED-Matrix zu erkennen und immer einen Pfeil anzuzeigen, der relativ zur Schwerkraft nach OBEN zeigt. Egal, wie Sie die Platine drehen – USB-Seite nach oben, OUSB-Seite nach oben, Seite "15" oder Seite "34" – der Pfeil dreht sich automatisch und zeigt in die physikalisch nach oben gerichtete Richtung.

Dies ist eine leistungsstarke Demonstration der Echtzeit-Orientierungserfassung mit dem integrierten Beschleunigungssensor. Alle sechs Projekte für dieses Modul werden in einem YouTube-Video vorgestellt, das ebenfalls auf dieser Seite eingebettet ist. Der vollständige Code für Projekt 5 wird automatisch unter dem Artikel geladen, und Affiliate-Links erscheinen im Abschnitt unter dem Code.

ESP32-S3 RGB-LED-Matrixmodul Übersicht

Das ESP32-S3 RGB-LED-Matrixmodul umfasst mehrere Komponenten, die dieses Projekt ermöglichen:

  • ESP32-S3-Mikrocontroller- bietet Wi-Fi, BLE und steuert die LED/IMU-Logik.
  • 8×8 RGB-LED-Matrix- zeigt den Pfeil in einer der vier Ausrichtungen an.
  • QMI8658C Beschleunigungssensor- erkennt Neigung, Bewegung und Orientierung.:contentReference[oaicite:0]{index=0}
  • USB-C-Anschlussfür Energie und Programmierung in der Arduino IDE.
  • Reset- und Boottastenzum Hochladen von Skizzen.
  • GPIO-Pinsverfügbar im gesamten Bereich für zusätzliche Projekte.

Die Richtung des Pfeils wird vollständig durch die Beschleunigungsmesserwerte bestimmt. Wenn das Board gedreht wird, erkennt der QMI8658C die neuen X/Y/Z-Werte, und die Skizze wählt aus, welches Pfeilmuster (↑, ↓, ←, →) gezeichnet werden soll.

Im Video behandelte Projekte (Zeitstempel)

  • 00:00- Einführung
  • 02:01- ESP32-Boards installieren
  • 03:32- Bibliotheken installieren
  • 05:32- Projekt 1: Bewegender Punkt
  • 11:11- Projekt 2: Textlauf
  • 12:59- Projekt 3: HTTP-Text
  • 16:41- Projekt 4: Tilt Dot
  • 18:55-Projekt 5: Pfeil Immer Nach Oben (dieses Projekt)
  • 20:02- Projekt 6: Zielspiel

Das Video zeigt klar, wie der Pfeil sich sofort in die andere Richtung ändert, je nachdem, wie das Modul gedreht wird. Es wird dringend empfohlen, diesen Abschnitt anzusehen.:contentReference[oaicite:1]{index=1}

ESP32-Boards im Arduino IDE installieren

Wenn Sie ein früheres Projekt abgeschlossen haben, ist die Board-Konfiguration bereits erledigt. Andernfalls:

  1. File > Preferences→ Fügen Sie die ESP32-Board-URL hinzu
  2. Tools > Board > Boards Manager…→ Installiere "ESP32"
  3. Wählen Sie das ESP32-S3-Board aus unterTools > Board
  4. Wählen Sie den richtigen USB-COM-Port aus unterTools > Port

Installation der erforderlichen Bibliotheken

Projekt 5 verwendet:

  • Adafruit NeoMatrix
  • Adafruit NeoPixel
  • Adafruit GFX
  • QMI8658(Bewegungsmelder)
  1. Sketch > Include Library > Manage Libraries…
  2. Suche:NeoMatrix→ Installieren
  3. Installiere Abhängigkeiten:NeoPixel+GFX
  4. Suchen und installierenQMI8658vom Autor

Wie Projekt 5 funktioniert

Der QMI8658C misst die Schwerkraft auf den X-, Y- und Z-Achsen. Durch den Vergleich dieser Werte bestimmt die Skizze, welche physikalische Seite der Platine nach oben zeigt:

  • USB-Seite nach oben
  • OUSB-Seite nach oben(gegenüber USB)
  • Seite "15" nach oben
  • Seite "34" oben

Jede Orientierung entspricht einem anderen Pfeilmuster auf der 8×8-Matrix. Die Zuordnung folgt deiner bestätigten Orientierungslogik aus früheren Debugging-Sitzungen. Die Drehung der Platine wird kontinuierlich gelesen, und der Pfeil wird aktualisiert, sobald sich die obere Seite ändert.

Projekt 5 - Code-Einstellungen (Pfeil Immer Nach Oben)

Unten sind die benutzeranpassbaren Werte aus dem Konfigurationsbereich. Der vollständige Projektcode erscheint automatisch unter dem Artikel.

Matrix-Konfiguration


// 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)

Dieses Projekt nutztNEO_MATRIX_FORTSCHRITTLayout, um sicherzustellen, dass der Pfeil entsprechend der tatsächlichen Bewegung korrekt zeigt.

Helligkeit


uint8_t matrixBrightness = 40;   // 0–255

Sie können diesen Wert für hellere Umgebungen erhöhen. Für den Innenbereich sind 30-60 angenehm.

Pfeilfarbe


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

Ändern Sie diese Werte, um die Farbe des Pfeils zu ändern. Zum Beispiel:

  • Grüner Pfeil:(0, 255, 0)
  • Blauer Pfeil:(0, 0, 255)
  • Weißer Pfeil:(255, 255, 255)

Empfindlichkeit und Glättung

Um Jitter zu vermeiden, enthält der Code Glättungs- und Schwellenwertlogik. In den Einstellungen finden Sie möglicherweise etwas wie:


// Sensitivity / smoothing adjustment
float tiltThreshold = 0.30f;   // adjust if arrow changes too easily
  • Wenn dein Pfeil zu leicht umschlägt →erhöhenSchwelle.
  • Wenn der Pfeil zu langsam ist, um sich zu ändern →VerringerungSchwelle.

Pfeilmuster

Die Skizze enthält Pfeil-Bitmuster für:

  • ↑ hoch
  • ↓ unten
  • ← links
  • → rechts

Sie müssen diese nicht ändern, aber Sie können die Formen im Code ändern, wenn Sie einen anderen Stil wünschen.

Zusammenfassung

Projekt 5 zeigt, wie die ESP32-S3 RGB-LED-Matrix und der QMI8658C-Beschleunigungssensor zusammenarbeiten, um die Ausrichtung zu erkennen und einen Pfeil anzuzeigen, der immer nach oben zeigt. Dieses Projekt baut auf dem Tilt Dot (Projekt 4) auf und bereitet dich auf das finale interaktive Spiel in Projekt 6 vor.

Der vollständige "Arrow Always Up"-Sketch ist unter diesem Artikel (automatisch geladen) verfügbar. Es wird dringend empfohlen, den entsprechenden Teil des Videos anzusehen, um zu sehen, wie sofort der Pfeil auf die Drehung des Boards reagiert. Wenn Sie dieses Projekt zu Hause nachbauen möchten, finden Sie Affiliate-Links für das ESP32-S3 RGB LED-Matrixmodul im Abschnitt mit dem Code.

Bilder

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
Sprache: C++
/*
 * Projekt 5: Pfeil Immer Nach Oben - ESP32-S3 RGB LED Matrix (Waveshare)  
 * Dieser Sketch liest die Neigung vom QMI8658C IMU und bewegt einen Punkt sanft auf der 8×8 RGB LED Matrix basierend auf der Ausrichtung des Boards.  
 * 
 * ▶️ Video Tutorial:  
 * https://youtu.be/JKLuYrRcLMI  
 * 
 * 📚⬇️ Ressourcen & Code-Seite:  
 * 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> // von Lahav Gahali

 // -------- LED MATRIZENINSTALLATION --------
#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 EINRICHTUNG --------
QMI8658 imu;
QMI8658_Data imuData;

 // -------- BENUTZEREINSTELLUNGEN --------

 // wahr -> Pfeil zeigt zur gegenüberliegenden Seite
 // USB↔OUSB, 34↔15
 // falsch -> der Pfeil zeigt auf die gleiche Seite, die OBEN ist
bool useOppositeMapping = false;

 // Pfeilfarbe (0-255 jeweils)
uint8_t dotRed   = 0;
uint8_t dotGreen = 150;
uint8_t dotBlue  = 0;

 // Bretterseiten
enum Side {
  SIDE_CENTER = 0,
  SIDE_USB,
  SIDE_OUSB,
  SIDE_15,
  SIDE_34
};

 // Richtung für das Zeichnen von Pfeilen
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 "?";
  }
}

 // -------- PFEILZEICHNUNG (IHER CODE, UNVERÄNDERT) --------

 // Zeichne einen einfachen Pfeil auf einer 8x8-Matrix, der in die angegebene Richtung zeigt.
void drawArrow(ArrowDir dir, uint16_t color) {
  matrix.fillScreen(0);

  switch (dir) {
    case ARROW_UP:
 // Hinweis
      matrix.drawPixel(3, 0, color);
      matrix.drawPixel(4, 0, color);
 // Zweite Reihe
      matrix.drawPixel(2, 1, color);
      matrix.drawPixel(3, 1, color);
      matrix.drawPixel(4, 1, color);
      matrix.drawPixel(5, 1, color);
 // Schaft
      matrix.drawLine(3, 2, 3, 6, color);
      matrix.drawLine(4, 2, 4, 6, color);
      break;

    case ARROW_DOWN:
 // Hinweis
      matrix.drawPixel(3, 7, color);
      matrix.drawPixel(4, 7, color);
 // Reihe über Tipp
      matrix.drawPixel(2, 6, color);
      matrix.drawPixel(3, 6, color);
      matrix.drawPixel(4, 6, color);
      matrix.drawPixel(5, 6, color);
 // Schaft
      matrix.drawLine(3, 1, 3, 5, color);
      matrix.drawLine(4, 1, 4, 5, color);
      break;

    case ARROW_LEFT:
 // Hinweis
      matrix.drawPixel(0, 3, color);
      matrix.drawPixel(0, 4, color);
 // Spalte nach Trinkgeld
      matrix.drawPixel(1, 2, color);
      matrix.drawPixel(1, 3, color);
      matrix.drawPixel(1, 4, color);
      matrix.drawPixel(1, 5, color);
 // Schaft
      matrix.drawLine(2, 3, 6, 3, color);
      matrix.drawLine(2, 4, 6, 4, color);
      break;

    case ARROW_RIGHT:
 // Hinweis
      matrix.drawPixel(7, 3, color);
      matrix.drawPixel(7, 4, color);
 // Spalte vor dem Trinkgeld
      matrix.drawPixel(6, 2, color);
      matrix.drawPixel(6, 3, color);
      matrix.drawPixel(6, 4, color);
      matrix.drawPixel(6, 5, color);
 // Schaft
      matrix.drawLine(1, 3, 5, 3, color);
      matrix.drawLine(1, 4, 5, 4, color);
      break;

    case ARROW_CENTER:
    default:
 // EinfachPlus im Zentrum
      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 → SEITENDETEKTION --------
 // Wir haben früher kalibriert:
 // +X = USB, -X = OUSB
 // +Y = 15, -Y = 34 (nach Ihrer Korrektur)

Side detectSideUp(float ax_g, float ay_g, float az_g) {
 // Objekterkennung
  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;

 // Schwellenwerte, um zu sagen "Diese Achse ist wirklich geneigt"
  const float tiltThreshY = 0.5f;
  const float tiltThreshX = 0.5f;

 // Bevorzugen Sie die Y-Achse für 15 / 34
  if (fabs(ay_g) >= tiltThreshY) {
    if (ay_g > 0) {
      return SIDE_34; // +Y = 34 nach oben
    } else {
      return SIDE_15; // -Y = 15 nach oben
    }
  }

 // Andernfalls verwenden Sie die X-Achse für USB / OUSB.
  if (fabs(ax_g) >= tiltThreshX) {
    if (ax_g > 0) {
      return SIDE_USB; // +X = USB hoch
    } else {
      return SIDE_OUSB; // -X = OUSB hoch
    }
  }

 // Nicht deutlich geneigt → als Mitte behandeln
  return SIDE_CENTER;
}

 // Karte von der oberen Seite zu dem Punkt, auf den der Pfeil zeigen sollte
Side arrowSideFromUpSide(Side upSide) {
  if (!useOppositeMapping) {
 // Der Pfeil zeigt die Seite, die OBEN ist.
    return upSide;
  }

 // Der Pfeil zeigt die gegenüberliegende Seite.
  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;
  }
}

 // Konvertiere SIDE in 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;
  }
}

 // ---------------- EINRICHTUNG & SCHLEIFE ----------------

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

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

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

 // Fehlerbehebung
  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);
}

Dinge, die Sie vielleicht brauchen

Ressourcen & Referenzen

Dateien📁

Fritzing-Datei