Cerca codice

Progetto Matrice LED RGB ESP32-S3 4 - Punta inclinata

Progetto Matrice LED RGB ESP32-S3 4 - Punta inclinata

Progetto 4 - Tilt Dot (Sposta il punto inclinando la matrice LED RGB ESP32-S3)

Il Progetto 4 introduce il sensore di movimento integrato nel modulo ESP32-S3 RGB LED Matrix. Invece di spostare automaticamente il punto (come nel Progetto 1) o far scorrere il testo (Progetti 2 e 3), questo progetto ti consente di controllare la posizione del punto semplicemente inclinando la scheda. Il punto si muove fluidamente attraverso il display RGB 8×8 basandosi su letture in tempo reale dall'accelerometro QMI8658C sul retro del modulo.

Tutti e sei i progetti di questa serie vengono dimostrati in un video di YouTube. Lo stesso video è incorporato in questa pagina, così puoi vedere esattamente come si muove il punto in tempo reale mentre la tavola si inclina. Il codice completo per questo progetto viene caricato automaticamente sotto l'articolo e i link per l'acquisto in affiliazione del modulo appaiono sotto la sezione del codice.

Panoramica del modulo matrice LED RGB ESP32-S3

Questo progetto utilizza il modulo matrice LED RGB ESP32-S3, che include:

  • microcontrollore ESP32-S3con Wi-Fi e Bluetooth
  • Matrice LED RGB 8×8(64 LED individui indirizzabili)
  • QMI8658C accelerometrosul retro per rilevamento dell'inclinazione e del movimento
  • porta USBper programmazione e potenza
  • Pulsanti di avvio / ripristino
  • Pin GPIO utilizzabiliper future espansioni

Il sensore QMI8658C leggeX,Y, eZvalori di accelerazione e orientamento, che consentono al punto di muoversi su/giù/sinistra/destra in base a come è inclinata la tavola.:contentReference[oaicite:0]{index=0}

Progetti trattati nel video (Timestamp)

  • 00:00- Introduzione
  • 02:01- Installazione delle schede ESP32
  • 03:32- Installazione delle librerie
  • 05:32- Progetto 1: Punto in Movimento
  • 11:11- Progetto 2: Scorrimento Testo
  • 12:59- Progetto 3: Testo HTTP
  • 16:41-Progetto 4: Tilt Dot (questo progetto)
  • 18:55- Progetto 5: Freccia Su
  • 20:02- Progetto 6: Gioco del Target

È fortemente consigliato guardare la dimostrazione dell'inclinazione nel video, poiché puoi vedere come il punto reagisce in modo fluido all'orientamento della tavola.:contentReference[oaicite:1]{index=1}

Installazione delle schede ESP32 in Arduino IDE

Se hai completato un progetto precedente, il supporto per la scheda è già installato. In caso contrario, segui questi passaggi:

  1. ApriFile > Preferences→ Aggiungi URL delle schede ESP32.
  2. Vai aTools > Board > Boards Manager…e installaESP32.
  3. Seleziona la tua scheda ESP32-S3 sottoTools > Board.
  4. Seleziona la corretta porta COM sottoTools > Port.

Installazione delle librerie necessarie

Questo progetto richiede le seguenti librerie:

  • Adafruit NeoMatrix
  • Adafruit NeoPixel
  • Adafruit GFX Library
  • QMI8658(sensore di movimento)

Installa nel Gestore delle librerie:

  1. ApertoSketch > Include Library > Manage Libraries….
  2. Cerca perAdafruit NeoMatrix→ Installa.
  3. Consentire l'installazione automatica diAdafruit GFXeAdafruit NeoPixel.
  4. Cerca perQMI8658da il suo autore elencato → Installa.:contentReference[oaicite:2]{index=2}

Come funziona il Progetto 4

Il sensore QMI8658C fornisce continuamente dati di accelerazione lungo gli assi X, Y e Z. Per questo progetto, utilizziamo solo gli assi X e Y per decidere:

  • Quanto lontano spostare il punto a sinistra o a destra (asse X)
  • Quanto lontano spostare il punto in alto o in basso (asse Y)

I valori del sensore sono mappati in un intervallo di coordinate da 0 a 7 (per la matrice LED 8×8). La posizione del punto si aggiorna molte volte al secondo, dando un effetto di scorrimento fluido mentre inclini il modulo.:contentReference[oaicite:3]{index=3}

Progetto 4 - Impostazioni del Codice (Punto inclinato)

Di seguito sono le impostazioni modificabili dagli utenti trovate vicino alla parte superiore del codice del progetto. Lo sketch completo appare automaticamente sotto l'articolo.

Matrice Pin e Dimensione


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

LasciaMATRIX_PINat14È collegato in modo fisso alla matrice a bordo.

Luminosità


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

Aumenta se necessario, ma evita la luminosità estrema quando si guarda da vicino.

Colore del punto


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

Cambia questi valori per creare qualsiasi colore. Esempi:

  • Rosso:(255, 0, 0)
  • Giallo:(255, 255, 0)
  • Bianco:(255, 255, 255)

Sensibilità al movimento

Per prevenire salti estremi, i valori dell'accelerometro vengono solitamente limitati o scalati. Una impostazione tipica è la seguente:


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

Se il punto si muove troppo lentamente → aumenta il valore. Se il punto si muove troppo bruscamente → diminuiscilo.

Velocità di aggiornamento (Frequenza di aggiornamento)

Puoi aggiungere un piccolo ritardo tra gli aggiornamenti per rendere il movimento più fluido:


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

Valori tra 10 e 30 ms si sentono molto reattivi.

Riassunto

Il Progetto 4 mette in funzione l'accelerometro QMI8658C integrato nell'ESP32-S3 permettendoti di controllare la matrice LED con il movimento fisico. Un leggero inclinamento della scheda sposta il punto nella stessa direzione, rendendo questo progetto un ottimo trampolino di lancio per i progetti più avanzati "Freccia Su" e "Gioco del Bersaglio".

Il disegno completo del Tilt Dot è caricato sotto questo articolo (automaticamente). Per una migliore comprensione, guarda la dimostrazione del tilt nel video, dove puoi vedere quanto gentilmente il punto si muove mentre la scheda viene ruotata. I collegamenti per acquistare il modulo matrice LED RGB ESP32-S3 sono inclusi nella sezione del codice.

Immagini

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
Lingua: C++
/*
 * Progetto 4: Tilt Dot - Matrice LED RGB ESP32-S3 (Waveshare)
 * 
 * Questo sketch legge il tilt dall'IMU QMI8658C e muove dolcemente un punto
 * sulla matrice LED RGB 8×8 in base all'orientamento della scheda.
 * 
 * ▶️ Video Tutorial:
 * https://youtu.be/JKLuYrRcLMI
 * 
 * 📚⬇️ Risorse e Pagina di Codice:
 * 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> // di Lahav Gahali

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

 // -------- IMU SETUP QMI8658 --------
QMI8658 imu;
QMI8658_Data imuData;

 // -------- IMPOSTAZIONI UTENTE --------

 // vero -> punto sul lato opposto: USB↔OUSB, 34↔15
 // falso -> punto sullo stesso lato di SU
bool useOppositeMapping = false;

 // Colore del punto (0-255 ciascuno)
uint8_t dotRed   = 0;
uint8_t dotGreen = 100;
uint8_t dotBlue  = 0;

 // Fianchi della tavola
enum Side {
  SIDE_CENTER = 0,
  SIDE_USB,
  SIDE_OUSB,
  SIDE_15,
  SIDE_34
};

 // Posizione del punto liscio (in coordinate pixel, ma mantenuta come float per il movimento morbido)
float dotPosX = 3.0f; // inizia dal centro
float dotPosY = 3.0f;

 // Fattore di lisciatura: più piccolo = movimento più lento (0,1 molto lento, 0,5 più veloce)
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 "?";
  }
}

 // Rileva quale lato è SU utilizzando assi calibrati:
 // +X = USB, -X = OUSB, +Y = 34, -Y = 15
Side detectSideUp(float ax_g, float ay_g, float az_g) {
 // Rilevamento di piani
  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;

 // Soglie per dire "questo asse è davvero inclinato"
  const float tiltThreshY = 0.5f;
  const float tiltThreshX = 0.5f;

 // 1) Preferire l'asse Y per 15 / 34 se è chiaramente inclinato
  if (fabs(ay_g) >= tiltThreshY) {
    if (ay_g > 0) {
      return SIDE_15; // +Y = 34 su
    } else {
      return SIDE_34; // -Y = 15 sopra
    }
  }

 // 2) Altrimenti, controlla l'asse X per USB / OUSB
  if (fabs(ax_g) >= tiltThreshX) {
    if (ax_g > 0) {
      return SIDE_USB; // +X = USB su
    } else {
      return SIDE_OUSB; // -X = OUSB su
    }
  }

 // Se nulla è fortemente inclinato, chiamalo semplicemente CENTRO.
  return SIDE_CENTER;
}

 // Mappa dal lato UP a dove dovrebbe andare il punto.
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;
  }
}

 // Converti la parte del punto in coordinate della matrice
void getDotPixel(Side dotSide, int &px, int &py) {
 // Matrice (0,0) = in alto a sinistra
 // centrato in alto: (3,0) → USB
 // centro in basso: (3,7) → OUSB
 // centro sinistro: (0,3) → 15
 // centro destra: (7,3) → 34
 // centro: (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 per 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);

 // --- Movimento fluido verso l'obiettivo ---
  dotPosX += (targetX - dotPosX) * dotSmooth;
  dotPosY += (targetY - dotPosY) * dotSmooth;

 // Converti in coordinate pixel intere
  int px = (int)round(dotPosX);
  int py = (int)round(dotPosY);

 // Morsetto giusto nel caso
  if (px < 0) px = 0;
  if (px > 7) px = 7;
  if (py < 0) py = 0;
  if (py > 7) py = 7;

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

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

  delay(80);
}




Cose di cui potresti avere bisogno

Risorse e riferimenti

File📁

File Fritzing