Este tutorial es parte de: Matriz de LED RGB ESP32-S3
Proyecto genial para crear aplicaciones prácticas y divertidas con el módulo de matriz RGB ESP32-S3. Encontrará enlaces a otros videos debajo de este artículo.
Proyecto de matriz LED RGB ESP32-S3 3 - Texto desde teléfono móvil
Proyecto 3 - Controlar la Matriz de Texto desde Tu Teléfono (Texto HTTP)
En este proyecto, la matriz de LED RGB ESP32-S3 aloja una pequeña página web para que puedas cambiar el texto en desplazamiento, el color, la dirección y la velocidad directamente desde tu teléfono o computadora. No necesitas una aplicación separada, solo un navegador web. Esto convierte al módulo en una pequeña pantalla de texto Wi-Fi que puedes actualizar en tiempo real.
Los seis proyectos de esta serie se explican y demuestran en un video de YouTube. El mismo video está incrustado en esta página, por lo que puedes ver exactamente cómo luce la interfaz web y cómo el texto se actualiza instantáneamente en la matriz. El código fuente completo para este proyecto se carga automáticamente debajo del artículo, y puedes comprar el módulo de matriz LED RGB ESP32-S3 en las tiendas afiliadas que se enumeran en la sección de código.
En este artículo nos centramos en cómo funciona la lógica de la red (Wi-Fi doméstico vs punto de acceso) y qué configuraciones puedes cambiar en el código para personalizar el comportamiento.



Resumen del módulo de matriz LED RGB ESP32-S3
El hardware es el mismo que para todos los otros proyectos de esta serie: una placa de microcontrolador ESP32-S3 con una matriz de LED RGB de 8×8 integrada y un sensor de movimiento QMI8658C en la parte posterior. El puerto USB-C se utiliza para alimentación y programación, y los pines alrededor de los bordes aún están disponibles para otras E/S.:contentReference[oaicite:0]{index=0}

- ESP32-S3- Microcontrolador con capacidad Wi-Fi y Bluetooth.
- matriz RGB de 8×8- 64 LEDs RGB direccionables para texto y gráficos.
- Acelerómetro QMI8658C- utilizado en los proyectos de tilt y juego.
- Puerto USB- alimenta la placa y carga bocetos desde el Arduino IDE.
- Pines expuestos- permitir sensores o actuadores adicionales si es necesario.
- Botones de inicio/reinicio- para la carga de firmware y reinicio.
Para el Proyecto 3, la característica más importante es el Wi-Fi del ESP32, que permite que la placa actúe como un pequeño servidor web para la página de control del texto.:contentReference[oaicite:1]{index=1}

Proyectos Cubiertos en el Video (Tiempos)
El primer video de esta serie cubre los seis proyectos. Para una referencia rápida:
- 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 (este proyecto)
- 16:41- Proyecto 4: Punto Inclinado
- 18:55- Proyecto 5: Flecha Arriba
- 20:02- Proyecto 6: Juego de Objetivos
Se le anima a ver la sección de Texto HTTP en el video mientras trabaja con este artículo. El video muestra cómo se genera la página web por el ESP32 y cómo el cambio de texto, color y velocidad se refleja instantáneamente en la matriz de LED.:contentReference[oaicite:2]{index=2}
Instalando placas ESP32 en el IDE de Arduino
Si ya has completado los Proyectos 1 o 2, la configuración de la placa está hecha y puedes saltarte esta sección. De lo contrario, sigue estos pasos en el IDE de Arduino:
- Abrir
File > Preferencesy añade la URL de las placas ESP32 a "URLs adicionales del Gestor de placas". - Ve a
Tools > Board > Boards Manager…, buscar paraESP32, e instala el paquete oficial de ESP32. - Seleccione la placa de matriz RGB ESP32-S3 correcta de
Tools > Board. - Conecte el módulo a través de USB y elija el puerto serie correcto en
Tools > Port.
Sin el soporte adecuado para la placa ESP32 y el puerto correcto, el sketch del servidor web no se cargará.
Instalando NeoMatrix y las bibliotecas requeridas
Este proyecto utiliza las mismas bibliotecas que el proyecto de desplazamiento de texto anterior:
Adafruit NeoMatrixAdafruit NeoPixelAdafruit GFX Library
Instalar a través del Gestor de Bibliotecas:
- Abrir
Sketch > Include Library > Manage Libraries…. - Buscar por
Adafruit NeoMatrixy haz clicInstalar. - Aceptar la instalación de dependencias
Adafruit GFXyAdafruit NeoPixel).
Una vez instalado, deberías ver los ejemplos de bocetos de NeoMatrix y NeoPixel bajoFile > Examples.
Dos modos Wi-Fi en el Proyecto 3
El concepto más importante en este proyecto es que el ESP32 puede trabajar endos modos diferentes:
- Modo estación (STA)- el ESP32 se conecta a tu red Wi-Fi doméstica existente.
- Modo de Punto de Acceso (AP)El ESP32 crea su propia red Wi-Fi si la Wi-Fi del hogar no está disponible.
Ambos modos utilizan la misma interfaz web: una página HTML servida desde el propio ESP32, donde puedes cambiar el texto, el color, la dirección del desplazamiento y la velocidad.:contentReference[oaicite:3]{index=3}
Modo 1 - Conectar a Wi-Fi doméstico (Modo Estación)
En el modo Estación, el ESP32 se une a la red Wi-Fi de su hogar u oficina. Este es el modo preferido siempre que su enrutador esté disponible porque:
- Tu teléfono y computadora ya están conectados a la misma red Wi-Fi.
- Puedes apuntar tu navegador a la dirección IP del ESP32 y controlar el texto desde cualquier dispositivo en esa red.
En la sección de configuración del boceto, proporcionas tu SSID de Wi-Fi y contraseña:
// Home Wi-Fi credentials (Station mode)
const char* WIFI_SSID = "YourHomeWiFi";
const char* WIFI_PASS = "YourHomePassword";
Después de que la placa se inicie, intenta conectarse aWIFI_SSIDSi tiene éxito, el código imprime la dirección IP asignada en el Monitor Serial, por ejemplo:
Connected to WiFi
IP address: 192.168.1.16
Para controlar el texto:
- Asegúrate de que tu teléfono o PC esté conectado a la misma red Wi-Fi (por ejemplo,
YourHomeWiFi). - Abre un navegador e ingresa la dirección IP impresa, como
http://192.168.1.16/. :contentReference[oaicite:4]{index=4} - La página de control aparecerá, permitiéndote escribir texto, elegir color, seleccionar dirección y ajustar la velocidad de desplazamiento.
Modo 2 - Punto de Acceso Autónomo (Modo AP)
Si el ESP32 no puede conectarse a tu Wi-Fi doméstico (contraseña incorrecta, red no disponible o estás usando el módulo fuera), el sketch vuelve automáticamente al modo punto de acceso. En el modo AP, el ESP32 se convierte en un hotspot Wi-Fi con su propio nombre de red y contraseña.
En este proyecto, la configuración del AP está fija en:
// Access Point (AP) credentials (fallback mode)
const char* AP_SSID = "ESP32";
const char* AP_PASS = "password";
Cuando el modo Estación falla, el módulo cambia al modo AP y comienza a transmitir una red Wi-Fi llamadaESP32. Para controlar la matriz:
- En tu teléfono o computadora, abre la configuración de Wi-Fi y conéctate a la red.ESP32.
- Introduce la contraseñacontraseña(como se define en el código).
- Una vez conectado, abre un navegador y ve a
http://192.168.4.1/(la IP predeterminada para el modo AP del ESP32). - Aparece la misma página de control, lo que te permite cambiar el texto, el color, la velocidad y la dirección.
Este comportamiento de respaldo hace que el proyecto sea útil en cualquier lugar: en casa, en el laboratorio o en un entorno de demostración donde no hay enrutador disponible.
Proyecto 3 - Configuraciones Principales en el Código
El boceto completo de HTTP Text se carga a continuación de este artículo en el sitio web. Aquí solo documentamos las opciones de configuración más importantes que es probable que edites.
Configuración de Wi-Fi y Punto de Acceso
En la parte superior del boceto encontrarás la sección de configuración de Wi-Fi. Solo cambia las credenciales de la Estación (Wi-Fi en casa); los ajustes del AP normalmente se mantienen como predeterminados:
// ---------- Wi-Fi SETTINGS ----------
// Home Wi-Fi (Station mode)
const char* WIFI_SSID = "YourHomeWiFi"; // put your router SSID here
const char* WIFI_PASS = "YourHomePassword"; // put your router password here
// Fallback Access Point (AP mode)
const char* AP_SSID = "ESP32"; // fixed AP name
const char* AP_PASS = "password"; // fixed AP password
Comportamiento:
- Si
WIFI_SSIDyWIFI_PASSson correctos y la red está disponible → el ESP32 se conecta como un dispositivo Wi-Fi normal (modo Estación). - Si la conexión falla después de un tiempo de espera → el ESP32 inicia su propio AP usando
AP_SSIDyAP_PASS.
Piano, tamaño y brillo de la matriz
Estos ajustes son los mismos que los proyectos anteriores:
// Matrix configuration
const int MATRIX_PIN = 14; // RGB matrix data pin
const int MATRIX_WIDTH = 8;
const int MATRIX_HEIGHT = 8;
// Overall display brightness (0–255)
uint8_t matrixBrightness = 40; // adjust for your environment
ManténMATRIX_PINen14para esta placa. Puedes aumentarmatrixBrightnesssi necesitas más luz, pero los valores más bajos son más cómodos para ver de cerca.
Texto predeterminado y configuraciones de desplazamiento
Cuando la pizarra se inicia, muestra un mensaje inicial hasta que abras la página web y escribas uno nuevo. Puedes cambiar el texto predeterminado en la configuración:
// Default message shown at startup
String currentText = "Robojax"; // overwrite from web UI later
El resto del comportamiento de desplazamiento se controla mediante un conjunto de variables que se actualizan a través de la interfaz web:
// Scroll delay in milliseconds (lower = faster)
int scrollDelayMs = 50;
// Scroll direction: 0=left, 1=right, 2=up, 3=down
int scrollDirection = 0; // default: scroll left
La página web envía nuevos valores basados en las selecciones del control deslizante y los botones. Desde el lado de Arduino, solo necesitas saber que:
- Disminuyendo
scrollDelayMshace que el texto se mueva más rápido. - Aumentando
scrollDelayMshace que se mueva más lento. - Cambiando
scrollDirectioncambia entre los modos de desplazamiento hacia la izquierda, hacia la derecha, hacia arriba o hacia abajo.
Color del texto (Controlado desde la página web)
El color del texto se controla mediante tres valores de 0 a 255 (rojo, verde, azul). Se actualizan cada vez que eliges un nuevo color en la página web:
// Current text color (R, G, B)
uint8_t textRed = 255;
uint8_t textGreen = 255;
uint8_t textBlue = 255;
Cuando seleccionas un color en el navegador y haces clic en Aplicar, el ESP32 analiza los valores RGB y actualiza estas tres variables; el texto cambia de color inmediatamente en la matriz. En el video, se demuestra este comportamiento con múltiples cambios de color, incluidos ejemplos en rojo, verde y azul.:contentReference[oaicite:5]{index=5}
Resumen
El Proyecto 3 convierte tu matriz de LED RGB ESP32-S3 en una pantalla de texto completamente inalámbrica que puedes controlar usando cualquier dispositivo con un navegador web. El boceto está diseñado para ser robusto:
- Primero intenta conectarse a tu Wi-Fi en casa utilizando el SSID y la contraseña que configuraste.
- Si eso falla, se convierte automáticamente en un punto de acceso con el nombre
ESP32y contraseñapassword. - En ambos modos, abrir la dirección IP correcta en un navegador muestra la misma página de control para texto, color, dirección y velocidad.
El código completo de texto HTTP está disponible a continuación de este artículo (cargado automáticamente en el sitio web). Para una guía completa paso a paso y una demostración en vivo de cómo se actualiza el texto en tiempo real, asegúrate de ver la sección del Proyecto 3 del video. Si deseas construir el proyecto tú mismo, también puedes comprar el módulo de matriz LED RGB ESP32-S3 utilizando los enlaces de afiliados que aparecen debajo del código.
Este tutorial es parte de: Matriz de LED RGB ESP32-S3
- Proyectos con Matriz LED RGB para ESP32-S3 (Juego de Inclinación, Texto, Flecha, Demostración WiFi)
- Proyecto 2 de matriz de LED RGB ESP32-S3 - Texto en desplazamiento
- Proyecto de matriz de LED RGB ESP32-S3 4 - Punto inclinado
- Proyecto de Matriz LED RGB ESP32-S3 5 - Flecha siempre arriba
- Proyecto de Matriz LED RGB ESP32-S3 6 - Juego de Cible
- Proyecto de reloj básico con matriz LED RGB ESP32-S3 Wi-Fi + hora NTP -1
- Proyecto de Reloj por Internet con Matriz LED RGB ESP32-S3 - Pantalla de Hora y Fecha multicolor de 2 Relojes
- Proyecto de Reloj de Internet con Matriz de LED RGB ESP32-S3 - 3 Colores Nocturnos con Fecha
- Proyecto de reloj de internet con matriz de LED RGB ESP32-S3 - 5 colores del arcoíris
- Proyecto de reloj en Internet con matriz de LED RGB ESP32-S3 - 4 colores aleatorios
- Prueba de matriz LED RGB ESP32-S3 para configuración RGB, GRB
/*
* Proyecto 4: Desplazamiento de Texto HTTP - Matriz de LED RGB ESP32-S3 (Waveshare)
*
* - Se conecta a tu WiFi doméstico (modo estación, con respaldo AP).
* - Sirve una página web donde puedes configurar:
* Texto
* Color
* Encender/Apagar pantalla
* Dirección de desplazamiento (Izquierda / Derecha / Arriba / Abajo)
* Retraso de desplazamiento (velocidad)
* - Soporta matriz de LED RGB 8×8 usando Adafruit_NeoMatrix.
*
* ▶️ Tutorial en Video:
* https://youtu.be/JKLuYrRcLMI
*
* 📄 Recursos y Página de Código:
* https://robojax.com/your-resources-page-here
*
* HTTP_Text_Scroll
*/
#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
// ======================= CONFIGURACIÓN DE WIFI =========================
// WiFi en casa (cambia esto por las credenciales de tu router)
const char* WIFI_SSID = "Biseem";
const char* WIFI_PASS = "wan9&Jang~";
// Punto de Acceso de Respaldo
const char* AP_SSID = "ESP32";
const char* AP_PASS = "password";
// ======================= CONFIGURACIÓN DE LA MATRIZ =======================
#define MATRIX_PIN 14
#define MATRIX_WIDTH 8
#define MATRIX_HEIGHT 8
// 0, 1, 2 o 3 - ajusta si la orientación del texto es incorrecta con el USB hacia arriba
#define MATRIX_ROTATION 0
#define BRIGHTNESS 15
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
);
// ======================= ESTADO DEL DESPLAZAMIENTO ==========================
enum ScrollDir {
DIR_LEFT = 0,
DIR_RIGHT,
DIR_UP,
DIR_DOWN
};
String scrollText = "Robojax";
uint16_t textColor = 0xFFFF; // blanco predeterminado
bool displayOn = true;
ScrollDir currentDir = DIR_LEFT;
// 1 paso cada tantos ms (menor = más rápido)
unsigned long scrollInterval = 80;
unsigned long lastScrollTime = 0;
// Posición de desplazamiento horizontal
int scrollX = MATRIX_WIDTH;
int scrollY = 0; // fila superior
// Estado para desplazamiento vertical letra por letra
int vertCharIndex = 0; // qué carácter de la cadena
int vertY = MATRIX_HEIGHT; // posición vertical de ese carácter
// ======================= SERVIDOR WEB ============================
WebServer server(80);
// ======================= PÁGINA HTML ============================
const char MAIN_page[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ESP32 Text Scroll</title>
<style>
body {
font-family: Arial, sans-serif;
background: #111;
color: #eee;
text-align: center;
margin: 0;
padding: 10px;
}
.container {
max-width: 360px;
width: 100%%;
margin: 0 auto;
background: #222;
padding: 12px;
border-radius: 10px;
box-sizing: border-box;
}
input[type="text"] {
width: 100%%;
padding: 8px;
box-sizing: border-box;
border-radius: 5px;
border: 1px solid #444;
background: #111;
color: #eee;
margin-bottom: 10px;
}
.row {
margin: 10px 0;
}
.label {
display: block;
margin-bottom: 5px;
text-align: left;
}
.toggle {
display: inline-flex;
align-items: center;
gap: 8px;
}
.arrow-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-template-rows: repeat(3, 50px);
gap: 8px;
justify-content: center;
margin-top: 10px;
}
.arrow-btn {
background: #333;
border: 1px solid #555;
color: #eee;
font-size: 18px;
border-radius: 10px;
cursor: pointer;
width: 100%%;
height: 100%%;
}
.arrow-btn.active {
background: #0a84ff;
}
.arrow-btn:disabled {
opacity: 0.5;
cursor: default;
}
button#applyBtn {
margin-top: 15px;
padding: 10px 20px;
border-radius: 8px;
border: none;
background: #0a84ff;
color: #fff;
font-size: 16px;
cursor: pointer;
}
button#applyBtn:active {
transform: scale(0.97);
}
</style>
</head>
<body>
<div class="container">
<h2>Robojax ESP32-S3 Matrix Text Scroll</h2>
<div class="row">
<span class="label">Text to scroll:</span>
<input type="text" id="text" value="Hello" />
</div>
<div class="row">
<span class="label">Color:</span>
<input type="color" id="color" value="#ffffff" />
</div>
<div class="row">
<span class="label">Scroll Delay (fast → slow):</span>
<input
type="range"
id="speed"
min="20"
max="300"
value="80"
oninput="document.getElementById('speedVal').innerText = this.value + ' ms';"
/>
<div id="speedVal" style="text-align:right;font-size:12px;margin-top:4px;">
80 ms
</div>
</div>
<div class="row">
<label class="toggle">
<input type="checkbox" id="power" checked />
<span>Display ON</span>
</label>
</div>
<div class="row">
<span class="label">Scroll Direction:</span>
<div class="arrow-grid">
<div></div>
<button class="arrow-btn" id="btnUp" onclick="setDir('up')">▲</button>
<div></div>
<button class="arrow-btn" id="btnLeft" onclick="setDir('left')">◀</button>
<div></div>
<button class="arrow-btn" id="btnRight" onclick="setDir('right')">▶</button>
<div></div>
<button class="arrow-btn" id="btnDown" onclick="setDir('down')">▼</button>
<div></div>
</div>
</div>
<button id="applyBtn" onclick="sendUpdate()">Apply</button>
<p id="status"></p>
</div>
<script>
let currentDir = 'left';
function setDir(dir) {
currentDir = dir;
document.querySelectorAll('.arrow-btn').forEach(b => b.classList.remove('active'));
if (dir === 'up') document.getElementById('btnUp').classList.add('active');
if (dir === 'down') document.getElementById('btnDown').classList.add('active');
if (dir === 'left') document.getElementById('btnLeft').classList.add('active');
if (dir === 'right') document.getElementById('btnRight').classList.add('active');
sendUpdate();
}
function sendUpdate() {
const text = document.getElementById('text').value;
const color = document.getElementById('color').value;
const power = document.getElementById('power').checked ? '1' : '0';
const speed = document.getElementById('speed').value;
const url = `/update?text=${encodeURIComponent(text)}&color=${encodeURIComponent(color)}&power=${power}&dir=${currentDir}&speed=${speed}`;
fetch(url)
.then(r => r.text())
.then(t => {
document.getElementById('status').innerText = t;
})
.catch(err => {
document.getElementById('status').innerText = 'Error sending update';
});
}
// Establecer activo por defecto
setDir('left');
</script>
</body>
</html>
)rawliteral";
// ======================= AYUDANTES ===============================
bool isHexChar(char c) {
return (c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'f') ||
(c >= 'A' && c <= 'F');
}
String urlDecode(const String &src) {
String result;
result.reserve(src.length());
for (size_t i = 0; i < src.length(); i++) {
char c = src[i];
if (c == '+') {
result += ' ';
} else if (c == '%' && i + 2 < src.length()) {
char h1 = src[i + 1];
char h2 = src[i + 2];
if (isHexChar(h1) && isHexChar(h2)) {
char hex[3] = {h1, h2, 0};
int val = (int)strtol(hex, nullptr, 16);
result += (char)val;
i += 2;
} else {
result += c;
}
} else {
result += c;
}
}
return result;
}
uint16_t colorFromHex(const String &hex) {
// Espera "#RRGGBB" o "RRGGBB"
String c = hex;
if (c.startsWith("#")) c.remove(0, 1);
if (c.length() != 6) {
// blanco predeterminado
return matrix.Color(255, 255, 255);
}
long value = strtol(c.c_str(), NULL, 16);
uint8_t r = (value >> 16) & 0xFF;
uint8_t g = (value >> 8) & 0xFF;
uint8_t b = (value) & 0xFF;
return matrix.Color(r, g, b);
}
void resetScrollPosition() {
int textWidth = scrollText.length() * 6; // fuente predeterminada ~6 px por carácter
int textHeight = 8; // La fuente de 5x7 cabe en 8.
switch (currentDir) {
case DIR_LEFT:
// Comienza justo fuera del borde derecho.
scrollX = MATRIX_WIDTH;
scrollY = 0;
break;
case DIR_RIGHT:
// Comienza justo fuera del borde izquierdo.
scrollX = -textWidth;
scrollY = 0;
break;
case DIR_UP:
// Desplazamiento vertical por letra, comenzando con el primer carácter debajo de la matriz
vertCharIndex = 0;
vertY = MATRIX_HEIGHT; // 8 → entra desde abajo
break;
case DIR_DOWN:
// Desplazamiento vertical por letra, comenzando con el primer carácter por encima de la matriz
vertCharIndex = 0;
vertY = -textHeight; // -8 → entra desde arriba
break;
}
}
// ======================= CONTROLADORES HTTP =========================
void handleRoot() {
server.send_P(200, "text/html", MAIN_page);
}
void handleUpdate() {
if (server.hasArg("text")) {
String txt = urlDecode(server.arg("text"));
if (txt.length() == 0) {
scrollText = " ";
} else {
scrollText = txt;
}
}
if (server.hasArg("color")) {
String hex = server.arg("color");
textColor = colorFromHex(hex);
}
if (server.hasArg("power")) {
String p = server.arg("power");
displayOn = (p == "1");
}
if (server.hasArg("dir")) {
String d = server.arg("dir");
if (d == "left") currentDir = DIR_LEFT;
else if (d == "right") currentDir = DIR_RIGHT;
else if (d == "up") currentDir = DIR_UP;
else if (d == "down") currentDir = DIR_DOWN;
}
if (server.hasArg("speed")) {
String s = server.arg("speed");
int val = s.toInt();
// abrazadera de seguridad sencilla
if (val < 10) val = 10; // muy rápido
if (val > 1000) val = 1000; // 1 segundo máximo
scrollInterval = (unsigned long)val;
// Serial.print("Intervalo de desplazamiento configurado a ");
// Serial.print(scrollInterval);
// serial.println(" ms");
}
resetScrollPosition();
server.send(200, "text/plain", "Updated");
}
// ======================= LÓGICA DE DESPLAZAMIENTO ==========================
void drawScroll() {
if (!displayOn) {
matrix.fillScreen(0);
matrix.show();
return;
}
int textWidth = scrollText.length() * 6;
int textHeight = 8;
matrix.fillScreen(0);
matrix.setTextSize(1);
matrix.setTextWrap(false);
matrix.setTextColor(textColor);
// -------- DESPLAZAMIENTO HORIZONTAL (IZQUIERDA / DERECHA) --------
if (currentDir == DIR_LEFT || currentDir == DIR_RIGHT) {
matrix.setCursor(scrollX, 0);
matrix.print(scrollText);
matrix.show();
if (currentDir == DIR_LEFT) {
scrollX--;
if (scrollX < -textWidth) {
scrollX = MATRIX_WIDTH;
}
} else { // DIR_DERECHA
scrollX++;
if (scrollX > MATRIX_WIDTH) {
scrollX = -textWidth;
}
}
return;
}
// -------- DESPLAZAMIENTO VERTICAL (ARRIBA / ABAJO) - POR LETRA --------
if (scrollText.length() == 0) {
matrix.show();
return;
}
// Personaje actual
char c = scrollText[vertCharIndex];
int charWidth = 6;
int baseX = (MATRIX_WIDTH - charWidth) / 2; // centrar horizontalmente
matrix.setCursor(baseX, vertY);
matrix.print(c);
matrix.show();
if (currentDir == DIR_UP) {
// Mover el personaje hacia arriba
vertY--;
if (vertY < -textHeight) {
// Este personaje está completamente aprobado, pasa al siguiente.
vertY = MATRIX_HEIGHT;
vertCharIndex++;
if (vertCharIndex >= scrollText.length()) {
vertCharIndex = 0; // volver al primer carácter
}
}
} else if (currentDir == DIR_DOWN) {
// Mover el personaje hacia abajo
vertY++;
if (vertY > MATRIX_HEIGHT) {
// Este personaje está completamente aprobado, pasa al siguiente.
vertY = -textHeight;
vertCharIndex++;
if (vertCharIndex >= scrollText.length()) {
vertCharIndex = 0; // bucle de retorno
}
}
}
}
// ======================= INICIO WIFI =============================
void startAPFallback() {
Serial.println("Starting AP fallback...");
WiFi.mode(WIFI_AP);
bool apOk = WiFi.softAP(AP_SSID, AP_PASS);
if (apOk) {
Serial.print("AP started. SSID: ");
Serial.print(AP_SSID);
Serial.print(" IP: ");
Serial.println(WiFi.softAPIP());
} else {
Serial.println("Failed to start AP.");
}
}
void connectWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
Serial.print("Connecting to WiFi ");
Serial.print(WIFI_SSID);
unsigned long startAttempt = millis();
const unsigned long timeout = 10000; // 10s
while (WiFi.status() != WL_CONNECTED && (millis() - startAttempt) < timeout) {
Serial.print(".");
delay(500);
}
Serial.println();
if (WiFi.status() == WL_CONNECTED) {
Serial.print("Connected. IP address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("WiFi connect failed, starting AP fallback.");
startAPFallback();
}
}
// ======================= CONFIGURACIÓN Y BUCLE ==========================
void setup() {
Serial.begin(115200);
delay(500);
// Inicialización de la matriz
matrix.begin();
matrix.setRotation(MATRIX_ROTATION);
matrix.setBrightness(BRIGHTNESS);
matrix.fillScreen(0);
matrix.show();
// WiFi
connectWiFi();
// Rutas del servidor web
server.on("/", handleRoot);
server.on("/update", handleUpdate);
server.onNotFound([]() {
server.send(404, "text/plain", "Not found");
});
server.begin();
Serial.println("HTTP server started.");
resetScrollPosition();
}
void loop() {
server.handleClient();
unsigned long now = millis();
if (now - lastScrollTime >= scrollInterval) {
lastScrollTime = now;
drawScroll();
}
}
Cosas que podrías necesitar
-
Amazonas
-
eBay
-
AliExpressCompra ESP32-S3 Matriz RGB en AliExpress (2)s.click.aliexpress.com
-
AliExpressCompra la matriz RGB ESP32-S3 en AliExpress.s.click.aliexpress.com
Recursos y referencias
-
Interno🎨 Herramienta de selección de colorrobojax.com
Archivos📁
Archivo de Fritzing
-
parte fritzing esp32-S3-supermini-tht
esp32-S3-supermini-tht.fzpz0.02 MB