Trong bài hướng dẫn này, bạn sẽ tạo một máy chủ web độc lập với ESP32 trên board Node Wifi32, điều khiển ngõ ra (hai đèn LED) bằng cách lập trình với phần mềm Arduino IDE. Máy chủ web đáp ứng trên thiết bị di động và có thể được truy cập bằng bất kỳ thiết bị nào làm trình duyệt trên mạng cục bộ. Chúng tôi sẽ hướng dẫn bạn cách tạo web server và cách viết code theo từng bước trên phần mềm Arduino IDE. Dù bạn là người mới bắt đầu tìm hiểu về Arduino cũng không sao, cách lập trình rất đơn giản!
>> Xem thêm: [PDF] Lập trình Arduino là gì? Tài liệu học Arduino miễn phí 2021
Mục lục
Tổng Quan
Trước khi đi vào bài hướng dẫn, điều quan trọng là phải theo dõi thật kỹ các quy trình của chúng tôi sẽ làm. Từ đó, bạn có thể thực hiện bài hướng dẫn này dễ dàng hơn:
- Máy chủ web bạn sẽ xây dựng và điều khiển hai đèn LED được kết nối với Node Wifi32 GPIO 25 và GPIO 27;
- Bạn có thể truy cập máy chủ web Node Wifi32 bằng cách nhập địa chỉ IP Node Wifi32 trên trình duyệt trong mạng cục bộ;
- Bằng cách nhấp vào các nút trên máy chủ web của bạn, bạn có thể thay đổi trạng thái của từng đèn LED ngay lập tức.
Đây chỉ là một ví dụ đơn giản để minh họa cách xây dựng một máy chủ web điều khiển ngõ ra. Bạn có thể thay thế các đèn LED đó bằng một Rơ-le, hoặc bất kỳ linh kiện điện tử nào khác mà bạn muốn.
Bạn đang cần ESP32 để thực hiện? Mua ngay tại đây!
Các Thiết Bị Chính
Đối với bài hướng dẫn này, bạn sẽ cần các phần sau:
- Board NodeWifi32
- Module LED x2
- Dây cắm x2
- Dây cáp kết nối
Truy cập trực tiếp vào https://ohstem.vn/san-pham/ để tìm tất cả các bộ phận cho dự án của mình với mức giá tốt nhất!
Sơ Đồ
Bắt đầu bằng cách xây dựng mạch. Kết nối hai đèn LED với Node Wifi32 như trong sơ đồ bên dưới – một đèn LED được kết nối với GPIO 25 và cái kia để kết nối với GPIO 27.
Lưu ý : Chúng tôi đang sử dụng board ESP32 DEV Module với 36 chân. Trước khi lắp ráp mạch, hãy đảm bảo rằng bạn đã kiểm tra sơ đồ chân của bo mạch mà bạn đang sử dụng.
Code lập trình Node Wifi32 Web Server trên phần mềm Arduino IDE
- Bạn chưa biết cách cài đặt phần mềm Arduino IDE? Hãy tham khảo bài viết: Cách cài đặt phần mềm Arduino IDE phiên bản mới nhất!
- Để có thể hiểu rõ cách thực hiện lập trình dưới đây, có thể bạn cần phải làm quen với giao diện của phần mềm Arduino IDE trước: Arduino IDE là gì? Các hàm của phần mềm Arduino IDE
Ở đây chúng tôi cung cấp code tạo máy chủ web Node Wifi32. Sao chép đoạn code bên dưới vào phần mềm Arduino IDE của bạn, nhưng bạn khoan hãy Upload vội. Bạn cần thực hiện một số thay đổi để code hoạt động cho bạn.
/********* Rui Santos Complete project details at https://randomnerdtutorials.com *********/ // Load Wi-Fi library #include <WiFi.h> // Replace with your network credentials const char* ssid = "REPLACE_WITH_YOUR_SSID"; // tên wifi const char* password = "REPLACE_WITH_YOUR_PASSWORD"; // password của wifi // Set web server port number to 80 WiFiServer server(80); // Variable to store the HTTP request String header; // Auxiliar variables to store the current output state String output25State = "off"; String output27State = "off"; // Assign output variables to GPIO pins const int output25 = 25; const int output27 = 27; // Current time unsigned long currentTime = millis(); // Previous time unsigned long previousTime = 0; // Define timeout time in milliseconds (example: 2000ms = 2s) const long timeoutTime = 2000; void setup() { Serial.begin(115200); // Initialize the output variables as outputs pinMode(output25, OUTPUT); pinMode(output27, OUTPUT); // Set outputs to LOW digitalWrite(output25, LOW); digitalWrite(output27, LOW); // Connect to Wi-Fi network with SSID and password Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } // Print local IP address and start web server Serial.println(""); Serial.println("WiFi connected."); Serial.println("IP address: "); Serial.println(WiFi.localIP()); server.begin(); } void loop(){ WiFiClient client = server.available(); // Listen for incoming clients if (client) { // If a new client connects, currentTime = millis(); previousTime = currentTime; Serial.println("New Client."); // print a message out in the serial port String currentLine = ""; // make a String to hold incoming data from the client while (client.connected() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected currentTime = millis(); if (client.available()) { // if there's bytes to read from the client, char c = client.read(); // read a byte, then Serial.write(c); // print it out the serial monitor header += c; if (c == '\n') { // if the byte is a newline character // if the current line is blank, you got two newline characters in a row. // that's the end of the client HTTP request, so send a response: if (currentLine.length() == 0) { // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) // and a content-type so the client knows what's coming, then a blank line: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); client.println(); // turns the GPIOs on and off if (header.indexOf("GET /25/on") >= 0) { Serial.println("GPIO 25 on"); output25State = "on"; digitalWrite(output25, HIGH); } else if (header.indexOf("GET /25/off") >= 0) { Serial.println("GPIO 25 off"); output25State = "off"; digitalWrite(output25, LOW); } else if (header.indexOf("GET /27/on") >= 0) { Serial.println("GPIO 27 on"); output27State = "on"; digitalWrite(output27, HIGH); } else if (header.indexOf("GET /27/off") >= 0) { Serial.println("GPIO 27 off"); output27State = "off"; digitalWrite(output27, LOW); } // Display the HTML web page client.println("<!DOCTYPE html><html>"); client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"); client.println("<link rel=\"icon\" href=\"data:,\">"); // CSS to style the on/off buttons // Feel free to change the background-color and font-size attributes to fit your preferences client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}"); client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;"); client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}"); client.println(".button2 {background-color: #555555;}</style></head>"); // Web Page Heading client.println("<body><h1>NodeWifi32 Web Server</h1>"); // Display current state, and ON/OFF buttons for GPIO 25 client.println("<p>GPIO 25 - State " + output25State + "</p>"); // If the output25State is off, it displays the ON button if (output26State=="off") { client.println("<p><a href=\"/25/on\"><button class=\"button\">ON</button></a></p>"); } else { client.println("<p><a href=\"/25/off\"><button class=\"button button2\">OFF</button></a></p>"); } // Display current state, and ON/OFF buttons for GPIO 27 client.println("<p>GPIO 27 - State " + output27State + "</p>"); // If the output27State is off, it displays the ON button if (output27State=="off") { client.println("<p><a href=\"/27/on\"><button class=\"button\">ON</button></a></p>"); } else { client.println("<p><a href=\"/27/off\"><button class=\"button button2\">OFF</button></a></p>"); } client.println("</body></html>"); // The HTTP response ends with another blank line client.println(); // Break out of the while loop break; } else { // if you got a newline, then clear currentLine currentLine = ""; } } else if (c != '\r') { // if you got anything else but a carriage return character, currentLine += c; // add it to the end of the currentLine } } } // Clear the header variable header = ""; // Close the connection client.stop(); Serial.println("Client disconnected."); Serial.println(""); } }
Nhập Thông Tin Đăng Nhập Vào Mạng Hiện Có
Bạn cần sửa đổi các dòng sau với thông tin đăng nhập mạng của mình: SSID và Password. Mã được nhận xét tốt về nơi bạn nên thực hiện các thay đổi.
// Replace with your network credentials const char* ssid = "TÊN ĐĂNG NHẬP WIFI"; const char* password = "PASSWORD WIFI";
Upload Code
Bây giờ, bạn có thể upload code và máy chủ web sẽ hoạt động ngay lập tức.
Làm theo các bước tiếp theo để upload code cho Node Wifi32:
- Cắm bo mạch Node Wifi32 vào máy tính của bạn;
- Trong phần mềm Arduino IDE, chọn bảng của bạn trong Tools > Board > ESP32 Arduino > ESP32 DEV Module
3. Chọn cổng COM trong Tools > Port.
4. Nhấn nút Upload trong phần mềm Arduino IDE và đợi vài giây trong khi mã biên dịch và tải lên bảng của bạn.
5) Chờ dòng thông báo “Done uploading” như hình dưới
Tìm Địa Chỉ IP Node Wifi32
Sau khi Upload code, hãy mở Serial Monitor với tốc độ truyền là 115200.
Nhấn nút RESET Node Wifi32. Node Wifi32 kết nối với Wi-Fi và xuất địa chỉ IP Node Wifi32 trên Màn hình nối tiếp. Sao chép địa chỉ IP đó, vì bạn cần nó để truy cập máy chủ web Node Wifi32.
Truy Cập Web Server
Để truy cập máy chủ web, hãy mở trình duyệt của bạn, dán địa chỉ IP của Node Wifi32 và bạn sẽ thấy trang sau. Trong trường hợp của chúng tôi, nó là 192.168.1.17.
Nếu bạn nhìn vào Serial Monitor, bạn có thể thấy những gì đang xảy ra trên nền. Node Wifi32 nhận được một yêu cầu HTTP từ một máy khách mới (trong trường hợp này là trình duyệt của bạn).
Bạn cũng có thể xem thông tin khác về yêu cầu HTTP.
Kiểm Tra Web Server
Bây giờ bạn có thể kiểm tra xem máy chủ web của bạn có hoạt động bình thường hay không. Nhấp vào các nút để điều khiển đèn LED.
Đồng thời, bạn có thể nhìn vào Serial Monitor để xem những gì đang diễn ra trong nền. Ví dụ: khi bạn nhấp vào nút để chuyển GPIO 25 ON, Node Wifi32 nhận được yêu cầu / 26 / on URL.
Khi Node Wifi32 nhận được yêu cầu đó, nó sẽ chuyển đèn LED được gắn vào GPIO 25 ON và cập nhật trạng thái của nó trên trang web.
Nút cho GPIO 27 hoạt động theo cách tương tự. Bạn hãy kiểm tra xem nó có hoạt động bình thường không.
Cách Code Hoạt Động
Trong phần này sẽ xem xét kỹ hơn mã để xem nó hoạt động như thế nào.
Điều đầu tiên bạn cần làm là đưa vào thư viện WiFi.
#include <WiFi.h>
Như đã đề cập trước đây, bạn cần chèn ssid và mật khẩu của mình vào các dòng sau bên trong dấu ngoặc kép.
const char* ssid = “”;
const char* password = “”;
Sau đó, bạn đặt máy chủ web của mình thành cổng 80.
WiFiServer server(80);
Dòng sau tạo một biến để lưu trữ tiêu đề của yêu cầu HTTP:
String header;
Tiếp theo, bạn tạo các biến hỗ trợ để lưu trữ trạng thái hiện tại của đầu ra của bạn. Nếu bạn muốn thêm nhiều đầu ra hơn và lưu trạng thái của nó, bạn cần tạo nhiều biến hơn.
String output25State = “off”;
String output27State = “off”;
Bạn cũng cần gán GPIO cho mỗi đầu ra của mình. Ở đây chúng tôi đang sử dụng GPIO 25 và GPIO 27. Bạn có thể sử dụng bất kỳ GPIO phù hợp nào khác.
const int output25 = 25;
const int output27 = 27;
Hàm setup trong phần mềm Arduino IDE
Bây giờ, chúng ta hãy đi vào setup(). Đầu tiên, chúng tôi bắt đầu giao tiếp nối tiếp ở tốc độ truyền 115200 cho mục đích gỡ lỗi.
Serial.begin(115200);
Bạn cũng xác định GPIO của mình là OUTPUT và đặt chúng thành LOW.
// Initialize the output variables as outputs pinMode(output25, OUTPUT); pinMode(output27, OUTPUT); // Set outputs to LOW digitalWrite(output25, LOW); digitalWrite(output27, LOW);
Các dòng sau bắt đầu kết nối Wi-Fi với WiFi.begin (ssid, password), đợi kết nối thành công và in địa chỉ IP Node Wifi32 trong Serial Monitor.
// Connect to Wi-Fi network with SSID and password Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } // Print local IP address and start web server Serial.println(""); Serial.println("WiFi connected."); Serial.println("IP address: "); Serial.println(WiFi.localIP()); server.begin();
Hàm loop trong phần mềm Arduino IDE
Bên trong loop(), chúng tôi sẽ hướng dẫn bạn lập trình trên phần mềm Arduino IDE khi bạn lần đầu thiết lập kết nối với máy chủ web.
NodeWifi32 luôn nhân tín hiệu đến với dòng sau:
WiFiClient client = server.available(); // Listen for incoming clients
Khi nhận được yêu cầu tín hiệu, chúng tôi sẽ lưu dữ liệu. Vòng lặp while sau đó sẽ chạy và thiết bị ngoại vi vẫn kết nối.
Chúng tôi khuyên bạn không nên thay đổi phần sau của mã trừ khi bạn biết chính xác mình đang làm gì.
if (client) { // If a new client connects, Serial.println("New Client."); // print a message out in the serial port String currentLine = ""; // make a String to hold incoming data from the client while (client.connected()) { // loop while the client's connected if (client.available()) { // if there's bytes to read from the client, char c = client.read(); // read a byte, then Serial.write(c); // print it out the serial monitor header += c; if (c == '\n') { // if the byte is a newline character // if the current line is blank, you got two newline characters in a row. / that's the end of the client HTTP request, so send a response: if (currentLine.length() == 0) { // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) // and a content-type so the client knows what's coming, then a blank line: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); client.println(); Phần tiếp theo của câu lệnh if và else sẽ kiểm tra nút nào được nhấn trong trang web của bạn và kiểm soát kết quả đầu ra tương ứng. Như chúng tôi đã thấy trước đây, chúng tôi thực hiện yêu cầu trên các URL khác nhau tùy thuộc vào nút được nhấn. // turns the GPIOs on and off if (header.indexOf("GET /25/on") >= 0) { Serial.println("GPIO 25 on"); output25State = "on"; digitalWrite(output25, HIGH); } else if (header.indexOf("GET /25/off") >= 0) { Serial.println("GPIO 25 off"); output25State = "off"; digitalWrite(output25, LOW); } else if (header.indexOf("GET /27/on") >= 0) { Serial.println("GPIO 27 on"); output27State = "on"; digitalWrite(output27, HIGH); } else if (header.indexOf("GET /27/off") >= 0) { Serial.println("GPIO 27 off"); output27State = "off"; digitalWrite(output27, LOW); }
Ví dụ: nếu bạn đã nhấn nút GPIO 25 ON, Node Wifi32 sẽ nhận được yêu cầu trên URL / 25 / ON (chúng ta có thể thấy rằng thông tin đó trên tiêu đề HTTP trên Serial Monitor). Vì vậy, chúng ta có thể kiểm tra xem tiêu đề có chứa biểu thức GET / 25 / on hay off. Nếu nó chứa, chúng tôi thay đổi output25state biến thành ON và Node Wifi32 bật đèn LED.
Điều này hoạt động tương tự cho các nút khác. Vì vậy, nếu bạn muốn thêm nhiều đầu ra hơn, bạn nên sửa đổi phần này của mã lập trình trên phần mềm Arduino để bao gồm chúng.
Hiển thị trang web HTML
Điều tiếp theo bạn cần làm là tạo trang web. Node Wifi32 sẽ gửi phản hồi đến trình duyệt của bạn với một số mã HTML để xây dựng trang web.
Trang web được gửi đến khách hàng bằng cách sử dụng client.println ().
Điều đầu tiên chúng ta nên gửi là các dòng sau, điều đó cho biết rằng chúng ta đang gửi HTML.
<!DOCTYPE HTML><html>
Sau đó, dòng sau làm cho trang web phản hồi trong bất kỳ trình duyệt web nào.
client.println(“<head><meta name=\”viewport\” content=\”width=device-width, initial-scale=1\”>”);
Và phần sau được sử dụng để ngăn chặn các yêu cầu trên favicon. – Bạn không cần lo lắng về dòng này.
client.println(“<link rel=\”icon\” href=\”data:,\”>”);
Tạo kiểu cho Trang Web
Tiếp theo, chúng ta có một số văn bản CSS để tạo kiểu cho các nút và giao diện trang web. Chúng tôi chọn phông chữ Helvetica, chọn cách hiển thị nội dung thành một khối và căn chỉnh ở trung tâm.
client.println(“<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}”);
Chúng tôi tạo kiểu cho các nút của mình với màu #4CAF50, không có đường viền, văn bản màu trắng và với padding: 16px 40px. Chúng tôi cũng không đặt trang trí văn bản, xác định kích thước phông chữ, lề và con trỏ thành con trỏ.
client.println(“.button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;”);
client.println(“text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}”);
Chúng tôi cũng xác định kiểu cho nút thứ hai, với tất cả các thuộc tính của nút mà chúng tôi đã xác định trước đó, nhưng với một màu khác. Đây sẽ là phong cách cho nút tắt.
client.println(“.button2 {background-color: #555555;}</style></head>”);
Đặt tiêu đề đầu tiên của trang web
Trong dòng tiếp theo, bạn có thể đặt tiêu đề đầu tiên cho trang web của mình. Ở đây chúng tôi có “Node Wifi32 Web Server ”, nhưng bạn có thể thay đổi văn bản này thành bất kỳ thứ gì bạn muốn.
// Web Page Heading
client.println(“<h1>NodeWifi32 Web Server</h1>”);
Hiển thị các nút và trạng thái tương ứng
Sau đó, bạn viết một đoạn văn để hiển thị GPIO 25 tình trạng hiện tại. Như bạn có thể thấy, chúng tôi sử dụng biến output25State, để trạng thái cập nhật ngay lập tức khi biến này thay đổi.
client.println(“<p>GPIO 25 – State ” + output25State + “</p>”);
Sau đó, chúng tôi hiển thị nút bật hoặc tắt, tùy thuộc vào trạng thái hiện tại của GPIO. Nếu trạng thái hiện tại của GPIO là tắt, chúng tôi hiển thị nút ON, nếu không, chúng tôi hiển thị nút OFF.
if (output25State=="off") { client.println("<p><a href=\"/25/on\"><button class=\"button\">ON</button></a></p>"); } else { client.println("<p><a href=\"/25/off\"><button class=\"button button2\">OFF</button></a></p>"); }
Chúng tôi sử dụng quy trình tương tự cho GPIO 27.
Ngắt Kết Nối
Cuối cùng, khi phản hồi kết thúc, chúng tôi xóa header và dừng kết nối với máy khách bằng client.stop ().
// Clear the header variable header = ""; // Close the connection client.stop();
Kết Luận
Trong hướng dẫn này, chúng tôi đã chỉ cho bạn cách tạo máy chủ web với Node Wifi32 bằng phần mềm Arduino IDE. Chúng tôi đã chỉ cho bạn một ví dụ đơn giản điều khiển hai đèn LED. Đây là ví dụ cơ bản nhất. Bạn có thể dựa vào đó để xây dựng các ý tưởng sáng tạo khác, như thay thế các đèn LED đó bằng một rơ le hoặc bất kỳ đầu ra nào khác mà bạn muốn điều khiển.
Để xem tất cả các bài hướng dẫn về lập trình Arduino, bạn truy cập vào đây nhé: Tổng hợp các bài hướng dẫn về Arduino. Nếu bạn có bất kỳ ý kiến đóng góp hoặc thắc mắc gì, bạn có thể để lại comment phía dưới hoặc liên hệ với OhStem qua Fanpage để được hỗ trợ nhé