Hierdie tutorialie is deel van: ESP32-S3 RGB LED-matriks
'n Koel projek om te skep vir prettige en praktiese toepassings met die ESP32-S3 RGB Matriksmodule. Skakels na ander video's is onder hierdie artikel.
ESP32-S3 RGB LED-matriksprojek 3 - Teks vanaf selfoon
Projek 3 – Beheer Matriksteks vanaf jou Foon (HTTP-teks)
In hierdie projek huisves die ESP32-S3 RGB-LED-matriks 'n klein webblad sodat jy die rolteks, kleur, rigting en spoed direk vanaf jou foon of rekenaar kan verander. Jy benodig nie 'n aparte toep nie – net 'n webblaaier. Dit maak die module 'n klein Wi-Fi-teksskerm wat jy in reële tyd kan opdateer.
Al ses projekte in hierdie reeks word in een YouTube-video verduidelik en gedemonstreer. Dieselfde video is op hierdie bladsy ingebed, sodat jy presies kan sien hoe die webkoppelvlak lyk en hoe teks onmiddellik op die matriks opdateer. Die volledige bronkode vir hierdie projek word outomaties onder die artikel gelaai, en jy kan die ESP32-S3 RGB-LED-matriksmodule by geaffilieerde winkels wat onder die kode-afdeling gelys word, aankoop.
In hierdie artikel fokus ons op hoe die netwerklogika werk (huis-Wi-Fi vs toegangspunt) en watter instellings jy in die kode kan verander om die gedrag aan te pas.



ESP32-S3 RGB-LED-matriksmoduleoorsig
Die hardeware is dieselfde as vir al die ander projekte in hierdie reeks: 'n ESP32-S3-mikrobeheerraad met 'n ingeboude 8×8 RGB-LED-matriks en 'n QMI8658C-bewegingsensor aan die agterkant. Die USB-C-poort word vir krag en programmering gebruik, en penne rondom die rande is steeds beskikbaar vir ander I/O.:contentReference[oaicite:0]{index=0}

- ESP32-S3 – Wi-Fi- en Bluetooth-geskikte mikrobeheerder.
- 8×8 RGB-matriks – 64 adresseerbare RGB-LED's vir teks en grafika.
- QMI8658C-versnellingsmeter – gebruik in die kantel- en speletjieprojekte.
- USB-poort – krag die raad en laai sketse vanaf Arduino IDE op.
- Blootgestelde penne – maak voorsiening vir bykomende sensors of aktueerders indien nodig.
- Boot/Reset-knoppies – vir firmware-oplaai en herbegin.
Vir Projek 3 is die belangrikste kenmerk die ESP32 se Wi-Fi, wat die raad in staat stel om as 'n klein webbediener vir die teksbeheerblad op te tree.:contentReference[oaicite:1]{index=1}

Projekte wat in die Video Gedek word (Tydstempels)
Die een video vir hierdie reeks dek al ses projekte. Vir vinnige verwysing:
- 00:00 – Inleiding
- 02:01 – Installeer ESP32-rade
- 03:32 – Installeer biblioteke
- 05:32 – Projek 1: Bewegende Punt
- 11:11 – Projek 2: Teksrol
- 12:59 – Projek 3: HTTP-teks (hierdie projek)
- 16:41 – Projek 4: Kantelpunt
- 18:55 – Projek 5: Pyl Op
- 20:02 – Projek 6: Teikenspeletjie
Jy word aangemoedig om die HTTP-teks-afdeling in die video te kyk terwyl jy met hierdie artikel werk. Die video wys hoe die webblad deur die ESP32 gegenereer word en hoe die verandering van teks, kleur en spoed onmiddellik op die LED-matriks weerspieël word.:contentReference[oaicite:2]{index=2}
Installeer ESP32-rade in Arduino IDE
As jy reeds Projekte 1 of 2 voltooi het, is die raadopstelling klaar en kan jy hierdie afdeling oorslaan. Andersins, volg hierdie stappe in die Arduino IDE:
- Maak
File > Preferencesoop en voeg die ESP32-rade-URL by “Additional Boards Manager URLs”. - Gaan na
Tools > Board > Boards Manager…, soek virESP32, en installeer die amptelike ESP32-pakket. - Kies die korrekte ESP32-S3 RGB-Matriksraad onder
Tools > Board. - Koppel die module via USB en kies die korrekte seriepoort onder
Tools > Port.
Sonder die behoorlike ESP32-raadondersteuning en korrekte poort sal die web-bediener-skets nie oplaai nie.
Installeer NeoMatrix en Vereiste Biblioteke
Hierdie projek gebruik dieselfde biblioteke as die vorige teksrolprojek:
Adafruit NeoMatrixAdafruit NeoPixelAdafruit GFX Library
Installeer via Library Manager:
- Maak
Sketch > Include Library > Manage Libraries…oop. - Soek vir
Adafruit NeoMatrixen klik op Install. - Aanvaar die installasie van afhanklikhede (
Adafruit GFXenAdafruit NeoPixel).
Sodra dit geïnstalleer is, behoort jy die NeoMatrix- en NeoPixel-voorbeeldsketse onder File > Examples te sien.
Twee Wi-Fi-modusse in Projek 3
Die belangrikste konsep in hierdie projek is dat die ESP32 in twee verskillende modusse kan werk:
- Stasie (STA)-modus – die ESP32 koppel aan jou bestaande huis-Wi-Fi-netwerk.
- Toegangspunt (AP)-modus – die ESP32 skep sy eie Wi-Fi-netwerk as huis-Wi-Fi nie beskikbaar is nie.
Beide modusse gebruik dieselfde webkoppelvlak: 'n HTML-bladsy wat vanaf die ESP32 self bedien word, waar jy die teks, kleur, rolrigting en spoed kan verander.:contentReference[oaicite:3]{index=3}
Modus 1 – Koppel aan Huis-Wi-Fi (Stasiemodus)
In Stasiemodus sluit die ESP32 by jou huis- of kantoor-Wi-Fi-netwerk aan. Dit is die voorkeurmodus wanneer jou router beskikbaar is omdat:
- Jou foon en rekenaar is reeds aan dieselfde Wi-Fi-netwerk gekoppel.
- Jy kan jou blaaier na die ESP32 se IP-adres rig en die teks vanaf enige toestel op daardie netwerk beheer.
In die instellingsafdeling van die skets verskaf jy jou Wi-Fi-SSID en wagwoord:
// Tuis Wi-Fi-geldeenthede (Stasie-modus) const char* WIFI_SSID = "YourHomeWiFi"; const char* WIFI_PASS = "YourHomePassword";Nadat die bord begin, probeer dit om met WIFI_SSID te verbind. As dit suksesvol is, druk die kode die toegekende IP-adres na die Serial Monitor, byvoorbeeld:
Connected to WiFi
IP address: 192.168.1.16
Om die teks te beheer:
- Maak seker jou foon of rekenaar is aan dieselfde Wi-Fi-netwerk gekoppel (byvoorbeeld,
YourHomeWiFi). - Maak 'n blaaier oop en voer die gedrukte IP-adres in, soos
http://192.168.1.16/. - Die beheerblad sal verskyn, wat jou toelaat om teks te tik, kleur te kies, rigting te kies, en spoed aan te pas.
Modus 2 – Standalone Access Point (AP-modus)
As die ESP32 nie met jou tuis-Wi-Fi kan verbind nie (verkeerde wagwoord, netwerk nie beskikbaar nie, of jy gebruik die module buite), val die skets outomaties terug na Access Point-modus. In AP-modus word die ESP32 self 'n Wi-Fi-kolpunt met sy eie netwerknaam en wagwoord.
In hierdie projek is die AP-instellings vasgestel as:
// Access Point (AP) credentials (fallback mode)
const char* AP_SSID = "ESP32";
const char* AP_PASS = "password";
Wanneer Stasie-modus misluk, skakel die module na AP-modus en begin uitsaai van 'n Wi-Fi-netwerk genaamd ESP32. Om die matriks te beheer:
- Op jou foon of rekenaar, maak die Wi-Fi-instellings oop en koppel aan die netwerk ESP32.
- Voer die wagwoord password in (soos in die kode gedefinieer).
- Sodra jy gekoppel is, maak 'n blaaier oop en gaan na
http://192.168.4.1/(die standaard IP vir ESP32 AP-modus). - Dieselfde beheerblad verskyn, wat jou toelaat om teks, kleur, spoed, en rigting te verander.
Hierdie terugvalgedrag maak die projek nuttig enige plek: by die huis, in die laboratorium, of in 'n demo-omgewing waar geen router beskikbaar is nie.
Projek 3 – Hoofinstellings in die Kode
Die volledige HTTP Text-skets word onder hierdie artikel deur die webwerf gelaai. Hier dokumenteer ons slegs die belangrikste konfigurasie-opsies wat jy waarskynlik sal wysig.
Wi-Fi en Access Point-instellings
Boonop in die skets sal jy die Wi-Fi-konfigurasie-afdeling vind. Verander slegs die Stasie (tuis-Wi-Fi) geloofsbriewe; die AP-instellings word normaalweg as standaard gehou:
// ---------- 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
Gedrag:
- As
WIFI_SSIDenWIFI_PASSkorrek is en die netwerk beskikbaar is → koppel die ESP32 as 'n normale Wi-Fi-toestel (Stasie-modus). - As verbinding na 'n tydperk misluk → begin die ESP32 sy eie AP met
AP_SSIDenAP_PASS.
Matriks-pen, -grootte, en -helderheid
Hierdie instellings is dieselfde as die vorige projekte:
// 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
Hou MATRIX_PIN by 14 vir hierdie bord. Jy kan matrixBrightness verhoog as jy meer lig nodig het, maar laer waardes is meer gemaklik vir naby-aansig.
Standaardteks en -rolinstellings
Wanneer die bord begin, vertoon dit 'n aanvanklike boodskap totdat jy die webblad oopmaak en 'n nuwe een tik. Jy kan die standaardteks in die konfigurasie verander:
// Default message shown at startup
String currentText = "Robojax"; // overwrite from web UI later
Die res van die rolgedrag word beheer deur 'n stel veranderlikes wat deur die webkoppelvlak bygewerk word:
// 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
Die webblad stuur nuwe waardes gebaseer op die skuifbalk- en knoppiekeuses. Van die Arduino-kant af hoef jy net te weet dat:
- Vermindering van
scrollDelayMsmaak die teks vinniger beweeg. - Vermeerdering van
scrollDelayMsmaak dit stadiger beweeg. - Verandering van
scrollDirectionskakel tussen links, regs, op, of af rolmodusse.
Tekskleur (Beheer vanaf die Webblad)
Die kleur van die teks word beheer deur drie 0–255 waardes (rooi, groen, blou). Hulle word bygewerk wanneer jy 'n nuwe kleur op die webblad kies:
// Current text color (R, G, B)
uint8_t textRed = 255;
uint8_t textGreen = 255;
uint8_t textBlue = 255;
Wanneer jy 'n kleur in die blaaier kies en op Pas toe klik, ontleed die ESP32 die RGB-waardes en werk hierdie drie veranderlikes by; die teks verander onmiddellik van kleur op die matriks. In die video word hierdie gedrag gedemonstreer met verskeie kleurveranderings, insluitend rooi, groen en blou voorbeelde.
Opsomming
Projek 3 verander jou ESP32-S3 RGB LED-matriks in 'n volledig draadlose teksvertoning wat jy met enige toestel met 'n webblaaier kan beheer. Die skets is ontwerp om robuust te wees:
- Dit probeer eers om aan jou huis-Wi-Fi te koppel deur die SSID en wagwoord wat jy ingestel het.
- As dit misluk, word dit outomaties 'n toegangspunt met die naam
ESP32en wagwoordpassword. - In beide modusse vertoon die opening van die korrekte IP-adres in 'n blaaier dieselfde beheerbladsy vir teks, kleur, rigting en spoed.
Die volledige HTTP-tekskode is beskikbaar onder hierdie artikel (word outomaties op die webwerf gelaai). Vir 'n volledige stap-vir-stap deurloop en 'n lewendige demonstrasie van hoe die teks in reële tyd opdateer, maak seker dat jy die Projek 3-afdeling van die video kyk. As jy die projek self wil bou, kan jy ook die ESP32-S3 RGB LED-matriksmodule koop deur die geaffilieerde skakels wat onder die kode gelys word.
Hierdie handleiding is deel van: ESP32-S3 RGB LED-matriks
- ESP32-S3 RGB LED-matriksprojek 1- Basiese Punt
- ESP32-S3 RGB LED-matriksprojek 2 - Roltelende teks
- ESP32-S3 RGB LED-matriksprojek 4 - Kantelkolletjie
- ESP32-S3 RGB LED-matriksprojek 5 - Pyl altyd op
- ESP32-S3 RGB LED-matriksprojek 6 - Cible-speletjie
- ESP32-S3 RGB LED-matriks Wi-Fi + NTP-tydklokprojek -1 Basiese klok
- ESP32-S3 RGB LED-matriks Internet-klokprojek - 2 Klok multi-kleur Tyd & Datum Vertoning
- ESP32-S3 RGB LED-matriks-internetklokprojek - 3 Nagkleure met Datum
- ESP32-S3 RGB LED-matriks-internetklokprojek - 5 Reënboogkleur
- ESP32-S3 RGB LED-matriks-internetklokprojek - 4 Ewekansige kleure
- ESP32-S3 RGB LED Matrix test for RGB, GRB setting
/*
Project 4: HTTP Text Scroll – ESP32-S3 RGB LED Matrix (Waveshare)
- Connects to your home WiFi (station mode, with AP fallback).
- Serves a web page where you can set:
* Text
* Color
* Display ON/OFF
* Scroll direction (Left / Right / Up / Down)
* Scroll delay (speed)
- Supports 8×8 RGB LED matrix using Adafruit_NeoMatrix.
▶️ Video Tutorial:
https://youtu.be/JKLuYrRcLMI
📄 Resources & Code Page:
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>
// ======================= WIFI SETTINGS =========================
// Home WiFi (change these to your router credentials)
const char* WIFI_SSID = "Biseem";
const char* WIFI_PASS = "wan9&Jang~";
// Fallback Access Point
const char* AP_SSID = "ESP32";
const char* AP_PASS = "password";
// ======================= MATRIX SETTINGS =======================
#define MATRIX_PIN 14
#define MATRIX_WIDTH 8
#define MATRIX_HEIGHT 8
// 0, 1, 2, or 3 – adjust if text orientation is wrong with USB up
#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
);
// ======================= SCROLL STATE ==========================
enum ScrollDir {
DIR_LEFT = 0,
DIR_RIGHT,
DIR_UP,
DIR_DOWN
};
String scrollText = "Robojax";
uint16_t textColor = 0xFFFF; // default white
bool displayOn = true;
ScrollDir currentDir = DIR_LEFT;
// 1 step every this many ms (lower = faster)
unsigned long scrollInterval = 80;
unsigned long lastScrollTime = 0;
// Horizontal scroll position
int scrollX = MATRIX_WIDTH;
int scrollY = 0; // top row
// State for vertical per-letter scroll
int vertCharIndex = 0; // which character of the string
int vertY = MATRIX_HEIGHT; // vertical position of that character
// ======================= WEB SERVER ============================
WebServer server(80);
// ======================= HTML PAGE ============================
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';
});
}
// Set default active
setDir('left');
</script>
</body>
</html>
)rawliteral";
// ======================= HELPERS ===============================
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) {
// Expect "#RRGGBB" or "RRGGBB"
String c = hex;
if (c.startsWith("#")) c.remove(0, 1);
if (c.length() != 6) {
// default white
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; // default font ~6 px per char
int textHeight = 8; // 5x7 font fits in 8
switch (currentDir) {
case DIR_LEFT:
// Start from just outside the right edge
scrollX = MATRIX_WIDTH;
scrollY = 0;
break;
case DIR_RIGHT:
// Start from just outside the left edge
scrollX = -textWidth;
scrollY = 0;
break;
case DIR_UP:
// Per-letter vertical scroll, starting with first character below matrix
vertCharIndex = 0;
vertY = MATRIX_HEIGHT; // 8 → enters from bottom
break;
case DIR_DOWN:
// Per-letter vertical scroll, starting with first character above matrix
vertCharIndex = 0;
vertY = -textHeight; // -8 → enters from top
break;
}
}
// ======================= HTTP HANDLERS =========================
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();
// simple safety clamp
if (val < 10) val = 10; // very fast
if (val > 1000) val = 1000; // 1 second max
scrollInterval = (unsigned long)val;
// Serial.print("Scroll interval set to ");
// Serial.print(scrollInterval);
// Serial.println(" ms");
}
resetScrollPosition();
server.send(200, "text/plain", "Updated");
}
// ======================= SCROLL LOGIC ==========================
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);
// -------- HORIZONTAL SCROLL (LEFT / RIGHT) --------
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_RIGHT
scrollX++;
if (scrollX > MATRIX_WIDTH) {
scrollX = -textWidth;
}
}
return;
}
// -------- VERTICAL SCROLL (UP / DOWN) – PER LETTER --------
if (scrollText.length() == 0) {
matrix.show();
return;
}
// Current character
char c = scrollText[vertCharIndex];
int charWidth = 6;
int baseX = (MATRIX_WIDTH - charWidth) / 2; // center horizontally
matrix.setCursor(baseX, vertY);
matrix.print(c);
matrix.show();
if (currentDir == DIR_UP) {
// Move character upwards
vertY--;
if (vertY < -textHeight) {
// This character is fully passed, go to next
vertY = MATRIX_HEIGHT;
vertCharIndex++;
if (vertCharIndex >= scrollText.length()) {
vertCharIndex = 0; // loop back to first character
}
}
} else if (currentDir == DIR_DOWN) {
// Move character downwards
vertY++;
if (vertY > MATRIX_HEIGHT) {
// This character is fully passed, go to next
vertY = -textHeight;
vertCharIndex++;
if (vertCharIndex >= scrollText.length()) {
vertCharIndex = 0; // loop back
}
}
}
}
// ======================= WIFI INIT =============================
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();
}
}
// ======================= SETUP & LOOP ==========================
void setup() {
Serial.begin(115200);
delay(500);
// Matrix init
matrix.begin();
matrix.setRotation(MATRIX_ROTATION);
matrix.setBrightness(BRIGHTNESS);
matrix.fillScreen(0);
matrix.show();
// WiFi
connectWiFi();
// Web server routes
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();
}
}
Goedere wat jy dalk nodig het
-
Amazon
-
eBay
-
AliExpressPurchase ESP32-S3 RGB matrix from AliExpresss.click.aliexpress.com
-
AliExpressPurchase ESP32-S3 RGB matrix from AliExpress (2)s.click.aliexpress.com
Hulpbronne en verwysings
-
Internaal🎨 Color picker Toolrobojax.com
Lêers📁
Fritzing-lêer
-
esp32-S3-supermini-tht fritzing part
esp32-S3-supermini-tht.fzpz0.02 MB