Ikẹkọ yii jẹ apakan ti: Matrix LED ESP32-S3 RGB
Iṣẹ́ àkànṣe láti ṣẹ̀dá fún àwọn ohun èlò ìgbádùn àti ìwúlò nípa lílo module ESP32-S3 RGB Matrix. Àwọn ìjápọ̀ sí àwọn fídíò mìíràn wà ní ìsàlẹ̀ àpilẹ̀kọ yìí.
Iṣẹ́ ESP32-S3 RGB LED Matrix Project 3 - Ọ̀rọ̀ láti fóónù alágbèéká
Ise 3 – Ṣàkótó Ọ̀rọ̀ Láti Fóònù Rẹ (HTTP Text)
Nínú ise yìí, ESP32-S3 RGB LED Matrix gbàlejò ojú-ojú wẹ́ẹ̀bù kékeré kan kí o lè yí ọ̀rọ̀ tí ń yípo, àwọ̀, ìtọ́sọ́nà, àti ìyára padà taara láti fóònù rẹ tàbí kọ̀ǹpútà rẹ. O kò nílò app ọ̀tọ̀ – wẹ́ẹ̀bù browser nìkan. Èyí jẹ́ kí module náà di ifihan ọ̀rọ̀ Wi-Fi kékeré tí o lè mú ìmúdójúìwọ̀n ní àkókò gidi.
Gbogbo ise mẹ́fà nínú ẹ̀yà yìí ni a ṣàlàyé àti ṣàfihàn nínú fídíò YouTube kan náà. Fídíò kan náà ni a fi sínú ojú-ojú wẹ́ẹ̀bù yìí, kí o lè rí bí ojú-ojú wẹ́ẹ̀bù náà ṣe rí àti bí ọ̀rọ̀ ṣe mú ìmúdójúìwọ̀n lẹ́sẹ̀kẹsẹ̀ lórí matrix. Kódì orísun pátápátá fún ise yìí ni a gbé sílẹ̀ lálẹ́ àpilẹ̀kọ yìí, àti o lè ra module ESP32-S3 RGB LED Matrix láti àwọn ìtàjà affiliate tí a kọ sílẹ̀ lábẹ́ abala kódì.
Nínú àpilẹ̀kọ yìí a fojú sórí bí ìṣiṣẹ́ nẹ́tíwọ́ọ̀kì ṣe ń ṣiṣẹ́ (home Wi-Fi vs access point) àti àwọn ètò wo ni o lè yí padà nínú kódì láti ṣe àtúnṣe ìwà.



Àkópọ̀ Module ESP32-S3 RGB LED Matrix
Ohun èlò náà jẹ́ kanna fún gbogbo àwọn ise mìíràn nínú ẹ̀yà yìí: bọ́ọ̀dù microcontroller ESP32-S3 pẹ̀lú matrix RGB 8×8 tí a kọ́ sínú rẹ̀ àti sensọ ìṣísẹ̀ QMI8658C ní ẹ̀yìn. Ibùdó USB-C ni a lò fún agbára àti siseto, àti àwọn pin ní àyíká etí ni ó ṣì wà fún IO mìíràn.:contentReference[oaicite:0]{index=0}

- ESP32-S3 – microcontroller tí ó ní agbára Wi-Fi àti Bluetooth.
- Matrix RGB 8×8 – 64 LED RGB tí a lè kojú fún ọ̀rọ̀ àti àwòrán.
- Accelerometer QMI8658C – tí a lò nínú àwọn ise tilt àti ere.
- Ibùdó USB – ń fún bọ́ọ̀dù ní agbára àti ń gbé àwọn sketch sílẹ̀ láti Arduino IDE.
- Àwọn pin tí a fòyà – gbà àwọn sensọ tàbí actuators àfikún láyè bí a bá nílò.
- Àwọn bọ̀tìnnì Boot/Reset – fún gbígbé firmware sílẹ̀ àti ìmúbẹ̀rẹ̀ padà.
Fún Ise 3, ẹ̀yà tí ó ṣe pàtàkì jùlọ ni Wi-Fi ESP32, tí ó jẹ́ kí bọ́ọ̀dù náà ṣiṣẹ́ gẹ́gẹ́ bí olùgbàlejò wẹ́ẹ̀bù kékeré fún ojú-ojú ìṣàkóso ọ̀rọ̀.:contentReference[oaicite:1]{index=1}

Àwọn Ise Tí A Bò Nínú Fídíò (Àwọn Àsìkò)
Fídíò kan fún ẹ̀yà yìí bò gbogbo ise mẹ́fà. Fún ìtọ́kasí iyára:
- 00:00 – Ìfáàrà
- 02:01 – Fífi àwọn bọ́ọ̀dù ESP32 sílẹ̀
- 03:32 – Fífi àwọn ilé-ìkàwé sílẹ̀
- 05:32 – Ise 1: Dot Tí ń Gbígbé
- 11:11 – Ise 2: Yíyí Ọ̀rọ̀
- 12:59 – Ise 3: HTTP Text (ise yìí)
- 16:41 – Ise 4: Tilt Dot
- 18:55 – Ise 5: Arrow Up
- 20:02 – Ise 6: Target Game
A gba ọ níyànjú láti wo abala HTTP Text nínú fídíò nígbà tí o ń ṣiṣẹ́ pẹ̀lú àpilẹ̀kọ yìí. Fídíò náà ṣàfihàn bí ESP32 ṣe ń ṣe ojú-ojú wẹ́ẹ̀bù náà àti bí yíyí ọ̀rọ̀, àwọ̀, àti ìyára padà ṣe ń fi ara hàn lẹ́sẹ̀kẹsẹ̀ lórí matrix LED.:contentReference[oaicite:2]{index=2}
Fífi Àwọn Bọ́ọ̀dù ESP32 Sílẹ̀ Nínú Arduino IDE
Bí o bá ti parí Ise 1 tàbí 2 tẹ́lẹ̀, ìṣètò bọ́ọ̀dù ti parí àti o lè fòyà abala yìí. Bí kò bá rí bẹ́ẹ̀, tẹ̀lé àwọn ìgbésẹ̀ wọ̀nyí nínú Arduino IDE:
- Ṣí
File > Preferencesàti fi URL àwọn bọ́ọ̀dù ESP32 sí “Additional Boards Manager URLs”. - Lọ sí
Tools > Board > Boards Manager…, wáESP32, àti fi package ESP32 òfíìsí sílẹ̀. - Yan bọ́ọ̀dù ESP32-S3 RGB Matrix tí ó tọ̀nà láti
Tools > Board. - So module náà pọ̀ nípasẹ̀ USB àti yan ibùdó serial tí ó tọ̀nà lábẹ́
Tools > Port.
Láìsí àtìlẹ́yìn bọ́ọ̀dù ESP32 tí ó tọ̀nà àti ibùdó tí ó tọ̀nà, sketch olùgbàlejò wẹ́ẹ̀bù kò ní gbé sílẹ̀.
Fífi NeoMatrix àti Àwọn Ilé-Ìkàwé Tí A Nílò Sílẹ̀
Ise yìí ń lo àwọn ilé-ìkàwé kanna bí ise yíyí ọ̀rọ̀ tẹ́lẹ̀:
Adafruit NeoMatrixAdafruit NeoPixelAdafruit GFX Library
Fi sílẹ̀ nípasẹ̀ Library Manager:
- Ṣí
Sketch > Include Library > Manage Libraries…. - Wá
Adafruit NeoMatrixàti tẹ Install. - Gbà fífi àwọn ìgbẹ́kẹ̀lé sílẹ̀ (
Adafruit GFXàtiAdafruit NeoPixel).
Nígbà tí a bá ti fi sílẹ̀, o yẹ kí o rí àwọn sketch àpẹẹrẹ NeoMatrix àti NeoPixel lábẹ́ File > Examples.
Àwọn Ọ̀nà Wi-Fi Méjì Nínú Ise 3
Ìròyìn tí ó ṣe pàtàkì jùlọ nínú ise yìí ni pé ESP32 lè ṣiṣẹ́ nínú àwọn ọ̀nà ọ̀tọ̀ọ̀tọ̀ méjì:
- Ọ̀nà Station (STA) – ESP32 ń so pọ̀ mọ́ nẹ́tíwọ́ọ̀kì Wi-Fi ilé rẹ tí ó wà.
- Ọ̀nà Access Point (AP) – ESP32 ń dá nẹ́tíwọ́ọ̀kì Wi-Fi tirẹ̀ bí Wi-Fi ilé kò bá sí.
Àwọn ọ̀nà méjèèjì ń lo ojú-ojú wẹ́ẹ̀bù kanna: ojú-ojú HTML tí ESP32 fúnra rẹ̀ ń pèsè, níbi tí o ti lè yí ọ̀rọ̀, àwọ̀, ìtọ́sọ́nà yíyí, àti ìyára padà.:contentReference[oaicite:3]{index=3}
Ọ̀nà 1 – So pọ̀ mọ́ Wi-Fi Ilé (Ọ̀nà Station)
Nínú ọ̀nà Station, ESP32 ń darapọ̀ mọ́ nẹ́tíwọ́ọ̀kì Wi-Fi ilé tàbí ọ́fíìsì rẹ. Èyí ni ọ̀nà tí a fẹ́ràn nígbàkígbà tí router rẹ bá wà nítorí:
- Fóònù rẹ àti kọ̀ǹpútà rẹ ti so pọ̀ mọ́ nẹ́tíwọ́ọ̀kì Wi-Fi kanna tẹ́lẹ̀.
- O lè tọ́ka browser rẹ sí àdírẹ́sì IP ESP32 àti ṣàkóso ọ̀rọ̀ náà láti ẹ̀yà èyíkéyìí lórí nẹ́tíwọ́ọ̀kì yẹn.
Nínú abala ètò sketch, o pèsè SSID àti ọ̀rọ̀ìpamọ́ Wi-Fi rẹ:
// Awọn iṣẹ́ Wi-Fi ilé (Ipo Ibudo)
const char* WIFI_SSID = "YourHomeWiFi";
const char* WIFI_PASS = "YourHomePassword";
Lẹ́yìn tí bọ́ọ̀dù bá ti bẹ̀rẹ̀, ó máa gbìyànjú láti sopọ̀ mọ́ WIFI_SSID. Bí ó bá yọrí sí rere, kóòdù náà máa tẹ àdírẹ́sì IP tí a fún un jáde sí Serial Monitor, fún àpẹẹrẹ:
Connected to WiFi
IP address: 192.168.1.16
Láti ṣàkóso ọ̀rọ̀ náà:
- Rí i dájú pé fóónù rẹ tàbí PC rẹ ti sopọ̀ mọ́ nẹ́tíwọọkì Wi-Fi kan náà (fún àpẹẹrẹ,
YourHomeWiFi). - Ṣí ẹ̀rọ̀ àwárí kan, kí o sì tẹ àdírẹ́sì IP tí a tẹ́ jáde, bíi
http://192.168.1.16/. - Ojúewé ìṣàkóso náà yóò farahàn, tí yóò jẹ́ kí o tẹ ọ̀rọ̀, yan àwọ̀, yan ìtọ́sọ́nà, àti ṣàtúnṣe ìyára ìyípo.
Ipo 2 – Ààyè Wíwọlé Ní Ìmúdúró (Ipo AP)
Bí ESP32 kò bá lè sopọ̀ mọ́ Wi-Fi ilé rẹ (ọ̀rọ̀ìpàṣẹ̀ tí kò tọ́, nẹ́tíwọọkì tí kò sí, tàbí bí o bá ń lo mọ́jùúlu ní ìta), sketch náà máa padà sí Ipo Ààyè Wíwọlé ní àìdánilójú. Ní Ipo AP, ESP32 fúnra rẹ̀ di ibi gbígbé Wi-Fi pẹ̀lú orúkọ nẹ́tíwọọkì àti ọ̀rọ̀ìpàṣẹ̀ tirẹ̀.
Nínú iṣẹ́ yìí, àwọn ètò AP jẹ́ àmúlò gẹ́gẹ́ bí:
// Awọn iṣẹ́ Ààyè Wíwọlé (AP) (ipo ìpadàbọ̀)
const char* AP_SSID = "ESP32";
const char* AP_PASS = "password";
Nígbà tí Ipo Ibudo bá kùnà, mọ́jùúlu náà yí padà sí Ipo AP, ó sì bẹ̀rẹ̀ sí í tan nẹ́tíwọọkì Wi-Fi kan tí a ń pè ní ESP32. Láti ṣàkóso matrix náà:
- Lórí fóónù tàbí kọ̀ǹpútà rẹ, ṣí àwọn ètò Wi-Fi, kí o sì sopọ̀ mọ́ nẹ́tíwọọkì ESP32.
- Tẹ ọ̀rọ̀ìpàṣẹ̀ password (gẹ́gẹ́ bí a ti ṣàlàyé rẹ̀ nínú kóòdù).
- Lẹ́yìn tí o bá ti sopọ̀, ṣí ẹ̀rọ̀ àwárí kan, kí o sì lọ sí
http://192.168.4.1/(IP àìtọ́wọ̀nà fún Ipo AP ESP32). - Ojúewé ìṣàkóso kan náà yóò farahàn, tí yóò jẹ́ kí o yí ọ̀rọ̀, àwọ̀, ìyára, àti ìtọ́sọ́nà padà.
Ìwà ìpadàbọ̀ yìí jẹ́ kí iṣẹ́ náà wúlò ní ibikíbi: ní ilé, ní yàrá-ìwádìí, tàbí ní àyíká àfihàn níbi tí kò sí router.
Iṣẹ́ 3 – Àwọn Ètò Pàtàkì Nínú Kóòdù
Sketch Ọ̀rọ̀ HTTP kíkún ni a gbé sílẹ̀ nísàlẹ̀ àpilẹ̀kọ yìí nípasẹ̀ ojú òpó wẹ́ẹ̀bù. Níhìn-ín, a ṣe àkọsílẹ̀ àwọn àṣàyàn ìṣàtúnṣe tí ó ṣe pàtàkì jùlọ tí o lè ṣàtúnṣe.
Àwọn Ètò Wi-Fi àti Ààyè Wíwọlé
Ní ìbẹ̀rẹ̀ sketch náà, o yóò rí abala ìṣàtúnṣe Wi-Fi. Ọ̀wọ́n àwọn iṣẹ́ Ibudo (Wi-Fi ilé) ni o yẹ kí o yí padà; àwọn ètò AP ni a máa ń pa mọ́ gẹ́gẹ́ bí àìtọ́wọ̀nà:
// ---------- ÀWỌN ÈTÒ WI-FI ----------
// Wi-Fi ilé (Ipo Ibudo)
const char* WIFI_SSID = "YourHomeWiFi"; // fi SSID router rẹ síbẹ̀
const char* WIFI_PASS = "YourHomePassword"; // fi ọ̀rọ̀ìpàṣẹ̀ router rẹ síbẹ̀
// Ààyè Wíwọlé Ìpadàbọ̀ (Ipo AP)
const char* AP_SSID = "ESP32"; // orúkọ AP àmúlò
const char* AP_PASS = "password"; // ọ̀rọ̀ìpàṣẹ̀ AP àmúlò
Ìwà:
- Bí
WIFI_SSIDàtiWIFI_PASSbá tọ́, tí nẹ́tíwọọkì náà sì wà → ESP32 sopọ̀ gẹ́gẹ́ bí ẹ̀rọ̀ Wi-Fi tí ó wà nípò déédé (Ipo Ibudo). - Bí ìsopọ̀ bá kùnà lẹ́yìn àkókò kan → ESP32 bẹ̀rẹ̀ AP tirẹ̀ ní lílo
AP_SSIDàtiAP_PASS.
Pin Matrix, Ìwọ̀n, àti Ìmọ́lẹ̀
Àwọn ètò wọ̀nyí jẹ́ kanna pẹ̀lú àwọn iṣẹ́ tí ó ti kọjá:
// Ìṣàtúnṣe Matrix
const int MATRIX_PIN = 14; // pin data matrix RGB
const int MATRIX_WIDTH = 8;
const int MATRIX_HEIGHT = 8;
// Ìmọ́lẹ̀ àfihàn gbogbogbò (0–255)
uint8_t matrixBrightness = 40; // ṣàtúnṣe fún àyíká rẹ
Pa MATRIX_PIN mọ́ ní 14 fún bọ́ọ̀dù yìí. O lè pọ̀ sí i matrixBrightness bí o bá nílò ìmọ́lẹ̀ púpọ̀ sí i, ṣùgbọ́n àwọn iye tí ó kéré sí i dára fún wíwo ní àrọ́wọ́tó.
Ọ̀rọ̀ Àìtọ́wọ̀nà àti Àwọn Ètò Ìyípo
Nígbà tí bọ́ọ̀dù bá bẹ̀rẹ̀, ó máa fi ọ̀rọ̀ ìbẹ̀rẹ̀ kan hàn títí tí o fi ṣí ojúewé wẹ́ẹ̀bù kí o sì tẹ ọ̀rọ̀ tuntun kan. O lè yí ọ̀rọ̀ àìtọ́wọ̀nà padà nínú ìṣàtúnṣe:
// Ọ̀rọ̀ àìtọ́wọ̀nà tí a fi hàn ní ìbẹ̀rẹ̀
String currentText = "Robojax"; // a máa kọ ọ́ lẹ́yìn láti ojúewé wẹ́ẹ̀bù
Ìyókù ìwà ìyípo ni a ń ṣàkóso nípasẹ̀ àwọn oniyipada kan tí ojú òpó wẹ́ẹ̀bù ń mú ìmúdójúìwọ̀n wá:
// Ìdádúró ìyípo ní milliseconds (kéré = yára)
int scrollDelayMs = 50;
// Ìtọ́sọ́nà ìyípo: 0=òsì, 1=ọ̀tún, 2=ókè, 3=ìsàlẹ̀
int scrollDirection = 0; // àìtọ́wọ̀nà: yípo sí òsì
Ojúewé wẹ́ẹ̀bù náà máa fi àwọn iye tuntun ránṣẹ́ nípa lílo àṣàyàn slider àti bọ̀tìnnì. Láti ẹ̀gbẹ́ Arduino, o nílò láti mọ̀ pé:
- Dídín
scrollDelayMskù máa jẹ́ kí ọ̀rọ̀ náà yára lọ. - Pípọ̀ sí i
scrollDelayMsmáa jẹ́ kí ó lọra. - Yíyí
scrollDirectionpadà máa yí láàárín àwọn ipo ìyípo òsì, ọ̀tún, òkè, tàbí ìsàlẹ̀.
Àwọ̀ Ọ̀rọ̀ (Tí Ojúewé Wẹ́ẹ̀bù Ń Ṣàkóso)
A ń ṣàkóso àwọ̀ ọ̀rọ̀ náà nípasẹ̀ àwọn iye 0–255 mẹ́ta (pupa, aláwọ̀ ewé, bulúù). A máa ń mú wọn ìmúdójúìwọ̀n wá nígbàkigbà tí o bá yan àwọ̀ tuntun kan lórí ojúewé wẹ́ẹ̀bù:
// Àwọ̀ ọ̀rọ̀ lọ́wọ́lọ́wọ́ (R, G, B)
uint8_t textRed = 255;
uint8_t textGreen = 255;
uint8_t textBlue = 255;
Nígbà tí o bá yan àwọ̀ kan nínú ẹ̀rọ̀ àwárí, kí o sì tẹ Apply, ESP32 máa ṣe àtúpalẹ̀ àwọn iye RGB, ó sì máa mú àwọn oniyipada mẹ́tẹ̀ẹ̀ta wọ̀nyí ìmúdójúìwọ̀n wá; ọ̀rọ̀ náà yóò yí àwọ̀ padà lẹ́sẹ̀kẹsẹ̀ lórí matrix. Nínú fídíò náà, a fi ìwà yìí hàn pẹ̀lú ọ̀pọ̀lọpọ̀ àwọn ìyípadà àwọ̀, pẹ̀lú àwọn àpẹẹrẹ pupa, aláwọ̀ ewé, àti bulúù.
Àkópọ̀
Iṣẹ́ 3 yí ESP32-S3 RGB LED Matrix rẹ padà sí àfihàn ọ̀rọ̀ aláìlókùn-ún tí o lè ṣàkóso ní lílo ẹ̀rọ̀ èyíkéyìí tí ó ní ẹ̀rọ̀ àwárí wẹ́ẹ̀bù. A ṣe sketch náà láti jẹ́ alágbára:
- Ó̩kọ́kọ́ ó máa gbìyànjú láti sopọ̀ mọ́ Wi-Fi ilé rẹ nípa lílo SSID àti ọ̀rọ̀ìpamọ́ tí o ṣètò.
- Bí ìyẹn bá kùnà, ó máa di ibi ìwọ̀nwọ̀n fúnra rẹ̀ pẹ̀lú orúkọ
ESP32àti ọ̀rọ̀ìpamọ́password. - Nínú àwọn ọ̀nà méjèèjì, ṣíṣí àdírẹ́sì IP tí ó tọ́ nínú ẹ̀rọ̀ aṣàwákiri yóò fi ojú-ìwé ìṣàkóso kan náà hàn fún ọ̀rọ̀, àwọ̀, ìtọ́sọ́nà, àti ìyára.
Kódì HTTP Ọ̀rọ̀ tí ó pé ni wà ní ìsàlẹ̀ àpilẹ̀kọ yìí (tí a kọ́já lọ́nà àdánidá lórí ojú-ìkànná). Fún ìṣàlàyé àtẹ̀sẹ̀wọ̀n kíkún àti ìfihàn ààyè kan tí ó fi bí ọ̀rọ̀ ṣe ń yí padà ní àkókò gidi, rí i pé o wo apá Project 3 nínú fídíò náà. Bí o bá fẹ́ kọ́ iṣẹ́ náà fúnra rẹ, o tún lè ra módúúlù ESP32-S3 RGB LED Matrix nípa lílo àwọn ọ̀já-ìsopọ̀ tí a kọ sí ìsàlẹ̀ kódì náà.
Ikẹkọ yii jẹ apakan ti: Matrix LED ESP32-S3 RGB
- Iṣẹ́ ESP32-S3 RGB LED Matrix 1- Àmì-ojú ìpilẹ̀ṣẹ̀
- Iṣẹ́ ESP32-S3 RGB LED Matrix Project 2 - Ọ̀rọ̀ Tí Ń Rìn
- Iṣẹ́ ESP32-S3 RGB LED Matrix Project 4 - Tilt dot
- Iṣẹ́ ESP32-S3 RGB LED Matrix Project 5 - Ọfà tí ó máa ń tọ́ka sí òkè nígbà gbogbo
- Iṣẹ́ ESP32-S3 RGB LED Matrix Project 6 - Ere Cible
- Iṣẹ́ Aago ESP32-S3 RGB LED Matrix Wi-Fi + NTP - 1 Aago Ìpìlẹ̀
- Iṣẹ́ Aago Internet Matrix LED RGB ESP32-S3 - Àfihàn Aago àti Ọjọ́ ní Àwọ̀ púpọ̀ 2
- Iṣẹ́ Aago Internet Matrix LED RGB ESP32-S3 - Àwọ̀ Alẹ́ 3 pẹ̀lú Ọjọ́
- Iṣẹ́ Aago Internet Matrix LED RGB ESP32-S3 - Àwọ̀ Òṣùwọ̀n 5
- Iṣẹ́ Aago Nẹ́tíwọọkì ESP32-S3 RGB LED Matrix - Àwọ̀ àìròtẹ́lẹ̀ mẹ́rin
- 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();
}
}
Ohun ti o le nilo
-
Amazon
-
eBay
-
AliExpressPurchase ESP32-S3 RGB matrix from AliExpresss.click.aliexpress.com
-
AliExpressPurchase ESP32-S3 RGB matrix from AliExpress (2)s.click.aliexpress.com
Orisun & itọkasi
-
Ináàbò🎨 Color picker Toolrobojax.com
Fáìlìs📁
Fayile Fritzing
-
esp32-S3-supermini-tht fritzing apakan
esp32-S3-supermini-tht.fzpz0.02 MB