Arduino WebSocket

Trong hướng dẫn này, chúng ta sẽ khám phá WebSocket là gì, tại sao nó hữu ích cho việc điều khiển Arduino một cách hiệu quả, và cách triển khai WebSocket với Arduino. Thông qua một ví dụ thực hành, chúng ta sẽ trình diễn cách xây dựng một ứng dụng chat kết nối trình duyệt web với Arduino, giúp bạn có thể:

websocket trên Arduino

Phần cứng cần chuẩn bị

1×Arduino UNO R4 WiFi
1×Alternatively, DIYables STEM V4 IoT
1×(Tùy chọn) DIYables STEM V4 IoT
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
1×(Khuyến nghị) Screw Terminal Block Shield for Arduino UNO R4
1×(Khuyến nghị) Breadboard Shield for Arduino UNO R4
1×(Khuyến nghị) Enclosure for Arduino UNO R4
1×(Khuyến nghị) Power Splitter for Arduino UNO R4
1×(Khuyến nghị) Prototyping Base Plate & Breadboard Kit for Arduino UNO

Or you can buy the following kits:

1×DIYables STEM V4 IoT Starter Kit (Arduino included)
1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)

Arduino Websocket là gì?

Bạn có thể đang tự hỏi, 'WebSocket là gì?' Nó khá đơn giản: WebSocket là một công nghệ cho phép trình duyệt web giao tiếp trực tiếp với máy chủ web theo thời gian thực.

  • Nếu không có WebSocket, bạn sẽ phải làm mới trang web để xem các cập nhật mới. Điều này không thực tế lắm.
  • Với WebSocket, trang web vẫn được kết nối liên tục với máy chủ. Điều này cho phép họ trao đổi thông tin ngay lập tức mà không cần làm mới trang.

Bạn có thể thường xuyên gặp công nghệ WebSocket trong các ứng dụng web hàng ngày, chẳng hạn như trò chơi trực tuyến, nhắn tin tức thời và cập nhật thị trường chứng khoán.

Tại sao chúng ta cần WebSocket để điều khiển Arduino một cách mượt mà?

Hãy tưởng tượng bạn muốn điều khiển chiếc xe điều khiển từ xa bằng giao diện web trên điện thoại hoặc máy tính của mình. Nếu không có WebSocket, mỗi lần bạn muốn thay đổi hướng hoặc tốc độ của xe, bạn sẽ phải làm mới trang web. Điều này giống như phải nhấn nút 'tải lại' mỗi khi bạn đưa ra lệnh cho xe.

Với WebSocket, tuy nhiên, nó như thể có một kết nối liên tục và trực tiếp giữa điện thoại hoặc máy tính của bạn với ô tô. Bạn không cần làm mới trang để điều khiển ô tô hoặc thay đổi tốc độ của nó. Nó như thể ô tô liên tục lắng nghe các lệnh của bạn trong thời gian thực, mà không gặp bất kỳ độ trễ nào do phải làm mới trang.

Nhìn chung, WebSocket tạo điều kiện cho:

  • Gửi dữ liệu từ trình duyệt web đến Arduino mà không cần tải lại trang web.
  • Gửi dữ liệu từ Arduino trở lại trình duyệt web mà không làm mới trang web.

Điều này cho phép giao tiếp hai chiều mượt mà trong thời gian thực.

Lợi ích của WebSocket với Arduino:

  • Kiểm soát thời gian thực: WebSocket cho phép giao tiếp tức thì với Arduino, đảm bảo phản hồi nhanh cho các lệnh để mang lại trải nghiệm người dùng liền mạch.
  • Kết nối duy trì: Duy trì một liên kết liên tục mà không làm mới trang điều khiển, tạo ra một kênh liên lạc luôn sẵn sàng cho các lệnh ngay tức thì.
  • Hiệu quả: Trải nghiệm phản hồi nhanh mà không cần tải lại trang liên tục, nâng cao sự hài lòng và hiệu quả của người dùng.

Trò chuyện Web với Arduino qua WebSocket

Nội dung của trang web (HTML, CSS, JavaScript) được lưu riêng trong một tập tin index.h. Vì vậy, chúng ta sẽ có hai tập tin mã trên Arduino IDE:

  • Một tệp .ino chứa mã Arduino, tạo ra một máy chủ web và máy chủ WebSocket
  • Một tệp .h chứa nội dung của trang web.

Hướng dẫn từng bước

  • Nếu đây là lần đầu bạn sử dụng Arduino Uno R4, hãy xem Cách bắt đầu với Arduino UNO R4.
  • Kết nối bảng Arduino với máy tính của bạn bằng cáp micro USB
  • Mở Arduino IDE trên máy tính của bạn.
  • Chọn bảng Arduino phù hợp (Arduino Uno R4 WiFi) và cổng COM.
  • Mở Library Manager bằng cách nhấp 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 Web Server for Arduino Uno R4 WiFi và xác định thư viện Web Server do DIYables tạo.
  • Nhấp nút Install để cài đặt thư viện Web Server.
thư viện máy chủ web cho Arduino UNO R4
  • Trong Arduino IDE, tạo một sketch mới, đặt tên cho nó, ví dụ, ArduinoGetStarted.com.ino
  • Sao chép mã dưới đây và mở bằng Arduino IDE
/* * Mã Arduino này được phát triển bởi newbiely.vn * Mã Arduino 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/arduino/arduino-websocket */ #include <UnoR4WiFi_WebServer.h> #include "index.h" // WiFi credentials const char WIFI_SSID[] = "YOUR_WIFI_SSID"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // Create web server instance UnoR4WiFi_WebServer server(80); UnoR4WiFi_WebSocket *webSocket; // Page handlers void handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { server.sendResponse(client, HTML_CONTENT); } // WebSocket event handlers void onWebSocketOpen(net::WebSocket& ws) { Serial.println("New WebSocket connection"); const char message[]{ "Hello from Arduino server!" }; ws.send(WebSocket::DataType::TEXT, message, strlen(message)); } void onWebSocketMessage(net::WebSocket& ws, const net::WebSocket::DataType dataType, const char* message, uint16_t length) { Serial.print(F("Received: ")); Serial.println(message); String reply = "Received: " + String((char*)message); ws.send(dataType, reply.c_str(), reply.length()); } void onWebSocketClose(net::WebSocket& ws, const net::WebSocket::CloseCode code, const char* reason, uint16_t length) { Serial.println("WebSocket client disconnected"); } void setup() { Serial.begin(9600); delay(1000); Serial.println("Arduino Uno R4 WiFi - WebSocket Server"); // 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"); } } void loop() { // Handle HTTP requests and WebSocket connections using the library server.handleClient(); server.handleWebSocket(); delay(10); }
  • Chỉnh sửa thông tin WiFi (SSID và mật khẩu) trong mã nguồn để khớp với thông tin đăng nhập của mạng bạn.
  • Tạo tệp index.h trong Arduino IDE bằng cách:
    • Nhấn vào nút ngay dưới biểu tượng Serial Monitor và chọn New Tab, hoặc sử dụng các phím Ctrl+Shift+N.
    Arduino ide 2 thêm tệp
    • Hãy nhập tên tệp index.h và nhấn nút OK
    Arduino ide 2 thêm tệp index.h
    • Sao chép đoạn mã dưới đây và dán vào index.h.
    /* * Mã Arduino này được phát triển bởi newbiely.vn * Mã Arduino 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/arduino/arduino-websocket */ const char *HTML_CONTENT = R"=====( <!DOCTYPE html> <html> <head> <title>Arduino WebSocket</title> <meta name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=0.7"> <link rel="icon" href="https://diyables.io/images/page/diyables.svg"> <style> /* Add some basic styling for the chat window */ body { background-color: #E1EFEF; font-size: 20px; line-height: 1.3; } button, input { font-size: 20px; line-height: 1.3; } .chat-container { margin: 0 auto; padding: 10px; } .chat-messages { height: 250px; overflow-y: auto; 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; } .message-sent { border-radius: 25px; background-color: #d35400; float: right; width: fit-content; padding: 10px 20px; margin: 0; } .message-received { border-radius: 25px; background-color: white; float: left; width: fit-content; padding: 10px 20px; margin: 0; } </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 += '<div style="width:100%;overflow: auto;">' + text + '</div>'; 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('<p class="message-sent">' + message + '</p>'); // 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('<p class="message-received">' + e_msg.data + '</p>'); } </script> </head> <body> <div class="chat-container"> <h2>Arduino WebSocket</h2> <div class="websocket"> <button class="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ó mã trong hai tập tin: ArduinoGetStarted.com.inoindex.h
    • Nhấn vào nút Tải lên trên Arduino IDE để tải mã lên Arduino.
    • Mở Serial Monitor
    • Xem kết quả trên Serial Monitor.
    COM6
    Send
    Arduino Uno R4 WiFi - WebSocket Server Connected! IP Address: 192.168.0.254 SSID: YOUR_WIFI_SSID IP Address: 192.168.0.254 Signal strength (RSSI): -44 dBm WebSocket server started on port 81 WebSocket URL: ws://192.168.0.254:81 WebSocket server enabled successfully
    Autoscroll Show timestamp
    Clear output
    9600 baud  
    Newline  
    • Ghi chú đị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 điện thoại thông minh hoặc máy tính của bạn.
    • Bạn sẽ thấy trang web như hình dưới đây:
    trình duyệt websocket cho Arduino
    • Nhấn nút KẾT NỐI để kết nối trang web với Arduino qua WebSocket.
    • Gõ một vài từ và gửi chúng đến Arduino.
    • Bạn sẽ thấy phản hồi từ Arduino.
    máy chủ trò chuyện websocket cho Arduino

    ※ Lưu ý:

    • Nếu bạn chỉnh sửa nội dung HTML trong index.h và không chạm vào bất kỳ nội dung nào trong tệp ArduinoGetStarted.com.ino, khi bạn biên dịch và tải mã lên Arduino, 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 tệp ArduinoGetStarted.com.ino (ví dụ thêm một dòng trống, thêm một chú thích...).

    Giải thích mã theo từng dòng

    Đoạn mã Arduino ở trên có lời giải thích theo từng dòng. Vui lòng đọc các chú thích trong mã.

Cách hệ thống hoạt động

Mã Arduino hoạt động bằng cách thiết lập đồng thời cả một máy chủ web và một máy chủ WebSocket. Đây là cách nó hoạt động:

  • Khi bạn nhập địa chỉ IP của Arduino vào trình duyệt web, nó yêu cầu trang web (Giao diện người dùng) từ Arduino.
  • Máy chủ web của Arduino sau đó gửi nội dung của trang web (HTML, CSS, JavaScript) tới trình duyệt của bạn.
  • Trình duyệt web của bạn hiển thị trang web.
  • Khi nhấp vào nút Kết nối trên trang web, mã JavaScript bên trong trang sẽ thiết lập một kết nối WebSocket với máy chủ WebSocket trên Arduino.
  • Khi kết nối WebSocket đã hoạt động, nếu bạn gõ gì đó và nhấn nút Gửi, mã JavaScript sẽ gửi nội dung bạn nhập đến Arduino thông qua kết nối WebSocket ở chế độ nền.
  • Sau khi nhận được đầu vào của bạn, máy chủ WebSocket trên Arduino gửi phản hồi trở lại cho trang web của bạn.

Bạn có thể tìm hiểu thêm các ví dụ Arduino WebSocket khác ở phía dưới.