Casharradan waa qayb ka mid ah: Matrix-ka LED-ka ee ESP32-S3 RGB
Mashruuc xiiso leh oo loogu talagalay in lagu abuuro barnaamijyo xiiso leh oo wax ku ool ah iyadoo la adeegsanayo moduleka ESP32-S3 RGB Matrix. Xiriirinta fiidiyowyada kale waxay ku yaalliin maqaalkan.
Mashruuca ESP32-S3 RGB LED Matrix Project 3 - Qoraal ka yimid taleefanka gacanta
Mashruuc 3 – Xakamaynta Qoraalka Matrix-ka Taleefankaaga (HTTP Text)
Mashruucan, ESP32-S3 RGB LED Matrix wuxuu martigeliyaa bog yar oo web ah si aad u beddesho qoraalka wareegaya, midabka, jihada, iyo xawaaraha si toos ah taleefankaaga ama kombiyuutarkaaga. Uma baahnid app gaar ah – kaliya browser web. Tani waxay ka dhigaysaa qalabkan bandhig qoraal oo Wi-Fi yar oo aad cusboonaysiin karto waqti toos ah.
Dhammaan lixda mashruuc ee taxanahan waxaa lagu sharaxay oo lagu muujiyay hal fiidiyow oo YouTube ah. Isla fiidiyowga ayaa ku dhex jira boggan, si aad si sax ah u aragto sida web interface-ka u eg yahay iyo sida qoraalka isla markiiba ugu cusboonaado matrix-ka. Koodhka buuxa ee mashruucan waxaa si toos ah loogu shubay hoosta maqaalka, waxaadna ka iibsan kartaa qalabka ESP32-S3 RGB LED Matrix dukaamada la xidhiidha ee ku qoran hoosta qaybta koodhka.
Maqaalkan waxaan diiradda saareynaa sida logic-ga shabakadu u shaqeeyo (Wi-Fi guriga vs access point) iyo goorma aad ku beddeli karto koodhka si aad u qaabayso hab-dhaqanka.



Guudmarka Qalabka ESP32-S3 RGB LED Matrix
Qalabku wuxuu la mid yahay dhammaan mashruucyada kale ee taxanahan: guddiga microcontroller-ka ESP32-S3 oo leh matrix RGB 8×8 oo ku dhex dhisan iyo sensor dhaqdhaqaaqa QMI8658C oo dhabarka ku yaal. Dekadda USB-C waxaa loo isticmaalaa koronto iyo barnaamijyada, biinanka ku wareegsan cidhifyada ayaa weli diyaar u ah IO kale.:contentReference[oaicite:0]{index=0}

- ESP32-S3 – microcontroller Wi-Fi iyo Bluetooth awood u leh.
- Matrix RGB 8×8 – 64 LED RGB oo la xakameyn karo oo loogu talagalay qoraal iyo sawirro.
- Accelerometer QMI8658C – loo isticmaalo mashruucyada leexinta iyo ciyaaraha.
- Dekadda USB – koronto siisaa guddiga oo soo galiyaa sketches-ka Arduino IDE.
- Biinanka la soo bandhigay – waxay u oggolaadaan sensorro ama actuators dheeri ah haddii loo baahdo.
- Badhamada Boot/Reset – loogu talagalay soo gelinta firmware-ka iyo dib u bilowga.
Mashruuca 3, sifada ugu muhiimsan waa Wi-Fi-ga ESP32, kaas oo u oggolaanaya guddiga inuu u shaqeeyo sidii server web yar oo loogu talagalay bogga xakamaynta qoraalka.:contentReference[oaicite:1]{index=1}

Mashruucyada Ku Qoran Fiidiyowga (Waqtiyada)
Hal fiidiyow oo taxanahan ah ayaa daboolaya dhammaan lixda mashruuc. Tixraac degdeg ah:
- 00:00 – Hordhac
- 02:01 – Rakibidda guddiyada ESP32
- 03:32 – Rakibidda maktabadaha
- 05:32 – Mashruuca 1: Dhibicda Dhaqaaqaysa
- 11:11 – Mashruuca 2: Wareegga Qoraalka
- 12:59 – Mashruuca 3: HTTP Text (mashruucan)
- 16:41 – Mashruuca 4: Dhibicda Leexinta
- 18:55 – Mashruuca 5: Fallaro Kor
- 20:02 – Mashruuca 6: Ciyaarta Bartilmaameedka
Waxaa lagu dhiirigelinayaa inaad daawato qaybta HTTP Text ee fiidiyowga inta aad la shaqeyneysay maqaalkan. Fiidiyowgu wuxuu muujinayaa sida bogga web-ka uu u soo saaro ESP32 iyo sida beddelka qoraalka, midabka, iyo xawaaraha isla markiiba looga tarjumayo LED matrix-ka.:contentReference[oaicite:2]{index=2}
Rakibidda Guddiyada ESP32 ee Arduino IDE
Haddii aad horey u dhammeysatay Mashruucyada 1 ama 2, dejinta guddiga waa la dhammeeyay waxaadna ka gudbi kartaa qaybtan. Haddii kale, raac tillaabooyinkan Arduino IDE:
- Fur
File > Preferencesoo ku dar URL-ka guddiyada ESP32 ee “Additional Boards Manager URLs”. - Tag
Tools > Board > Boards Manager…, raadiESP32, oo rakib xirmada rasmiga ah ee ESP32. - Dooro guddiga saxda ah ee ESP32-S3 RGB Matrix ee
Tools > Board. - Ku xir qalabka USB-ga oo dooro dekedda saxda ah ee
Tools > Port.
Haddii aan la helin taageerada saxda ah ee guddiga ESP32 iyo dekedda saxda ah, sketch-ka web-server-ku ma soo geli doono.
Rakibidda NeoMatrix iyo Maktabadaha Loo Baahan Yahay
Mashruucan wuxuu isticmaalaa isla maktabadihii mashruucii hore ee wareegga qoraalka:
Adafruit NeoMatrixAdafruit NeoPixelAdafruit GFX Library
Ku rakib Manager-ka Maktabadda:
- Fur
Sketch > Include Library > Manage Libraries…. - Raadi
Adafruit NeoMatrixoo guji Install. - Aqbal rakibidda ku-tiirsanaanta (
Adafruit GFXiyoAdafruit NeoPixel).
Marka la rakibo, waa inaad ku aragtaa tusaalooyinka NeoMatrix iyo NeoPixel ee hoos yimaada File > Examples.
Laba Hab oo Wi-Fi ah ee Mashruuca 3
Fikradda ugu muhiimsan ee mashruucan waa in ESP32 uu ku shaqeyn karo laba hab oo kala duwan:
- Habka Station (STA) – ESP32 wuxuu ku xidhmaa shabakadda Wi-Fi-ga ee gurigaaga ee jirta.
- Habka Access Point (AP) – ESP32 wuxuu abuuraa shabakad Wi-Fi oo u gaar ah haddii Wi-Fi guriga uusan diyaar ahayn.
Labada hab waxay isticmaalaan isla web interface-ka: bog HTML ah oo laga soo saaro ESP32 laftiisa, halkaas oo aad ku beddeli karto qoraalka, midabka, jihada wareegga, iyo xawaaraha.:contentReference[oaicite:3]{index=3}
Habka 1 – Ku Xidhnaanshaha Wi-Fi Guriga (Habka Station)
Habka Station, ESP32 wuxuu ku biiraa shabakadda Wi-Fi-ga guriga ama xafiiskaaga. Kani waa habka la doorbido marka router-kaagu uu diyaar yahay sababtoo ah:
- Taleefankaaga iyo kombiyuutarkaagu waxay horey ugu xidhnaayeen isla shabakadda Wi-Fi-ga.
- Waxaad tilmaami kartaa browser-kaaga cinwaanka IP-ga ee ESP32 oo waxaad ka xakameyn kartaa qoraalka qalab kasta oo ku yaal shabakaddaas.
Qaybta dejinta ee sketch-ka, waxaad siisaa SSID-ka Wi-Fi-gaaga iyo erayga sirta ah:
Guriga Wi-Fi credentials-ka (Qaabka Station) const char* WIFI_SSID = "WiFi-gurigaaga"; const char* WIFI_PASS = "Password-ka-gurigaaga"; Marka board-ku uu boot-garo, wuxuu isku dayaa inuu ku xirmo WIFI_SSID. Haddii uu ku guuleysto, koodhku wuxuu daabacaa cinwaanka IP-ga ee loo qoondeeyay Serial Monitor-ka, tusaale ahaan: Connected to WiFi IP address: 192.168.1.16 Si aad u xakamayso qoraalka: 1. Hubi in taleefankaaga ama PC-gaagu uu ku xiran yahay isku shabakadda Wi-Fi-ga (tusaale ahaan, YourHomeWiFi). 2. Fur browser-ka oo geli cinwaanka IP-ga ee la daabacay, sida http://192.168.1.16/. 3. Bogga xakamaynta ayaa soo bixi doona, isagoo kuu oggolaanaya inaad ku qorto qoraal, doorato midab, doorato jihada, oo aad hagaajiso xawaaraha is-dhaafista. Qaabka 2 – Access Point Madaxbanaan (Qaabka AP) Haddii ESP32-ga uu awoodi waayo inuu ku xirmo Wi-Fi-gaaga guriga (password khaldan, shabakad aan la heli karin, ama aad isticmaalayso module-ka dibadda), sketch-ku wuxuu si toos ah ugu dhacaa Qaabka Access Point. Qaabka AP, ESP32-ga laftiisu wuxuu noqdaa hotspot Wi-Fi ah oo leh magaciisa shabakadeed iyo password-kiisa. Mashruucan, dejinta AP-ga waxay u go'an tahay sida: // Access Point (AP) credentials-ka (qaabka fallback) const char* AP_SSID = "ESP32"; const char* AP_PASS = "password"; Marka Qaabka Station uu guuldareysto, module-ku wuxuu u beddelaa Qaabka AP wuxuuna bilaabaa inuu baahiyo shabakad Wi-Fi ah oo la yiraahdo ESP32. Si aad u xakamayso matrix-ka: 1. Taleefankaaga ama kombuyuutarkaaga, fur dejinta Wi-Fi-ga oo ku xir shabakadda ESP32. 2. Geli password-ka password (sida lagu qeexay koodhka). 3. Markaad ku xiranto, fur browser-ka oo aad http://192.168.4.1/ (IP-ga caadiga ah ee Qaabka AP ee ESP32). 4. Isla bogga xakamaynta ayaa soo baxaya, isagoo kuu oggolaanaya inaad beddesho qoraalka, midabka, xawaaraha, iyo jihada. Dhaqankan fallback-ka ah wuxuu mashruuca ka dhigayaa mid waxtar leh meel kasta: guriga, shaybaarka, ama jawi demo ah oo aan router la heli karin. Mashruuca 3 – Dejinta Muhiimka ah ee Koodhka Sketch-ka HTTP Text ee buuxa waxaa hoos ku shubay website-ku maqaalkan. Halkan waxaanu dokumentaynaa kaliya doorashooyinka qaabaynta ee ugu muhiimsan ee aad u badan tahay inaad wax ka beddesho. Dejinta Wi-Fi iyo Access Point Dusha sketch-ka waxaad ka heli doontaa qaybta qaabaynta Wi-Fi. Kaliya beddel credentials-ka Station (Wi-Fi guriga); dejinta AP-ga waxaa caadi ahaan loo hayaa sida default-ka: // ---------- DEJINTA WI-FI ---------- // Wi-Fi guriga (Qaabka Station) const char* WIFI_SSID = "YourHomeWiFi"; // halkan ku qor SSID-ka router-kaaga const char* WIFI_PASS = "YourHomePassword"; // halkan ku qor password-ka router-kaaga // Fallback Access Point (Qaabka AP) const char* AP_SSID = "ESP32"; // magaca AP-ga go'an const char* AP_PASS = "password"; // password-ka AP-ga go'an Dhaqanka: - Haddii WIFI_SSID iyo WIFI_PASS ay sax yihiin oo shabakaddu ay jirto → ESP32 wuxuu ku xirmaa sidii qalab Wi-Fi caadi ah (Qaabka Station). - Haddii xiriirku uu guuldareysto ka dib waqti-go'an → ESP32 wuxuu bilaabaa AP-ga u gaarka ah isagoo isticmaalaya AP_SSID iyo AP_PASS. Pin-ka Matrix-ka, Cabbirka, iyo Iftiinka Dejintan waxay la mid tahay mashruucyadii hore: // Qaabaynta Matrix-ka const int MATRIX_PIN = 14; // pin-ka xogta ee RGB matrix const int MATRIX_WIDTH = 8; const int MATRIX_HEIGHT = 8; // Iftiinka guud ee bandhigga (0–255) uint8_t matrixBrightness = 40; // ku hagaaji deegaankaaga Ku hay MATRIX_PIN at 14 board-gan. Waxaad kordhin kartaa matrixBrightness haddii aad u baahan tahay iftiin dheeri ah, laakiin qiimayaasha hoose ayaa ku habboon daawashada dhow. Qoraalka Caadiga ah iyo Dejinta Is-dhaafista Marka board-ku uu bilaabmo, wuxuu soo bandhigayaa farriin bilow ah ilaa aad furto bogga web-ka oo aad ku qorto mid cusub. Waxaad beddeli kartaa qoraalka caadiga ah ee qaabaynta: // Farriinta caadiga ah ee lagu muujiyo bilowga String currentText = "Robojax"; // waxaa laga beddeli karaa web UI-ga markii dambe Inta ka hartay dhaqanka is-dhaafista waxaa xakameeya doorsoomayaal ay cusboonaysiiso interface-ka web-ka: // Dib u dhaca is-dhaafista ee milliseken (hoose = ka dhakhso badan) int scrollDelayMs = 50; // Jihada is-dhaafista: 0=bidix, 1=midig, 2=kor, 3=hoos int scrollDirection = 0; // default: u is-dhaaf bidix Bogga web-ku wuxuu soo diraa qiimayaal cusub oo ku salaysan slider-ka iyo doorashooyinka badhanka. Dhinaca Arduino-ga, kaliya waxaad u baahan tahay inaad ogaato in: - Hoos u dhaca scrollDelayMs wuxuu qoraalka ka dhigayaa mid si dhakhso leh u dhaqaaqa. - Kordhinta scrollDelayMs wuxuu ka dhigayaa mid si gaabis ah u dhaqaaqa. - Beddelka scrollDirection wuxuu u beddelaa bidix, midig, kor, ama hoos. Midabka Qoraalka (Waxaa Xakameeya Bogga Web-ka) Midabka qoraalka waxaa xakameeya saddex qiime oo 0–255 ah (guduud, cagaar, buluug). Waxaa la cusboonaysiiyaa mar kasta oo aad doorato midab cusub oo ku yaal bogga web-ka: // Midabka qoraalka hadda (R, G, B) uint8_t textRed = 255; uint8_t textGreen = 255; uint8_t textBlue = 255; Markaad doorato midab browser-ka oo aad gujiso Apply, ESP32-ga wuxuu falanqeeyaa qiimayaasha RGB wuxuuna cusboonaysiiyaa saddexda doorsoome; qoraalku isla markiiba wuxuu beddelaa midabka matrix-ka. Fiidiyowga, dhaqankan waxaa lagu muujiyay beddello midab oo badan, oo ay ku jiraan tusaalooyin guduud, cagaar, iyo buluug. Soo Koobid Mashruuca 3 wuxuu ESP32-S3 RGB LED Matrix-kaaga u beddelaa bandhig qoraal oo si buuxda wireless ah oo aad ku xakameyn karto adigoo isticmaalaya qalab kasta oo leh browser web ah. Sketch-ku waxaa loo qaabeeyey inuu ahaado mid adag:- Waxa uu marka hore isku dayaa in uu ku xidhmao Wi-Fi-gaaga guriga isagoo isticmaalaya SSID-ka iyo erayga sirta ah ee aad qaawisay.
- Haddii taas guuldareysato, si otomaatig ah wuxuu u noqdaa barta gelitaanka oo magaceedu yahay
ESP32iyo erayga sirta ahpassword. - Labada qaabba, furista cinwaanka IP-ga saxda ah ee browser-ka waxay muujinaysaa bogga xakamaynta isku midka ah ee qoraalka, midabka, jihada, iyo xawaaraha.
Koodhka HTTP Text ee dhammaystiran ayaa ka hoos yaal maqaalkan (si otomaatig ah ayaa lagu shubaa websaydhka). Si aad u hesho tallaabo-tallaabo buuxda iyo muujin toos ah oo ku saabsan sida qoraalku ugu cusboonaado waqtiga dhabta ah, hubi inaad daawato qaybta Mashruuca 3 ee fiidiyowga. Haddii aad rabto inaad adigu dhisto mashruuca, waxaad sidoo kale iibsan kartaa qalabka ESP32-S3 RGB LED Matrix adigoo isticmaalaya xiriiriyeyaasha la xidhiidha ee hoos ku qoran koodhka.
Casharradan waa qayb ka mid ah: Matrix-ka LED-ka ee ESP32-S3 RGB
- Mashruuca LED Matrix-ka RGB ee ESP32-S3 1- Dhibic Aasaasi ah
- Mashruuca LED Matrix RGB ee ESP32-S3 2 - Qoraal Guurguura
- Mashruuca LED Matrix RGB ee ESP32-S3 4 - Dhibicda leexinta
- Mashruuca Matrix-ka LED-ka RGB ee ESP32-S3 5 - Fallaar had iyo jeer kor u taagan
- Mashruuca LED Matrix RGB ee ESP32-S3 6 - Ciyaarta Cible
- Mashruucda Saacadda NTP + Wi-Fi Matrix LED RGB ee ESP32-S3 -1 Saacad Aasaasi ah
- Mashruuca Saacadda Shabakadda ee ESP32-S3 RGB LED Matrix - 2 Saacadood oo midabbo kala duwan leh oo Muujinaya Waqtiga & Taariikhda
- Mashruuca Saacadda Shabakadda ee LED Matrix RGB ee ESP32-S3 - 3 Midab Habeen ah oo leh Taariikh
- Mashruuca Saacadda Shabakadda LED Matrix RGB ee ESP32-S3 - 5 Midabka Qaanso Roobaadka
- Mashruuca Saacadda Shabakadda ee ESP32-S3 RGB LED Matrix - 4 Midab oo Random ah
- 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();
}
}
Waad u baahan tahay
-
Amaazon
-
eBay
-
AliExpressPurchase ESP32-S3 RGB matrix from AliExpresss.click.aliexpress.com
-
AliExpressPurchase ESP32-S3 RGB matrix from AliExpress (2)s.click.aliexpress.com
Kheyraadka & Tixraacyada
-
Gudaha🎨 Color picker Toolrobojax.com
Faylasha📁
Faylka Fritzing
-
esp32-S3-supermini-tht fritzing part
esp32-S3-supermini-tht.fzpz0.02 MB