Cách tạo Web Server bằng phần mềm Arduino IDE cho ESP32

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

Tạo web Server bằng phần mềm Arduino IDE

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:

Các thiết bị chính để lập trình

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.

Kết nối 2 LEd với Node WIfi 32

Code lập trình Node Wifi32 Web Server trên 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:

  1.  Cắm bo mạch Node Wifi32 vào máy tính của bạn;
  2.  Trong phần mềm Arduino IDE, chọn bảng của bạn trong Tools > Board > ESP32 Arduino > ESP32 DEV Module 
Chọn bảng của bạn trên phần mềm Arduino IDE

3. Chọn cổng COM trong  Tools >  Port.

Chọn cổng COM
Chọn cổng COM trên phần mềm Arduino IDE

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.

Nhấn nút Upload

5) Chờ dòng thông báo “Done uploading” như hình dưới

Done uploading

Tìm Địa Chỉ IP Node Wifi32

Sau khi Upload code, hãy mở Serial Monitor với tốc độ truyền là 115200.

Mở Serial Monitor trên phần mềm Arduino IDE

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.

Địa chỉ IP 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.

Địa chỉ IP của Node WIfi 32 Web Server

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).

Giao diện Serial Monitor

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.

Đ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.

Yêu cầu GPIO 25 on

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.

Cập nhật trạng thái trên 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é

Tags: ESP32, phần mềm Arduino IDe, web server

Những bài liên quan

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Fill out this field
Fill out this field
Vui lòng nhập địa chỉ email hợp lệ.
You need to agree with the terms to proceed