Trong bài viết này, tôi sẽ hướng dẫn các bạn tạo một web server độc lập với mô-đun ESP8266 để hiển thị nhiệt độ và độ ẩm từ cảm biến DHT11 hoặc DHT22 bằng cách sử dụng Arduino IDE. Web server mà bạn xây dựng có thể được truy cập bởi bất kỳ thiết bị nào có trình duyệt trên mạng cục bộ của bạn.
Chuẩn bị
Phần cứng
- NodeMCU ESP8266
- Cảm biến DHT11
- Cáp USB
- Dây cắm Breadboard
Phần mềm
Sơ đồ nguyên lý
- Chân Vcc của cảm biến DHT11 được kết nối với chân 3.3V của ESP8266
- Chân GND của cảm biến DHT11 được kết nối với chân GND của ESP8266
- Ngõ ra của cảm biến DHT11 được kết nối với chân GPIO5 của ESP8266.
Chương trình
#include <ESP8266WiFi.h>
#include “DHT.h”
#define DHTTYPE DHT11
const char* ssid = “ten-wifi”;
const char* password = “password-wifi”;
WiFiServer server(80);
const int DHTPin = 5;
DHT dht(DHTPin, DHTTYPE);
static char celsiusTemp[7];
static char fahrenheitTemp[7];
static char humidityTemp[7];
void setup()
{
Serial.begin(115200);
delay(10);
dht.begin();
Serial.println();
Serial.print(“Dang ket noi den mang… “);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(“.”);
}
Serial.println(“”);
Serial.println(“Da ket noi WiFi”);
server.begin();
Serial.println(“Web server dang khoi dong. Vui long doi dia chi IP…”);
delay(1000);
Serial.println(WiFi.localIP());
}
void loop()
{
WiFiClient client = server.available();
if (client)
{
Serial.println(“Co client moi”);
boolean blank_line = true;
while (client.connected())
{
if (client.available())
{
char c = client.read();
if (c == ‘\n’ && blank_line)
{
float h = dht.readHumidity();
float t = dht.readTemperature();
float f = dht.readTemperature(true);
if (isnan(h) || isnan(t) || isnan(f))
{
Serial.println(“Khong the doc du lieu tu cam bien DHT!”);
strcpy(celsiusTemp, “Failed”);
strcpy(fahrenheitTemp, “Failed”);
strcpy(humidityTemp, “Failed”);
}
else
{
float hic = dht.computeHeatIndex(t, h, false);
dtostrf(hic, 6, 2, celsiusTemp);
float hif = dht.computeHeatIndex(f, h);
dtostrf(hif, 6, 2, fahrenheitTemp);
dtostrf(h, 6, 2, humidityTemp);
}
client.println(“HTTP/1.1 200 OK”);
client.println(“Content-Type: text/html”);
client.println(“Connection: close”);
client.println();
client.println(“<!DOCTYPE HTML>”);
client.println(“<html>”);
client.println(“<h1>ESP8266 & DHT11</h1>”);
client.println(“<head></head><body><h2>Nhiet do va do am</h2><h3>Nhiet do theo do C: “);
client.println(celsiusTemp);
client.println(“*C</h3><h3>Nhiet do theo do F: “);
client.println(fahrenheitTemp);
client.println(“*F</h3><h3>Do am: “);
client.println(humidityTemp);
client.println(“%</h3><h3>”);
client.println(“<h2>dientuadenz.com</h2>”);
client.println(“</body></html>”);
break;
}
if (c == ‘\n’)
{
blank_line = true;
}
else if (c != ‘\r’)
{
blank_line = false;
}
}
}
delay(1);
client.stop();
Serial.println(“Ngat ket noi client.”);
}
}
Giải thích chương trình
Chúng ta thêm thư viện ESP8266Wifi.h để cung cấp cho ESP8266 các công việc WiFi cụ thể và chúng ta sử dụng thư viện này để kết nối với mạng. Ngoài ra, chúng ta còn thêm thư viện DHT.h, cho phép chúng ta đọc dữ liệu về nhiệt độ và độ ẩm từ cảm biến.
#include <ESP8266WiFi.h>
#include “DHT.h”
Khai báo loại cảm biến DHT mà chúng ta đang sử dụng.
#define DHTTYPE DHT11
Nhập tên tên và mật khẩu WiFi của bạn.
const char* ssid = “SERVER NAME”;
const char* password = “SERVER PASSWORD”;
Khai báo web server trên cổng 80. Cổng 80 là cổng mặc định, web server “lắng nghe” và nhận dữ liệu từ máy khách (web client).
WiFiServer server(80);
DHTPin là một số nguyên không đổi, các hằng số (const) không thay đổi trong suốt chương trình. DHTPin được nối với chân GPIO05 (D1) của ESP8266 và khởi tạo cảm biến DHT.
const int DHTPin = 5;
DHT dht(DHTPin, DHTTYPE);
Khai báo các biến tạm thời với kiểu static char cho nhiệt độ và độ ẩm.
static char celsiusTemp[7];
static char fahrenheitTemp[7];
static char humidityTemp[7];
Đoạn chương trình nằm trong hàm setup sẽ chỉ chạy một lần trong khi chạy chương trình.
Đây là đoạn chương trình trong hàm setup, nó sẽ kết nối với mạng WiFi và cũng khởi tạo giao tiếp nối tiếp để gỡ lỗi và ghi nhật ký với tốc độ baud là 115200.
void setup() {
Serial.begin(115200);
delay(10);
dht.begin();
Kết nối thực sự với WiFi được khởi tạo bằng cách sử dụng các câu lệnh bên dưới.
Serial.println();
Serial.print(“Dang ket noi den mang… “);
Serial.println(ssid);
WiFi.begin(ssid, password);
Quá trình kết nối có thể mất vài giây. Vòng lặp While () kiểm tra kết nối mô-đun ESP8266 với WiFi. Nếu nó được kết nối với WiFi thì trên serial monitor sẽ hiển thị thông báo “Da ket noi WiFi”, ngược lại thì các dấu chấm (….) sẽ hiển thị trên serial monitor.
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(“.”);
}
Serial.println(“”);
Serial.println(“Da ket noi WiFi”);
Chương trình sẽ in địa chỉ IP của mô-đun ESP8266. Địa chỉ IP này được cung cấp bởi server DHCP chạy trên bộ định tuyến WiFi. Để truy cập nó, chúng ta cần kết nối hệ thống của chúng ta với cùng một mạng WiFi (hệ thống của chúng ta sẽ nhận một địa chỉ IP khác từ server DHCP của bộ định tuyến) và chúng ta cần nhập địa chỉ IP của ESP8266 vào trong trình duyệt của hệ thống chúng ta.
server.begin();
Serial.println(“Web server dang khoi dong. Vui long doi dia chi IP…”);
delay(1000);
Serial.println(WiFi.localIP()); }
Đặt đoạn code chính của bạn vào hàm void loop () để chạy liên tục.
Chờ đợi và kiểm tra để một client được kết nối.
Lưu ý: Client chính là trình duyệt. Khi chúng ta truy cập địa chỉ IP của ESP8266 trong trình duyệt thì chính là gửi yêu cầu đến web server lắng nghe trên cổng TCP 80.
void loop() {
WiFiClient client = server.available();
Nếu có client mới, biến Boolean ‘client’ sẽ là đúng và chúng ta tiến hành xử lý yêu cầu.
if (client)
{
Serial.println(“Co client moi”);
boolean blank_line = true;
while (client.connected())
{
if (client.available())
{
char c = client.read();
Nếu client được kết nối thì đọc độ ẩm, nhiệt độ bằng độ C và độ F.
if (c == ‘\n’ && blank_line)
{
float h = dht.readHumidity();
float t = dht.readTemperature();
float f = dht.readTemperature(true);
Kiểm tra nếu đọc dữ liệu không thành công thì kết thúc sớm. Nếu đọc dữ liệu từ cảm biến thất bại thì đưa ra thông báo “Khong the doc du lieu tu cam bien DHT!”.
if (isnan(h) || isnan(t) || isnan(f))
{
Serial.println(“Khong the doc du lieu tu cam bien DHT!”);
strcpy(celsiusTemp,”Failed”);
strcpy(fahrenheitTemp, “Failed”);
strcpy(humidityTemp, “Failed”);
}
Nếu việc đọc dữ liệu từ cảm biến thành công, thì sẽ tính và hiển thị các giá trị nhiệt độ theo độ C, độ F và độ ẩm.
else
{
float hic = dht.computeHeatIndex(t, h, false);
dtostrf(hic, 6, 2, celsiusTemp);
float hif = dht.computeHeatIndex(f, h);
dtostrf(hif, 6, 2, fahrenheitTemp);
dtostrf(h, 6, 2, humidityTemp);
}
Chương trình HTML để tạo một trang web hiển thị giá trị nhiệt độ và độ ẩm.
client.println(“HTTP/1.1 200 OK”);
client.println(“Content-Type: text/html”);
client.println(“Connection: close”);
client.println();
client.println(“<!DOCTYPE HTML>”);
client.println(“<html>”);
client.println(“<h1>ESP8266 & DHT11</h1>”);
client.println(“<head></head><body><h2>Nhiet do va do am</h2><h3>Nhiet do theo do C: “);
client.println(celsiusTemp);
client.println(“*C</h3><h3>Nhiet do theo do F: “);
client.println(fahrenheitTemp);
client.println(“*F</h3><h3>Do am: “);
client.println(humidityTemp);
client.println(“%</h3><h3>”);
client.println(“<h2>dientuadenz.com</h2>”);
client.println(“</body></html>”);
break;
}
if (c == ‘\n’)
{
blank_line = true;
}
else if (c != ‘\r’)
{
blank_line = false;
}
}
}
delay(1);
client.stop();
Serial.println(“Ngat ket noi client.”);
}
}
Truy cập web server
Sau khi nạp chương trình, bạn hãy mở serial monitor với tốc độ baud là 115200. Và nhấn nút RESET trên NodeMCU. Nếu mọi thứ đều ổn thì bạn sẽ thấy địa chỉ IP động thu được từ bộ định tuyến của bạn.
Tiếp theo, bạn hãy copy địa chỉ IP được hiển thị trên serial monitor và dán vào trình duyệt web. ESP8266 NodeMCU sẽ cung cấp một trang web hiển thị nhiệt độ và độ ẩm tương đối như hình bên dưới.
Kết luận
Trong dự án này, chúng ta sử dụng cảm biến DHT11 để theo dõi nhiệt độ và độ ẩm của nơi nó được đặt. Trái tim của dự án là ESP8266 WiFi SoC. ESP8266 được lập trình như một máy chủ web chạy trên cổng HTTP mặc định 80. Khi nhận được yêu cầu từ máy khách (trình duyệt web), nó sẽ đọc dữ liệu từ cảm biến DHT11 và gửi phản hồi sẽ được hiển thị trong trình duyệt.