Questo tutorial è parte di: Matrice LED RGB ESP32-S3
Fantastico progetto da realizzare per applicazioni pratiche e divertenti utilizzando il modulo RGB Matrix ESP32-S3. I link ad altri video si trovano più avanti in questo articolo.
Progetto ESP32-S3 Matrice LED RGB 3 - Testo da telefono cellulare
Progetto 3 - Testo della matrice di controllo dal tuo telefono (Testo HTTP)
In questo progetto il modulo ESP32-S3 RGB LED Matrix ospita una piccola pagina web in modo da poter modificare il testo scorrevole, il colore, la direzione e la velocità direttamente dal tuo telefono o computer. Non hai bisogno di un'app separata, solo di un browser web. Questo rende il modulo un piccolo display di testo Wi-Fi che puoi aggiornare in tempo reale.
Tutti e sei i progetti di questa serie sono spiegati e dimostrati in un video di YouTube. Lo stesso video è incorporato in questa pagina, quindi puoi vedere esattamente come appare l'interfaccia web e come il testo si aggiorna istantaneamente sulla matrice. Il codice sorgente completo per questo progetto viene caricato automaticamente sotto l'articolo, e puoi acquistare il modulo matrice LED RGB ESP32-S3 presso i negozi affiliati elencati nella sezione codice.
In questo articolo ci concentriamo su come funziona la logica di rete (Wi-Fi domestico vs punto di accesso) e su quali impostazioni puoi modificare nel codice per personalizzare il comportamento.



Panoramica del Modulo Matrice LED RGB ESP32-S3
L'hardware è lo stesso di tutti gli altri progetti di questa serie: una scheda microcontrollore ESP32-S3 con una matrice LED RGB 8×8 incorporata e un sensore di movimento QMI8658C sul retro. La porta USB-C è utilizzata per l'alimentazione e la programmazione, e i pin attorno ai bordi sono ancora disponibili per altre I/O.:contentReference[oaicite:0]{index=0}

- ESP32-S3Microcontrollore con capacità Wi-Fi e Bluetooth.
- matrice RGB 8×8- 64 LED RGB indirizzabili per testo e grafica.
- accelerometro QMI8658C- utilizzato nei progetti di tilt e gioco.
- porta USB- alimenta la scheda e carica gli sketch dall'IDE di Arduino.
- Pin esposti- consentire sensori o attuatori aggiuntivi se necessario.
- Pulsanti di avvio/reimpostazione- per il caricamento del firmware e il riavvio.
Per il Progetto 3, la caratteristica più importante è il Wi-Fi dell'ESP32, che consente alla scheda di funzionare come un piccolo server web per la pagina di controllo del testo.:contentReference[oaicite:1]{index=1}

Progetti trattati nel video (Timestamp)
Il video unico per questa serie copre tutti e sei i progetti. Per un rapido riferimento:
- 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 del Testo
- 12:59-Progetto 3: HTTP Testo (questo progetto)
- 16:41- Progetto 4: Tilt Dot
- 18:55- Progetto 5: Freccia Su
- 20:02- Progetto 6: Gioco del bersaglio
Si consiglia di guardare la sezione HTTP Text nel video mentre si lavora con questo articolo. Il video mostra come viene generata la pagina web dall'ESP32 e come le modifiche al testo, al colore e alla velocità vengano riflesse istantaneamente sulla matrice di LED.:contentReference[oaicite:2]{index=2}
Installazione delle schede ESP32 nell'Arduino IDE
Se hai già completato i Progetti 1 o 2, la configurazione della scheda è stata completata e puoi saltare questa sezione. Altrimenti, segui questi passaggi nell'IDE Arduino:
- Apri
File > Preferencese aggiungi l'URL delle schede ESP32 a "URL aggiuntivi del gestore schede". - Vai a
Tools > Board > Boards Manager…, cerca diESP32e installa il pacchetto ufficiale ESP32. - Seleziona la scheda matrice RGB ESP32-S3 corretta da
Tools > Board. - Collega il modulo tramite USB e scegli la porta seriale corretta sotto
Tools > Port.
Senza il supporto corretto per la scheda ESP32 e la porta giusta, lo sketch del server web non verrà caricato.
Installazione di NeoMatrix e librerie richieste
Questo progetto utilizza le stesse librerie del precedente progetto di scorrimento del testo:
Adafruit NeoMatrixAdafruit NeoPixelAdafruit GFX Library
Installa tramite il Gestore Librerie:
- Apri
Sketch > Include Library > Manage Libraries…. - Cerca per
Adafruit NeoMatrixe fai clicInstalla. - Accetta l'installazione delle dipendenze
Adafruit GFXeAdafruit NeoPixel).
Una volta installati, dovresti vedere gli esempi di sketch NeoMatrix e NeoPixel sottoFile > Examples.
Due modalità Wi-Fi nel Progetto 3
Il concetto più importante di questo progetto è che l'ESP32 può funzionare indue modalità diverse:
- Modalità Stazione (STA)- l'ESP32 si connette alla tua rete Wi-Fi domestica esistente.
- Modalità Access Point (AP)L'ESP32 crea la propria rete Wi-Fi se la rete Wi-Fi di casa non è disponibile.
Entrambi i modelli utilizzano la stessa interfaccia web: una pagina HTML servita direttamente dall'ESP32, dove puoi cambiare il testo, il colore, la direzione di scorrimento e la velocità.:contentReference[oaicite:3]{index=3}
Modalità 1 - Connessione al Wi-Fi di casa (Modalità Stazione)
In modalità Stazione, l'ESP32 si connette alla rete Wi-Fi di casa o dell'ufficio. Questa è la modalità preferita ogni volta che il tuo router è disponibile perché:
- Il tuo telefono e computer sono già connessi alla stessa rete Wi-Fi.
- Puoi puntare il tuo browser all'indirizzo IP dell'ESP32 e controllare il testo da qualsiasi dispositivo su quella rete.
Nella sezione delle impostazioni dello sketch, fornisci il tuo SSID Wi-Fi e la password:
// Home Wi-Fi credentials (Station mode)
const char* WIFI_SSID = "YourHomeWiFi";
const char* WIFI_PASS = "YourHomePassword";
Dopo che la scheda si avvia, tenta di connettersi aWIFI_SSIDSe ha successo, il codice stampa l'indirizzo IP assegnato al Monitor Serial, per esempio:
Connected to WiFi
IP address: 192.168.1.16
Per controllare il testo:
- Assicurati che il tuo telefono o PC sia connesso alla stessa rete Wi-Fi (ad esempio,
YourHomeWiFi). - Apri un browser e inserisci l'indirizzo IP stampato, come
http://192.168.1.16/. :contentReference[oaicite:4]{index=4} - La pagina di controllo apparirà, consentendoti di digitare testo, scegliere il colore, selezionare la direzione e regolare la velocità di scorrimento.
Modalità 2 - Punto di Accesso Standalone (Modalità AP)
Se l'ESP32 non riesce a connettersi al Wi-Fi di casa (password errata, rete non disponibile o se stai utilizzando il modulo all'esterno), lo sketch torna automaticamente alla modalità Punto di Accesso. In modalità AP, l'ESP32 diventa un hotspot Wi-Fi con il proprio nome di rete e password.
In questo progetto, le impostazioni AP sono fissate a:
// Access Point (AP) credentials (fallback mode)
const char* AP_SSID = "ESP32";
const char* AP_PASS = "password";
Quando la modalità Stazione fallisce, il modulo passa alla modalità AP e inizia a trasmettere una rete Wi-Fi chiamataESP32. Per controllare la matrice:
- Sul tuo telefono o computer, apri le impostazioni Wi-Fi e connettiti alla rete.ESP32.
- Inserisci la passwordpassword(come definito nel codice).
- Una volta connesso, apri un browser e vai a
http://192.168.4.1/(l'indirizzo IP predefinito per la modalità AP dell'ESP32). - La stessa pagina di controllo appare, permettendoti di cambiare testo, colore, velocità e direzione.
Questo comportamento di fallback rende il progetto utile ovunque: a casa, in laboratorio o in un ambiente dimostrativo dove non è disponibile alcun router.
Progetto 3 - Impostazioni principali nel codice
Il completo schema del testo HTTP è caricato sotto questo articolo dal sito web. Qui documentiamo solo le opzioni di configurazione più importanti che è probabile tu debba modificare.
Impostazioni Wi-Fi e Punto di Accesso
In cima del disegno troverai la sezione di configurazione Wi-Fi. Cambia solo le credenziali della Stazione (Wi-Fi di casa); le impostazioni AP sono normalmente mantenute come predefinite:
// ---------- 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
Comportamento:
- Se
WIFI_SSIDeWIFI_PASSsono corretti e la rete è disponibile → ESP32 si connette come un normale dispositivo Wi-Fi (modalità Stazione). - Se la connessione fallisce dopo un timeout → ESP32 avvia il proprio AP utilizzando
AP_SSIDeAP_PASS.
Pin della matrice, dimensione e luminosità
Queste impostazioni sono le stesse dei progetti precedenti:
// 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
MantieniMATRIX_PINat14per questa scheda. Puoi aumentarematrixBrightnessse hai bisogno di più luce, ma valori più bassi sono più comodi per la visualizzazione da vicino.
Impostazioni predefinite del testo e di scorrimento
Quando la scheda si avvia, visualizza un messaggio iniziale fino a quando non apri la pagina web e non ne digiti uno nuovo. Puoi cambiare il testo predefinito nella configurazione:
// Default message shown at startup
String currentText = "Robojax"; // overwrite from web UI later
Il resto del comportamento dello scroll è controllato da un insieme di variabili che vengono aggiornate dall'interfaccia 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 pagina web invia nuovi valori basati sulle selezioni dello slider e dei pulsanti. Dal lato di Arduino, devi solo sapere che:
- Decrescente
scrollDelayMsrende il testo più veloce. - In aumento
scrollDelayMslo fa muovere più lentamente. - Cambiando
scrollDirectionpassa tra modalità di scorrimento a sinistra, a destra, in alto o in basso.
Colore del testo (Controllato dalla pagina web)
Il colore del testo è controllato da tre valori compresi tra 0 e 255 (rosso, verde, blu). Vengono aggiornati ogni volta che scegli un nuovo colore sulla pagina web:
// Current text color (R, G, B)
uint8_t textRed = 255;
uint8_t textGreen = 255;
uint8_t textBlue = 255;
Quando scegli un colore nel browser e clicchi su Applica, l'ESP32 analizza i valori RGB e aggiorna queste tre variabili; il testo cambia immediatamente colore sulla matrice. Nel video, questo comportamento è dimostrato con molteplici variazioni di colore, inclusi esempi di rosso, verde e blu.:contentReference[oaicite:5]{index=5}
Riepilogo
Il Progetto 3 trasforma il tuo matrice LED RGB ESP32-S3 in un display testuale completamente wireless che puoi controllare utilizzando qualsiasi dispositivo con un browser web. Lo sketch è progettato per essere robusto:
- Prima tenta di connettersi al tuo Wi-Fi domestico utilizzando l'SSID e la password che hai configurato.
- Se ciò fallisce, diventa automaticamente un punto di accesso con il nome
ESP32e passwordpassword. - In entrambe le modalità, l'apertura dell'indirizzo IP corretto in un browser visualizza la stessa pagina di controllo per testo, colore, direzione e velocità.
Il codice HTTP Text completo è disponibile sotto questo articolo (caricato automaticamente sul sito web). Per una guida passo passo completa e una dimostrazione dal vivo su come il testo si aggiorna in tempo reale, assicurati di guardare la sezione Progetto 3 del video. Se desideri costruire il progetto da solo, puoi anche acquistare il modulo LED Matrix RGB ESP32-S3 utilizzando i link affiliati elencati sotto il codice.
Questo tutorial è parte di: Matrice LED RGB ESP32-S3
- Progetti con Matrice LED RGB ESP32-S3 (Gioco Inclinazione, Testo, Freccia, Demo WiFi)
- Progetto Matrice LED RGB ESP32-S3 2 - Testo Scorrevole
- Progetto Matrice LED RGB ESP32-S3 4 - Punta inclinata
- Progetto Matrice LED RGB ESP32-S3 5 - Freccia sempre verso l'alto
- Progetto 6 della matrice LED RGB ESP32-S3 - Gioco Cible
- Progetto orologio di base ESP32-S3 Matrice LED RGB Wi-Fi + Orologio NTP -1
- Progetto Orologio Internet con Matrice LED RGB ESP32-S3 - Orologio a colori multipli con visualizzazione di Ora e Data
- Progetto Orologio Internet con Matrice LED RGB ESP32-S3 - Colore Notte 3 con Data
- Progetto di orologio Internet con matrice LED RGB ESP32-S3 - 5 colori arcobaleno
- Progetto Orologio Internet con Matrice LED RGB ESP32-S3 - 4 Colori casuali
- Test della matrice LED RGB ESP32-S3 per impostazione RGB, GRB
/*
* Progetto 4: Scorrimento Testo HTTP - Matrice LED RGB ESP32-S3 (Waveshare)
*
* - Si connette al tuo WiFi domestico (modalità stazione, con fallback AP).
* - Serve una pagina web dove puoi impostare:
* Testo
* Colore
* Display ON/OFF
* Direzione di scorrimento (Sinistra / Destra / Su / Giù)
* Ritardo di scorrimento (velocità)
* - Supporta matrice LED RGB 8×8 utilizzando Adafruit_NeoMatrix.
*
* ▶️ Tutorial Video:
* https://youtu.be/JKLuYrRcLMI
*
* 📄 Risorse & Pagina Codice:
* 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>
// ======================= IMPOSTAZIONI WIFI =========================
// WiFi domestico (cambia queste con le credenziali del tuo router)
const char* WIFI_SSID = "Biseem";
const char* WIFI_PASS = "wan9&Jang~";
// Punto di accesso di emergenza
const char* AP_SSID = "ESP32";
const char* AP_PASS = "password";
// ======================= IMPOSTAZIONI MATRICE =======================
#define MATRIX_PIN 14
#define MATRIX_WIDTH 8
#define MATRIX_HEIGHT 8
// 0, 1, 2 o 3 - regola se l'orientamento del testo è sbagliato con USB in alto
#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
);
// ======================= STATO DELLA SCORRIMENTO ==========================
enum ScrollDir {
DIR_LEFT = 0,
DIR_RIGHT,
DIR_UP,
DIR_DOWN
};
String scrollText = "Robojax";
uint16_t textColor = 0xFFFF; // bianco predefinito
bool displayOn = true;
ScrollDir currentDir = DIR_LEFT;
// 1 passo ogni questo numero di ms (minore = più veloce)
unsigned long scrollInterval = 80;
unsigned long lastScrollTime = 0;
// Posizione di scorrimento orizzontale
int scrollX = MATRIX_WIDTH;
int scrollY = 0; // fila superiore
// Stato per lo scorrimento verticale per lettera
int vertCharIndex = 0; // quale carattere della stringa
int vertY = MATRIX_HEIGHT; // posizione verticale di quel carattere
// ======================= SERVER WEB ============================
WebServer server(80);
// ======================= PAGINA 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';
});
}
// Imposta attivo predefinito
setDir('left');
</script>
</body>
</html>
)rawliteral";
// ======================= AIUTANTI ===============================
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) {
// Aspettati "#RRGGBB" o "RRGGBB"
String c = hex;
if (c.startsWith("#")) c.remove(0, 1);
if (c.length() != 6) {
// bianco predefinito
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; // carattere predefinito ~6 px per carattere
int textHeight = 8; // Il carattere 5x7 si adatta in 8
switch (currentDir) {
case DIR_LEFT:
// Inizia appena all'esterno del bordo destro.
scrollX = MATRIX_WIDTH;
scrollY = 0;
break;
case DIR_RIGHT:
// Inizia appena al di fuori del bordo sinistro.
scrollX = -textWidth;
scrollY = 0;
break;
case DIR_UP:
// Scorrimento verticale per lettera, partendo dal primo carattere sotto la matrice
vertCharIndex = 0;
vertY = MATRIX_HEIGHT; // 8 → entra da basso
break;
case DIR_DOWN:
// Scorrimento verticale per lettera, iniziando con il primo carattere sopra la matrice
vertCharIndex = 0;
vertY = -textHeight; // -8 → entra dall'alto
break;
}
}
// ======================= GESTORI 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();
// morsetto di sicurezza semplice
if (val < 10) val = 10; // molto veloce
if (val > 1000) val = 1000; // 1 secondo max
scrollInterval = (unsigned long)val;
// Serial.print("Intervallo di scorrimento impostato su ");
// Serial.print(scrollInterval);
// Serial.println(" ms");
}
resetScrollPosition();
server.send(200, "text/plain", "Updated");
}
// ======================= LOGICA SCORRIMENTO ==========================
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);
// -------- SCORRIMENTO ORIZZONTALE (SINISTRA / DESTRA) --------
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_DESTRA
scrollX++;
if (scrollX > MATRIX_WIDTH) {
scrollX = -textWidth;
}
}
return;
}
// -------- SCORRIMENTO VERTICALE (SU / GIÙ) - PER LETTERA --------
if (scrollText.length() == 0) {
matrix.show();
return;
}
// Personaggio attuale
char c = scrollText[vertCharIndex];
int charWidth = 6;
int baseX = (MATRIX_WIDTH - charWidth) / 2; // centrare orizzontalmente
matrix.setCursor(baseX, vertY);
matrix.print(c);
matrix.show();
if (currentDir == DIR_UP) {
// Sposta il personaggio verso l'alto
vertY--;
if (vertY < -textHeight) {
// Questo personaggio è completamente superato, vai al successivo.
vertY = MATRIX_HEIGHT;
vertCharIndex++;
if (vertCharIndex >= scrollText.length()) {
vertCharIndex = 0; // torna al primo carattere
}
}
} else if (currentDir == DIR_DOWN) {
// Sposta il personaggio verso il basso
vertY++;
if (vertY > MATRIX_HEIGHT) {
// Questo personaggio è completamente superato, vai al successivo.
vertY = -textHeight;
vertCharIndex++;
if (vertCharIndex >= scrollText.length()) {
vertCharIndex = 0; // ritorno al ciclo
}
}
}
}
// ======================= INIZIO 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();
}
}
// ======================= CONFIGURAZIONE E CICLO ==========================
void setup() {
Serial.begin(115200);
delay(500);
// Inizializzazione della matrice
matrix.begin();
matrix.setRotation(MATRIX_ROTATION);
matrix.setBrightness(BRIGHTNESS);
matrix.fillScreen(0);
matrix.show();
// WiFi
connectWiFi();
// Percorsi del server 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();
}
}
Cose di cui potresti avere bisogno
-
Amazon
-
eBay
-
AliExpressAcquista ESP32-S3 RGB Matrix su AliExpress (2)s.click.aliexpress.com
-
AliExpressAcquista la matrice RGB ESP32-S3 da AliExpresss.click.aliexpress.com
Risorse e riferimenti
-
Interno🎨 Strumento selettore di colorerobojax.com
File📁
File Fritzing
-
esp32-S3-supermini-tht parte fritzing
esp32-S3-supermini-tht.fzpz0.02 MB