Código de búsqueda

Proyecto de matriz de LED RGB ESP32-S3 4 - Punto inclinado

Proyecto de matriz de LED RGB ESP32-S3 4 - Punto inclinado

Proyecto 4 - Punto Inclinado (Mueve el Punto inclinando la Matriz LED RGB ESP32-S3)

El Proyecto 4 introduce el sensor de movimiento integrado en el módulo de matriz LED RGB ESP32-S3. En lugar de mover automáticamente el punto (como en el Proyecto 1) o desplazar texto (Proyectos 2 y 3), este proyecto te permite controlar la posición del punto simplemente inclinando la placa. El punto se mueve suavemente a través de la pantalla RGB de 8×8 basado en lecturas en tiempo real del acelerómetro QMI8658C en la parte posterior del módulo.

Los seis proyectos de esta serie se demuestran en un video de YouTube. El mismo video está incrustado en esta página, por lo que puedes ver exactamente cómo se mueve el punto en tiempo real a medida que la tabla se inclina. El código completo para este proyecto se carga automáticamente debajo del artículo, y los enlaces de compra afiliados para el módulo aparecen bajo la sección del código.

Resumen del módulo de matriz de LED RGB ESP32-S3

Este proyecto utiliza el módulo de matriz de LED RGB ESP32-S3, que incluye:

  • microcontrolador ESP32-S3con Wi-Fi y Bluetooth
  • matriz LED RGB de 8×8(64 LED individuales direccionables)
  • Acelerómetro QMI8658Cen la parte posterior para la detección de inclinación y movimiento
  • puerto USBpara programación y potencia
  • Botón de arranque / reinicio
  • Pines GPIO utilizablespara futuras expansiones

El sensor QMI8658C leeX,Y, andZvalores de aceleración y orientación, permitiendo que el punto se mueva hacia arriba/abajo/izquierda/derecha según cómo esté inclinado el tablero.:contentReference[oaicite:0]{index=0}

Proyectos Cubiertos en el Video (Marcas de Tiempo)

  • 00:00- Introducción
  • 02:01- Instalando placas ESP32
  • 03:32- Instalando bibliotecas
  • 05:32- Proyecto 1: Punto en Movimiento
  • 11:11- Proyecto 2: Desplazamiento de texto
  • 12:59- Proyecto 3: Texto HTTP
  • 16:41-Proyecto 4: Tilt Dot (este proyecto)
  • 18:55- Proyecto 5: Flecha Arriba
  • 20:02- Proyecto 6: Juego de Objetivos

Se recomienda encarecidamente ver la demostración de inclinación en el video, ya que puedes ver cómo el punto reacciona suavemente a la orientación de la tabla.:contentReference[oaicite:1]{index=1}

Instalando las placas ESP32 en Arduino IDE

Si has completado algún proyecto anterior, el soporte de la placa ya está instalado. De lo contrario, sigue estos pasos:

  1. AbiertoFile > Preferences→ Añadir URL de placas ESP32.
  2. Ir aTools > Board > Boards Manager…y instalarESP32.
  3. Seleccione su placa ESP32-S3 bajoTools > Board.
  4. Seleccione el puerto COM correcto bajoTools > Port.

Instalando bibliotecas necesarias

Este proyecto requiere las siguientes bibliotecas:

  • Adafruit NeoMatrix
  • Adafruit NeoPixel
  • Adafruit GFX Library
  • QMI8658(sensor de movimiento)

Instálalos en el Administrador de Bibliotecas:

  1. AbrirSketch > Include Library > Manage Libraries….
  2. Buscar porAdafruit NeoMatrix→ Instalar.
  3. Permitir la instalación automática deAdafruit GFXyAdafruit NeoPixel.
  4. Buscar porQMI8658por su autor listado → Instalar.:contentReference[oaicite:2]{index=2}

Cómo Funciona el Proyecto 4

El sensor QMI8658C proporciona continuamente datos de aceleración a lo largo de los ejes X, Y y Z. Para este proyecto, solo utilizamos los ejes X e Y para decidir:

  • Qué tan lejos mover el punto a la izquierda o a la derecha (eje X)
  • Qué tan lejos mover el punto hacia arriba o hacia abajo (eje Y)

Los valores del sensor se mapean en un rango de coordenadas de 0 a 7 (para la matriz de LED de 8×8). La posición del punto se actualiza muchas veces por segundo, dando el efecto de deslizamiento suave a medida que inclinas el módulo.:contentReference[oaicite:3]{index=3}

Proyecto 4 - Configuraciones de Código (Punto Inclinable)

A continuación se encuentran los ajustes editables por el usuario que se encuentran cerca de la parte superior del código del proyecto. El boceto completo aparece automáticamente debajo del artículo.

Punto y tamaño de matriz


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

DejarMATRIX_PINen14Está conectado de forma fija a la matriz a bordo.

Brillo


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

Aumenta si es necesario, pero evita el brillo extremo al observar de cerca.

Color del punto


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

Cambia estos valores para crear cualquier color. Ejemplos:

  • Rojo:(255, 0, 0)
  • Amarillo:(255, 255, 0)
  • Blanco:(255, 255, 255)

Sensibilidad al movimiento

Para prevenir saltos extremos, los valores del acelerómetro suelen ser limitados o escalados. Una configuración típica se ve así:


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

Si el punto se mueve demasiado lento → aumenta el valor. Si el punto se mueve demasiado bruscamente → disminúyelo.

Velocidad de actualización (Tasa de refresco)

Puedes añadir un pequeño retraso entre actualizaciones para suavizar el movimiento:


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

Valores entre 10-30 ms se sienten muy responsivos.

Resumen

El Proyecto 4 da vida al acelerómetro QMI8658C integrado del ESP32-S3 al permitirte controlar la matriz de LED con movimiento físico. Una pequeña inclinación de la placa mueve el punto en la misma dirección, lo que convierte este proyecto en un escalón perfecto para los proyectos más avanzados "Flecha Arriba" y "Juego de Objetivos".

El boceto completo de Tilt Dot está cargado debajo de este artículo (automáticamente). Para una mejor comprensión, mira la demostración de tilt en el video, donde puedes ver lo suavemente que se mueve el punto mientras se rota la placa. Los enlaces para comprar el módulo de matriz de LED RGB ESP32-S3 están incluidos en la sección de código.

Imágenes

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
Idioma: C++
/*
 * Proyecto 4: Tilt Dot - Matriz LED RGB ESP32-S3 (Waveshare)
 * 
 * Este boceto lee la inclinación del IMU QMI8658C y mueve suavemente un punto en la matriz LED RGB de 8×8 según la orientación de la placa.
 * 
 * ▶️ Tutorial en Video:
 * https://youtu.be/JKLuYrRcLMI
 * 
 * 📚⬇️ Recursos y Página de Código:
 * 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> // por Lahav Gahali

 // -------- CONFIGURACIÓN DE MATRIZ 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
);

 // -------- CONFIGURACIÓN DE IMU QMI8658 --------
QMI8658 imu;
QMI8658_Data imuData;

 // -------- AJUSTES DEL USUARIO --------

 // verdadero -> punto en el lado opuesto: USB↔OUSB, 34↔15
 // falso -> punto en el mismo lado que ARRIBA
bool useOppositeMapping = false;

 // Color del punto (0-255 cada uno)
uint8_t dotRed   = 0;
uint8_t dotGreen = 100;
uint8_t dotBlue  = 0;

 // Lados de la tabla
enum Side {
  SIDE_CENTER = 0,
  SIDE_USB,
  SIDE_OUSB,
  SIDE_15,
  SIDE_34
};

 // Posición del punto suave (en coordenadas de píxeles, pero mantenido como flotante para suavizar)
float dotPosX = 3.0f; // comenzar en el centro
float dotPosY = 3.0f;

 // Factor de suavizado: menor = movimiento más lento (0.1 muy lento, 0.5 más rápido)
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 "?";
  }
}

 // Detecta qué lado está ARRIBA utilizando ejes calibrados:
 // +X = USB, -X = OUSB, +Y = 34, -Y = 15
Side detectSideUp(float ax_g, float ay_g, float az_g) {
 // Detección de pisos
  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;

 // Umbrales para decir "este eje está realmente inclinado"
  const float tiltThreshY = 0.5f;
  const float tiltThreshX = 0.5f;

 // 1) Prefiera el eje Y para 15 / 34 si está claramente inclinado
  if (fabs(ay_g) >= tiltThreshY) {
    if (ay_g > 0) {
      return SIDE_15; // +Y = 34 arriba
    } else {
      return SIDE_34; // -Y = 15 arriba
    }
  }

 // 2) De lo contrario, verifica el eje X para USB / OUSB
  if (fabs(ax_g) >= tiltThreshX) {
    if (ax_g > 0) {
      return SIDE_USB; // +X = USB arriba
    } else {
      return SIDE_OUSB; // -X = OUSB arriba
    }
  }

 // 3) Si nada está fuertemente inclinado, simplemente llámalo CENTRO.
  return SIDE_CENTER;
}

 // Mapa desde el lado de UP hasta donde debería ir el 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;
  }
}

 // Convertir el lado del punto a coordenadas de la matriz
void getDotPixel(Side dotSide, int &px, int &py) {
 // Matriz (0,0) = esquina superior izquierda
 // centro superior: (3,0) → USB
 // centro inferior: (3,7) → OUSB
 // centro izquierdo: (0,3) → 15
 // centro derecho: (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 para 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);

 // --- Movimiento suave hacia el objetivo ---
  dotPosX += (targetX - dotPosX) * dotSmooth;
  dotPosY += (targetY - dotPosY) * dotSmooth;

 // Convertir a coordenadas de píxeles enteras
  int px = (int)round(dotPosX);
  int py = (int)round(dotPosY);

 // Abrazadera por si acaso
  if (px < 0) px = 0;
  if (px > 7) px = 7;
  if (py < 0) py = 0;
  if (py > 7) py = 7;

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

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




Cosas que podrías necesitar

Recursos y referencias

Archivos📁

Archivo de Fritzing