Trong hướng dẫn này, chúng ta sẽ học cách điều khiển bảng hiển thị LED matrix qua giao diện web bằng ESP32. Cụ thể, chúng ta sẽ lập trình ESP32 thành một web server thực hiện các chức năng sau:
Trả về giao diện web cho người dùng khi nhận được yêu cầu từ trình duyệt web.
Cung cấp giao diện web cho phép người dùng gửi tin nhắn đến ESP32
Hiển thị tin nhắn trên LED matrix khi nhận được tin nhắn.
Tiết lộ: Một số liên kết trong bài viết này là liên kết tiếp thị Amazon và có thể nhận hoa hồng theo chính sách của chương trình.
Về LED Matrix và Web Server
Chúng ta có thể sử dụng HTTP thuần túy để gửi văn bản từ giao diện web đến ESP32. Tuy nhiên, sử dụng WebSocket giúp giao diện phản hồi nhanh hơn và không làm tăng độ phức tạp nhiều, vì vậy trong hướng dẫn này, chúng ta sẽ sử dụng WebSocket.
Chưa quen với LED Matrix, Web Server và WebSocket, bao gồm sơ đồ chân, chức năng và lập trình? Hãy khám phá các hướng dẫn toàn diện về những chủ đề này bên dưới:
Kết nối board ESP32 với máy tính của bạn qua cáp micro USB
Mở Arduino IDE trên máy tính.
Chọn đúng board ESP32 (ví dụ: ESP32 Dev Module) và cổng COM.
Mở Library Manager bằng cách click vào biểu tượng Library Manager trên thanh điều hướng bên trái của Arduino IDE.
Tìm kiếm "DIYables ESP32 WebServer", sau đó tìm thư viện Web Server được tạo bởi DIYables.
Click nút Install để cài đặt thư viện Web Server.
Tìm kiếm "MD_Parola", sau đó tìm thư viện MD_Parola
Click nút Install.
Bạn sẽ được hỏi có muốn cài đặt thư viện "MD_MAX72XX"
Click nút Install All để cài đặt thư viện phụ thuộc.
Trên Arduino IDE, tạo sketch mới, đặt tên cho nó, ví dụ: newbiely.com.ino
Copy đoạn code dưới đây và mở với Arduino IDE
/* * Mã ESP32 này được phát triển bởi newbiely.vn * Mã ESP32 này được cung cấp để sử dụng công khai, không có ràng buộc. * Để xem hướng dẫn chi tiết và sơ đồ kết nối, vui lòng truy cập: * https://newbiely.vn/tutorials/esp32/esp32-led-matrix-via-web */#include <DIYables_ESP32_WebServer.h>#include"index.h"#include <MD_Parola.h>#include <MD_MAX72xx.h>#define HARDWARE_TYPE MD_MAX72XX::FC16_HW#define MAX_DEVICES 4 // 4 blocks#define CS_PIN 21 // ESP32 pin GPIO21// WiFi credentialsconstchar WIFI_SSID[] = "YOUR_WIFI_SSID";constchar WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";// Create web server instanceDIYables_ESP32_WebServer server;DIYables_ESP32_WebSocket* webSocket;// create an instance of the MD_Parola classMD_Parola ledMatrix = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);// Web Page handlersvoid handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { server.sendResponse(client, HTML_CONTENT);}// WebSocket event handlersvoid onWebSocketOpen(net::WebSocket& ws) {Serial.println("New WebSocket connection");// Send welcome messageconstchar welcome[] = "Connected to ESP32 WebSocket Server!";}void onWebSocketMessage(net::WebSocket& ws, const net::WebSocket::DataType dataType, const char* message, uint16_tlength) {Serial.print("WebSocket Received (");Serial.print(length);Serial.print(" bytes): ");Serial.println(message); ledMatrix.displayClear(); // clear led matrix display ledMatrix.displayScroll(message, PA_CENTER, PA_SCROLL_LEFT, 100);// Broadcast response to all connected clients using the libraryif (webSocket != nullptr) {String response = "Displayed: " + String(message) + "on LED Matrix"; webSocket->broadcastTXT(response);Serial.print("WebSocket sent (");Serial.print(response.length());Serial.print(" bytes): ");Serial.println(response); }}void onWebSocketClose(net::WebSocket& ws, const net::WebSocket::CloseCode code, const char* reason, uint16_tlength) {Serial.println("WebSocket client disconnected");}voidsetup() {Serial.begin(9600);delay(1000);Serial.println("ESP32 Web Server and WebSocket Server"); ledMatrix.begin(); // initialize the object ledMatrix.setIntensity(15); // set the brightness of the LED matrix display (from 0 to 15) ledMatrix.displayClear(); // clear led matrix display ledMatrix.displayScroll("esp32io.com", PA_CENTER, PA_SCROLL_LEFT, 100);// Configure web server routes server.addRoute("/", handleHome);// Start web server with WiFi connection server.begin(WIFI_SSID, WIFI_PASSWORD);// Enable WebSocket functionality webSocket = server.enableWebSocket(81);if (webSocket != nullptr) {// Set up WebSocket event handlers webSocket->onOpen(onWebSocketOpen); webSocket->onMessage(onWebSocketMessage); webSocket->onClose(onWebSocketClose); } else {Serial.println("Failed to start WebSocket server"); }}voidloop() {// Then handle HTTP requests server.handleClient();// Handle WebSocket server.handleWebSocket();if (ledMatrix.displayAnimate()) { ledMatrix.displayReset(); }}
Tạo file index.h trong Arduino IDE bằng cách:
Click vào nút ngay bên dưới biểu tượng serial monitor và chọn New Tab, hoặc sử dụng phím Ctrl+Shift+N.
Đặt tên file là index.h và click nút OK
Copy đoạn code dưới đây và paste vào index.h.
/* * Mã ESP32 này được phát triển bởi newbiely.vn * Mã ESP32 này được cung cấp để sử dụng công khai, không có ràng buộc. * Để xem hướng dẫn chi tiết và sơ đồ kết nối, vui lòng truy cập: * https://newbiely.vn/tutorials/esp32/esp32-led-matrix-via-web */constchar *HTML_CONTENT = R"=====(<!DOCTYPE html><!-- saved from url=(0019)http://192.168.0.2/ --><html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252"><title>ESP32 WebSocket</title><meta name="viewport" content="width=device-width, initial-scale=0.7"><link rel="icon" href="https://diyables.io/images/page/diyables.svg"><style>/* Add some basic styling for the chat window */body { font-size: 16px;}.chat-container { width: 400px; margin: 0 auto; padding: 10px;}.chat-messages { height: 250px; overflow-y: auto; border: 1px solid #444; padding: 5px; margin-bottom: 5px;}.user-input {display: flex; margin-bottom: 20px;}.user-input input { flex: 1; border: 1px solid #444; padding: 5px;}.user-input button { margin-left: 5px; background-color: #007bff; color: #fff; border: none; padding: 5px 10px;cursor: pointer;}.websocket {display: flex; align-items: center; margin-bottom: 5px;}.websocket button { background-color: #007bff; color: #fff; border: none; padding: 5px 10px;cursor: pointer;}.websocket .label { margin-left: auto;}</style><script>var ws;var wsm_max_len = 4096; /* bigger length causes uart0 buffer overflow with low speed smart device */function update_text(text) { var chat_messages = document.getElementById("chat-messages"); chat_messages.innerHTML += text + '<br>'; chat_messages.scrollTop = chat_messages.scrollHeight;}function send_onclick() {if(ws != null) { var message = document.getElementById("message").value;if (message) { document.getElementById("message").value = ""; ws.send(message + "\n"); update_text('<span style="color:navy">' + message + '</span>');// You can send the message to the server or process it as needed } }}function connect_onclick() { if(ws == null) { ws = new WebSocket("ws://" + window.location.host + ":81"); document.getElementById("ws_state").innerHTML = "CONNECTING"; ws.onopen = ws_onopen; ws.onclose = ws_onclose; ws.onmessage = ws_onmessage; } else ws.close();}function ws_onopen() { document.getElementById("ws_state").innerHTML = "<span style='color:blue'>CONNECTED</span>"; document.getElementById("bt_connect").innerHTML = "Disconnect"; document.getElementById("chat-messages").innerHTML = "";}function ws_onclose() { document.getElementById("ws_state").innerHTML = "<span style='color:gray'>CLOSED</span>"; document.getElementById("bt_connect").innerHTML = "Connect"; ws.onopen = null; ws.onclose = null; ws.onmessage = null; ws = null;}function ws_onmessage(e_msg) { e_msg = e_msg || window.event; // MessageEvent console.log(e_msg.data); update_text('<span style="color:blue">' + e_msg.data + '</span>');}</script></head><body> <div class="chat-container"> <h2>ESP32 WebSocket</h2> <div class="websocket"> <buttonclass="connect-button" id="bt_connect" onclick="connect_onclick()">Connect</button> <span class="label">WebSocket: <span id="ws_state"><span style="color:blue">CLOSED</span></span></span> </div> <div class="chat-messages" id="chat-messages"></div> <div class="user-input"> <input type="text" id="message" placeholder="Type your message..."> <button onclick="send_onclick()">Send</button> </div> <div class="sponsor">Sponsored by <a href="https://amazon.com/diyables">DIYables</a></div></div></body></html>)=====";
Bây giờ bạn có code trong hai file: newbiely.com.ino và index.h
Click nút Upload trên Arduino IDE để upload code lên ESP32.
Mở Serial Monitor
Kiểm tra kết quả trên Serial Monitor.
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
Connecting to WiFi...
Connected to WiFi
ESP32 Web Server's IP address IP address: 192.168.0.2
Ln 11, Col 1
ESP32 Dev Module on COM15
2
Ghi lại địa chỉ IP được hiển thị, và nhập địa chỉ này vào thanh địa chỉ của trình duyệt web trên smartphone hoặc máy tính của bạn.
Bạn sẽ thấy trang web như bên dưới:
Click nút CONNECT để kết nối trang web với ESP32 qua WebSocket.
Nhập một số từ và gửi chúng đến ESP32.
Bạn sẽ thấy phản hồi từ ESP32.
※ Lưu ý:
Nếu bạn sửa đổi nội dung HTML trong file index.h và không thay đổi gì trong file newbiely.com.ino, khi bạn compile và upload code lên ESP32, Arduino IDE sẽ không cập nhật nội dung HTML.
Để Arduino IDE cập nhật nội dung HTML trong trường hợp này, hãy thực hiện một thay đổi trong file newbiely.com.ino (ví dụ: thêm dòng trống, thêm comment....)
Giải Thích Code Từng Dòng
Code ESP32 ở trên có giải thích từng dòng. Vui lòng đọc các comment trong code!