/*
* ====================================================================
* LETRERO LED DINÁMICO CON MENSAJES Y EFECTOS ALEATORIOS
* ====================================================================
*
* Este código controla una matriz de LEDs de 48x16 píxeles.
*
* Funcionalidades:
* 1. Muestra una lista predefinida de mensajes.
* 2. Selecciona un mensaje al azar cada vez que el anterior termina.
* 3. Aplica un efecto de entrada, un efecto de salida y una alineación
* de forma aleatoria para cada mensaje que se muestra.
* 4. El código es fácilmente expandible para añadir más mensajes y efectos.
*/
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
// ---------- CONFIGURACIÓN DEL HARDWARE ----------
// Tipo de hardware. FC16_HW es el más común. Si el texto se ve raro, prueba con PAROLA_HW.
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
// Número TOTAL de módulos 8x8 en el letrero (para wokwi: 32x8 = 4 modulos)
// Para 32x8: 4 módulos de ancho (1) x 1 modulos de alto = 4
// Para 32x16: 4 módulos de ancho (1) x 2 modulos de alto = 8
// Para 64x16: 8 módulos de ancho (2) x 2 modulos de alto = 16
#define MAX_DEVICES 4 //poner la cantidad de modulos como si fueran de 8x8
// Pines de conexión del Arduino a la matriz.
#define CLK_PIN 4
#define DATA_PIN 2
#define CS_PIN 3
// Crear el objeto principal de Parola que controlará el letrero.
MD_Parola letrero = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// ---------- LISTA DE MENSAJES (¡AQUÍ PUEDES AÑADIR LOS TUYOS!) ----------
// Para añadir un nuevo mensaje, solo agrégalo a la lista entre comillas y separado por una coma.
const char *mensajes[] = {
"Hola, bienvenido a mi proyecto!",
"Siguenos, dale like y comparte",
"Arduino y MD_Parola son geniales"
};
// El programa calcula automáticamente cuántos mensajes hay.
const int NUM_MENSAJES = sizeof(mensajes) / sizeof(mensajes[0]);
// ---------- LISTA DE EFECTOS DE ANIMACIÓN ----------
// Hemos creado una lista con todas las animaciones disponibles para elegirlas al azar.
textEffect_t efectos[] = {
PA_PRINT, // Aparece letra por letra
PA_SCROLL_LEFT, // Desplazamiento clásico a la izquierda
PA_SCROLL_RIGHT, // Desplazamiento a la derecha
PA_SCROLL_UP, // Desplazamiento hacia arriba
PA_SCROLL_DOWN, // Desplazamiento hacia abajo
PA_SPRITE, // Aparece como un "fantasma" de videojuego
PA_FADE, // Aparece y desaparece suavemente (fade in/out)
PA_OPENING, // El texto se abre desde el centro
PA_CLOSING, // El texto se cierra hacia el centro
PA_WIPE, // El texto se "limpia" para aparecer
PA_MESH, // Aparece como una malla
PA_DISSOLVE, // Se disuelve para aparecer
PA_BLINDS, // Aparece como si se abrieran persianas
PA_RANDOM, // Aparece con píxeles aleatorios
PA_SLICE // El texto se corta y cae en su lugar
};
// El programa calcula cuántos efectos hay.
const int NUM_EFECTOS = sizeof(efectos) / sizeof(efectos[0]);
// ---------- LISTA DE ALINEACIONES DE TEXTO ----------
textPosition_t alineaciones[] = {PA_LEFT, PA_CENTER, PA_RIGHT};
const int NUM_ALINEACIONES = sizeof(alineaciones) / sizeof(alineaciones[0]);
// ---------- CONFIGURACIÓN DE VELOCIDAD Y PAUSA ----------
// Puedes experimentar con estos valores.
int velocidadScroll = 75; // Velocidad del texto. Menor número = más rápido.
int pausaEntreMensajes = 1000; // Pausa en milisegundos ANTES de que el texto desaparezca.
void setup() {
// Inicializa el objeto Parola.
letrero.begin();
// Establece el brillo de los LEDs (0=mínimo, 15=máximo).
letrero.setIntensity(4);
// Limpia la pantalla al iniciar.
letrero.displayClear();
// ¡MUY IMPORTANTE! Inicia el generador de números aleatorios.
// Se usa un pin analógico no conectado para obtener una "semilla" realmente aleatoria.
randomSeed(analogRead(A0));
}
void loop() {
// La magia principal de Parola sucede aquí.
// letrero.displayAnimate() se encarga de dibujar cada fotograma de la animación.
// Devuelve 'true' SOLAMENTE cuando una animación ha terminado por completo.
if (letrero.displayAnimate()) {
// --- Una vez que la animación termina, preparamos la siguiente ---
// 1. Elegimos un índice de mensaje al azar.
int indiceMensaje = random(0, NUM_MENSAJES);
// 2. Elegimos una alineación al azar.
int indiceAlineacion = random(0, NUM_ALINEACIONES);
// 3. Elegimos un efecto de ENTRADA y uno de SALIDA al azar.
int indiceEfectoEntrada = random(0, NUM_EFECTOS);
int indiceEfectoSalida = random(0, NUM_EFECTOS);
// 4. Configuramos el letrero con los nuevos parámetros aleatorios.
letrero.displayText(
mensajes[indiceMensaje], // El texto del mensaje elegido
alineaciones[indiceAlineacion], // La alineación elegida
velocidadScroll, // La velocidad que definimos arriba
pausaEntreMensajes, // La pausa que definimos arriba
efectos[indiceEfectoEntrada], // El efecto de entrada elegido
efectos[indiceEfectoSalida] // El efecto de salida elegido
);
// Esta línea no es estrictamente necesaria con la lógica anterior,
// pero es una buena práctica para reiniciar el estado de la animación.
// letrero.displayReset();
}
}