Dự án này chỉ ra cách xây dựng một máy chủ web với bảng ESP8266 NodeMCU để vẽ các bài đọc cảm biến trong các biểu đồ với nhiều chuỗi. Ví dụ: chúng tôi sẽ vẽ số đọc cảm biến từ bốn cảm biến nhiệt độ DS18B20 khác nhau trên cùng một biểu đồ. Bạn có thể sửa đổi dự án để vẽ bất kỳ dữ liệu nào khác. Để xây dựng các biểu đồ, chúng ta sẽ sử dụng thư viện JavaScript Highcharts.
Trang 1ESP8266 Số đọc cảm biến biểu đồ NodeMCU trong
biểu đồ (Nhiều chuỗi)
Dự án này chỉ ra cách xây dựng một máy chủ web với bảng ESP8266 NodeMCU để vẽcác bài đọc cảm biến trong các biểu đồ với nhiều chuỗi Ví dụ: chúng tôi sẽ vẽ số đọc
cảm biến từ bốn cảm biến nhiệt độ DS18B20 khác nhau trên cùng một biểu đồ Bạn có
thể sửa đổi dự án để vẽ bất kỳ dữ liệu nào khác Để xây dựng các biểu đồ, chúng ta sẽ
sử dụng thư viện JavaScript Highcharts
Chúng tôi có một hướng dẫn tương tự cho bảng ESP32:
Số đọc cảm biến biểu đồ ESP32 trong biểu đồ (Nhiều chuỗi)
Tổng quan dự án
Dự án này sẽ xây dựng một máy chủ web với bảng mạch ESP8266 NodeMCU hiển thị
các chỉ số nhiệt độ từ bốn cảm biến nhiệt độ DS18B20 trên cùng một biểu đồ — biểu đồvới nhiều chuỗi Biểu đồ hiển thị tối đa 40 điểm dữ liệu cho mỗi chuỗi và các bài đọc mớiđược thêm vào sau mỗi 30 giây Bạn có thể thay đổi các giá trị này trong mã của mình
Trang 2Cảm biến nhiệt độ DS18B20
Cảm biến nhiệt độ DS18B20 là cảm biến nhiệt độ kỹ thuật số một dây Điều này có nghĩa
là nó chỉ yêu cầu một dòng dữ liệu để giao tiếp với vi điều khiển của bạn
Trang 3Mỗi cảm biến có một số sê-ri 64 bit duy nhất, có nghĩa là bạn có thể kết nối nhiều cảm
biến với cùng một GPIO — như chúng ta sẽ làm trong hướng dẫn này Tìm hiểu thêm vềcảm biến nhiệt độ DS18B20:
Cảm biến nhiệt độ ESP8266 DS18B20 với Arduino IDE (Máy chủ Web, Đơn, Nhiều)
Sự kiện do máy chủ gửi
Các bài đọc được cập nhật tự động trên trang web bằng cách sử dụng Sự kiện do Máy
chủ Gửi (SSE)
Trang 4Để tìm hiểu thêm về SSE với ESP8266, bạn có thể đọc:
ESP8266 Máy chủ Web NodeMCU sử dụng các sự kiện do máy chủ gửi (Cập nhậtcảm biến đọc tự động)
Các tệp được lưu trên hệ thống tệp (LittleFS)
Để giữ cho dự án của chúng tôi được tổ chức tốt hơn và dễ hiểu hơn, chúng tôi sẽ lưu
các tệp HTML, CSS và JavaScript để xây dựng trang web trên hệ thống tệp của bảng
(LittleFS)
Tìm hiểu thêm về cách sử dụng LittleFS với ESP8266, bạn có thể đọc:
Cài đặt ESP8266 NodeMCU LittleFS Filesystem Uploader trong Arduino IDE
Điều kiện tiên quyết
Hãy chắc chắn rằng bạn kiểm tra tất cả các điều kiện tiên quyết trong phần này trước khitiếp tục với dự án
1 Cài đặt bảng ESP8266 trong Arduino IDE
Chúng tôi sẽ lập trình ESP8266 bằng Arduino IDE Vì vậy, bạn phải cài đặt tiện ích bổ
sung ESP8266 Thực hiện theo hướng dẫn tiếp theo nếu bạn chưa có:
Cài đặt bo mạch ESP8266 trong Arduino IDE (Windows, Mac OS X, Linux)
Nếu bạn muốn sử dụng VS Code với tiện ích mở rộng PlatformIO, hãy làm theo hướng
dẫn tiếp theo để tìm hiểu cách lập trình ESP8266:
Trang 5Bắt đầu với VS Code và PlatformIO IDE cho ESP32 và ESP8266 (Windows, Mac
OS X, Linux Ubuntu)
2 Plugin Filesystem Uploader
Để tải các tệp HTML, CSS và JavaScript lên bộ nhớ flash ESP8266 (LittleFS), chúng tôi
sẽ sử dụng một plugin cho trình tải lên hệ thống tệp Arduino IDE: LittleFS Làm theo
hướng dẫn tiếp theo để cài đặt plugin tải lên hệ thống tệp:
Cài đặt ESP8266 NodeMCU LittleFS Filesystem Uploader trong Arduino IDE
Nếu bạn đang sử dụng VS Code với tiện ích mở rộng PlatformIO, hãy đọc hướng dẫn
sau để tìm hiểu cách tải tệp lên hệ thống tệp:
ESP8266 NodeMCU với VS Code và PlatformIO: Tải tệp lên hệ thống tệp (LittleFS)
3 Cài đặt thư viện
Để xây dựng dự án này, bạn cần cài đặt các thư viện sau:
Bạn có thể cài đặt hai thư viện đầu tiên bằng Trình quản lý thư viện Arduino Đi tới
Sketch > Include Library > Manage Libraries và tìm kiếm tên thư viện.
Các thư viện ESPAsyncWebServer và AsynTCP không có sẵn để cài đặt thông qua Trìnhquản lý thư viện Arduino, vì vậy bạn cần sao chép các tệp thư viện vào thư mục Thư viện
cài đặt Arduino Ngoài ra, trong Arduino IDE, bạn có thể vào Sketch > Include Library >
Add zip Library và chọn các thư viện bạn vừa tải xuống.
Cài đặt thư viện (VS Code + PlatformIO)
Nếu bạn đang lập trình ESP8266 bằng PlatformIO, bạn nên thêm các dòng sau vào tệpplatformio.ini để bao gồm các thư viện (cũng thay đổi tốc độ Serial Monitor thành
115200):
monitor_speed = 115200
lib_deps = ESP Async WebServer
arduino-libraries/Arduino_JSON @ 0.1.0
milesburton/ [email protected] ^3.9.1
paulstoffregen/ [email protected] ^2.3.5
Các bộ phận cần thiết
Để làm theo hướng dẫn này, bạn cần các phần sau:
ESP8266 (đọc bảng phát triển ESP8266 tốt nhất)
Cảm biến nhiệt độ 4x DS18B20 (một hoặc nhiều cảm biến) – phiên bản chống thấmnước
Điện trở 4.7k Ohm
Dây nhảy
Trang 6Nếu bạn không có bốn cảm biến DS18B20, bạn có thể sử dụng ba hoặc hai Ngoài ra,
bạn cũng có thể sử dụng các cảm biến khác (bạn cần sửa đổi mã) hoặc dữ liệu từ bất kỳnguồn nào khác (ví dụ: số đọc cảm biến nhận được qua MQTT, ESP-NOW hoặc các giátrị ngẫu nhiên — để thử nghiệm với dự án này )
Sơ đồ
Nối bốn cảm biến DS18B20 vào bo mạch của bạn
Đề xuất đọc: Tham khảo sơ đồ chân ESP8266: Bạn nên sử dụng chân GPIO nào?
Lấy địa chỉ của cảm biến DS18B20
Trang 7Mỗi cảm biến nhiệt độ DS18B20 có một số sê-ri được chỉ định Đầu tiên, bạn cần tìm con
số đó để gắn nhãn cho từng cảm biến cho phù hợp Bạn cần làm điều này để sau này
bạn biết bạn đang đọc nhiệt độ từ cảm biến nào
Tải mã sau lên ESP8266 Đảm bảo rằng bạn đã chọn đúng bo mạch và cổng COM
// Based on the OneWire library example
OneWire ds(4); //data wire connected to GPIO 4
bạn có thể thêm nhãn vật lý vào mỗi cảm biến
Mở Serial Monitor với tốc độ truyền 115200, nhấn nút RST / EN trên bo mạch và bạn sẽnhận được một cái gì đó như sau (nhưng với các địa chỉ khác nhau):
Trang 8Bỏ chọn tùy chọn "Tự động cuộn" để bạn có thể sao chép các địa chỉ Trong trường hợp
của chúng tôi, chúng tôi có các địa chỉ sau:
Bản phác thảo Arduino xử lý máy chủ web;
index.html: để xác định nội dung của trang web;
sytle.css: để tạo kiểu cho trang web;
Tập lệnh.js: để lập trình hành vi của trang web — xử lý các phản hồi, sự kiện của
máy chủ web, tạo biểu đồ, v.v
Trang 9Bạn nên lưu các tệp HTML, CSS và JavaScript bên trong một thư mục được gọi là dữ
liệu bên trong thư mục phác thảo Arduino, như thể hiện trong sơ đồ trước Chúng tôi sẽ
tải các tệp này lên hệ thống tệp ESP8266 (LittleFS)
Bạn có thể tải xuống tất cả các tệp dự án:
Tải xuống tất cả các tệp dự án Arduino
Tệp HTML
Sao chép nội dung sau vào tệp html chỉ mục
<! Complete project details:
https://randomnerdtutorials.com/esp8266-nodemcu-plot-readings-charts-multiple/ >
<!DOCTYPE html>
<html>
<head>
<title>ESP IOT DASHBOARD</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="favicon.png">
<link rel="stylesheet" type="text/css" href="style.css">
Trang 10Sao chép các kiểu sau vào tệp css kiểu của bạn
/* Complete project details: readings-charts-multiple/ */
Tệp JavaScript (tạo biểu đồ)
Sao chép nội dung sau vào tập lệnh.js tệp Dưới đây là danh sách chức năng của mã
này:
Trang 11khởi tạo giao thức nguồn sự kiện;
thêm trình nghe sự kiện cho sự kiện new_readings;
tạo biểu đồ;
nhận các bài đọc cảm biến mới nhất từ sự kiện new_readings và vẽ chúng trong
biểu đồ;
thực hiện yêu cầu HTTP GET cho các bài đọc cảm biến hiện tại khi bạn truy cập
trang web lần đầu tiên
Trang 12// Complete project details: readings-charts-multiple/
https://randomnerdtutorials.com/esp8266-nodemcu-plot-// Get current sensor readings when the page loads
window.addEventListener('load', getReadings);
// Create Temperature Chart
var chartT = new Highcharts.Chart({
Trang 13for (var i = 0; i < keys.length; i++){
var x = (new Date()).getTime();
Trang 14Thêm trình nghe sự kiện gọi hàm getReadings khi trang web tải.
// Get current sensor readings when the page loads
window.addEventListener('load', getReadings);
Đối tượng cửa sổ đại diện cho một cửa sổ đang mở trong trình duyệt Phương thức
addEventListener() thiết lập một hàm được gọi khi một sự kiện nhất định xảy ra Trong
trường hợp này, chúng ta sẽ gọi hàm getReadings khi trang tải ('load') để nhận số đọc
cảm biến hiện tại
Bây giờ, chúng ta hãy xem hàm getReadings Chúng tôi sẽ gửi một yêu cầu HTTP để
ESP biết rằng nó cần gửi các bài đọc mới Khi ESP nhận được yêu cầu này, nó sẽ đặt lại
bộ hẹn giờ để gửi một sự kiện mới với các bài đọc
Tạo một đối tượng XMLHttpRequest mới Sau đó, gửi một yêu cầu GET đến máy chủ
trên URL /readings bằng cách sử dụng các phương thức open() và send()
function getReadings() {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/readings", true);
xhr.send();
}
Trang 15Khi chúng tôi gửi yêu cầu đó, ESP sẽ gửi phản hồi Vì vậy, chúng ta cần xử lý những gìxảy ra khi chúng ta nhận được phản hồi Chúng ta sẽ sử dụng thuộc tính
onreadystatechange để định nghĩa một hàm sẽ được thực thi khi thuộc tính readyState
thay đổi Thuộc tính readyState giữ trạng thái của XMLHttpRequest Phản hồi của yêu
cầu đã sẵn sàng khi readyState là 4 và trạng thái là 200
readyState = 4 có nghĩa là yêu cầu đã hoàn thành và phản hồi đã sẵn sàng;
status = 200 có nghĩa là "OK"
Trong trường hợp của chúng tôi, chúng tôi sẽ chỉ ghi lại phản hồi ESP (thông báo "OK")
Vì vậy, yêu cầu sẽ trông giống như thế này:
Trang 16// Create Temperature Chart
var chartT = new Highcharts.Chart({
Trang 17text: 'Temperature Celsius Degrees'
var chartT = new Highcharts.Chart({
Trong dòng tiếp theo, xác định nơi bạn muốn đặt biểu đồ Trong ví dụ của chúng ta,
chúng ta muốn đặt nó trong phần tử HTML với id nhiệt độ biểu đồ — xem phần tệp
đường kẻ — bạn có thể thay đổi nó thành bất kỳ màu nào bạn muốn
Tiếp theo, xác định các thuộc tính đánh dấu Bạn có thể chọn từ một số biểu tượng mặcđịnh—hình vuông, hình tròn, hình kim cương, hình tam giác , hình tam giác xuống Bạn
cũng có thể tạo các biểu tượng của riêng mình Bán kính đề cập đến kích thước của
điểm đánh dấu và fillColor đề cập đến màu của điểm đánh dấu Có các thuộc tính khác
mà bạn có thể sử dụng để tùy chỉnh điểm đánh dấu—tìm hiểu thêm
Trang 18Có nhiều tùy chọn khác mà bạn có thể sử dụng để tùy chỉnh loạt phim của mình — hãy
kiểm tra tài liệu về plotOptions
Bạn cũng có thể xác định tiêu đề biểu đồ — trong trường hợp này, vì chúng tôi đã xác
định tiêu đề cho biểu đồ trong tiêu đề của tệp HTML, chúng tôi sẽ không đặt tiêu đề ở
đây Tiêu đề được hiển thị theo mặc định, vì vậy chúng ta phải đặt nó thành undefined
title: {
text: undefined
},
Xác định các thuộc tính cho trục X — đây là trục nơi chúng ta sẽ hiển thị dữ liệu và thời
gian Kiểm tra thêm tùy chọn để tùy chỉnh trục X
Nếu, vì lý do nào đó, sau khi xây dựng dự án, các biểu đồ không hiển thị múi giờ phù
hợp, hãy thêm các dòng sau vào tệp JavaScript sau dòng thứ hai:
Vì vậy, hãy thêm điều đó khi tạo biểu đồ như sau:
var chart = new Highcharts.Chart({
time:{
useUTC: false
},
(…)
Trang 19Để tìm hiểu thêm về chỗ nghỉ này, hãy kiểm tra liên kết này trên tài liệu:
for (var i = 0; i < keys.length; i++){
var x = (new Date()).getTime();
Đầu tiên, chúng ta lấy các khóa của đối tượng JSON và lưu chúng vào biến khóa Điều
này cho phép chúng ta đi qua tất cả các phím trong đối tượng
var keys = Object.keys(jsonValue);
Biến keys sẽ là một mảng với tất cả các key trong đối tượng JSON Trong trường hợp
của chúng tôi:
["sensor1", "sensor2", "sensor3", "sensor4"]
Điều này hoạt động nếu bạn có một đối tượng JSON với số lượng khóa khác nhau hoặcvới các khóa khác nhau Sau đó, chúng ta sẽ đi qua tất cả các khóa (keys.length()) để vẽtừng giá trị của nó trong biểu đồ
Trang 20Giá trị x cho biểu đồ là dấu thời gian.
var x = (new Date()).getTime()
Biến khóa giữ khóa hiện tại trong vòng lặp Lần đầu tiên chúng ta đi qua vòng lặp, biến
chính là "sensor1"
const key = keys[i];
Sau đó, chúng ta lấy giá trị của khóa (jsonValue[key]) và lưu nó dưới dạng một số trongbiến y
Biểu đồ của chúng tôi có nhiều chuỗi (chỉ số bắt đầu từ 0) Chúng ta có thể truy cập chuỗiđầu tiên trong
biểu đồ nhiệt độ bằng cách sử dụng: chartT.series [0], tương ứng với chartT.series [i] lầnđầu tiên chúng ta đi qua vòng lặp
Đầu tiên, chúng tôi kiểm tra độ dài dữ liệu chuỗi:
Nếu chuỗi có hơn 40 điểm: thêm và dịch chuyển một điểm mới;
Hoặc nếu chuỗi có ít hơn 40 điểm: thêm một điểm mới
Để thêm một điểm mới, hãy dùng phương thức addPoint() chấp nhận các đối số sau đây:Giá trị được vẽ Nếu nó là một số duy nhất, một điểm có giá trị y đó được
nối vào chuỗi Nếu nó là một mảng, nó sẽ được hiểu là giá trị x và y Trong trườnghợp của chúng ta, chúng ta truyền một mảng với các giá trị x và y;
Tùy chọn vẽ lại (boolean): đặt thành true để vẽ lại biểu đồ sau khi thêm điểm
Tùy chọn dịch chuyển (boolean): Nếu đúng, một điểm sẽ bị dịch chuyển khỏi đầu
chuỗi khi một điểm được nối vào cuối Khi độ dài biểu đồ lớn hơn 40, chúng tôi đặttùy chọn shift thành true
withEvent option (boolean): Được sử dụng nội bộ để kích hoạt chuỗi sự kiện
addPoint—tìm hiểu thêm tại đây
Vì vậy, để thêm một điểm vào biểu đồ, chúng tôi sử dụng các dòng tiếp theo:
Tạo một đối tượng EventSource mới và chỉ định URL của trang gửi cập nhật Trong
trường hợp của chúng tôi, đó là /events
Trang 21if (!!window.EventSource) {
var source = new EventSource('/events');
Khi bạn đã khởi tạo nguồn sự kiện, bạn có thể bắt đầu nghe thư từ máy chủ bằng
Khi các bài đọc mới có sẵn, ESP8266 sẽ gửi một sự kiện (new_readings) cho khách
hàng Các dòng sau đây xử lý những gì xảy ra khi trình duyệt nhận được sự kiện đó
Bản phác thảo Arduino
Sao chép mã sau vào Arduino IDE của bạn hoặc vào tệp chính.cpp nếu bạn đang sử
dụng PlatformIO
Trang 22// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Create AsyncWebServer object on port 80
unsigned long lastTime = 0;
unsigned long timerDelay = 30000;
// GPIO where the DS18B20 sensors are connected to
const int oneWireBus = 4;
// Setup a oneWire instance to communicate with OneWire devices (DS18B20)
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
// Address of each sensor
DeviceAddress sensor3 = { 0x28, 0xFF, 0xA0, 0x11, 0x33, 0x17, 0x3, 0x96 };
Trang 23// Web Server Root URL
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LittleFS, "/index.html", "text/html");
});
server.serveStatic("/", LittleFS, "/");
// Request for the latest sensor readings
server.on("/readings", HTTP_GET, [](AsyncWebServerRequest *request){
lastTime = lastTime + timerDelay;
request->send(200, "text/plain", "OK!");
Trang 24// and set reconnect delay to 1 second
client->send("hello!", NULL, millis(), 10000);
if ((millis() - lastTime) > timerDelay) {
// Send Events to the client with the Sensor Readings Every 10 seconds
Chúng ta hãy xem mã và xem nó hoạt động như thế nào để gửi các bài đọc đến máy
khách bằng cách sử dụng các sự kiện do máy chủ gửi
Bao gồm cả thư viện
Các thư viện OneWire và DallasTemperature là cần thiết để giao tiếp với các cảm biến
Các tệp HTML, CSS và JavaScript để xây dựng trang web được lưu trên hệ thống tệp
ESP8266 (LittleFS) Vì vậy, chúng ta cũng cần bao gồm thư viện LitteFS
#include "LittleFS.h"
Bạn cũng cần bao gồm thư viện Arduino_JSON để xử lý các chuỗi JSON dễ dàng hơn
#include <Arduino_JSON.h>
Thông tin đăng nhập mạng
Chèn thông tin đăng nhập mạng của bạn vào các biến sau, để ESP8266 có thể kết nối
với mạng cục bộ của bạn bằng Wi-Fi