Hướng dẫn này chỉ ra cách xây dựng máy chủ web ESP8266 NodeMCU bằng thanh trượt để kiểm soát độ sáng LED. Bạn sẽ học cách thêm thanh trượt vào các dự án máy chủ web của mình, lấy giá trị của nó và lưu nó vào một biến mà ESP8266 có thể sử dụng. Chúng tôi sẽ sử dụng giá trị đó để kiểm soát chu kỳ hoạt động của tín hiệu PWM và thay đổi độ sáng của đèn LED. Thay vì đèn LED, bạn có thể điều khiển động cơ servo chẳng hạn.
Trang 1ESP8266 NodeMCU Web Server với thanh trượt: Điều
khiển độ sáng LED (PWM)
Hướng dẫn này chỉ ra cách xây dựng máy chủ web ESP8266 NodeMCU bằng thanh
trượt để kiểm soát độ sáng LED Bạn sẽ học cách thêm thanh trượt vào các dự án máy chủ web của mình, lấy giá trị của nó và lưu nó vào một biến mà ESP8266 có thể sử
dụng Chúng tôi sẽ sử dụng giá trị đó để kiểm soát chu kỳ hoạt động của tín hiệu PWM
và thay đổi độ sáng của đèn LED Thay vì đèn LED, bạn có thể điều khiển động cơ servo chẳng hạn
Ngoài ra, bạn cũng có thể sửa đổi mã trong hướng dẫn này để thêm thanh trượt vào các
dự án của mình để đặt giá trị ngưỡng hoặc bất kỳ giá trị nào khác mà bạn cần sử dụng
trong mã của mình
Tổng quan dự án
Trang 2ESP8266 lưu trữ một máy chủ web hiển thị một trang web với một thanh trượt;
Khi bạn di chuyển thanh trượt, bạn thực hiện một yêu cầu HTTP ESP8266 với giá trị thanh trượt mới;
Yêu cầu HTTP có định dạng sau: GET/slider?value=SLIDERVALUE, trong đó
SLIDERVALUE là một số từ 0 đến 1023 Bạn có thể sửa đổi thanh trượt của mình
để bao gồm bất kỳ phạm vi nào khác;
Từ yêu cầu HTTP, ESP8266 nhận giá trị hiện tại của thanh trượt;
ESP8266 điều chỉnh chu kỳ nhiệm vụ PWM phù hợp với giá trị thanh trượt;
Điều này có thể hữu ích để kiểm soát độ sáng của đèn LED (như chúng ta sẽ làm trong ví dụ này), động cơ servo, thiết lập giá trị ngưỡng hoặc các ứng dụng khác
Điều kiện tiên quyết
Trước khi tiến hành dự án này, hãy đảm bảo bạn kiểm tra các điều kiện tiên quyết sau
Arduino IDE
Chúng tôi sẽ lập trình bo mạch ESP8266 NodeMCU bằng Arduino IDE, vì vậy trước khi tiếp tục với hướng dẫn này, hãy đảm bảo rằng bạn đã cài đặt bảng ESP8266 trong
Arduino IDE của mình
Cài đặt bảng mạch ESP8266 NodeMCU trong Arduino IDE (Windows, Mac OS X và Linux)
Thư viện máy chủ web không đồng bộ
Trang 3Chúng ta sẽ xây dựng máy chủ web bằng các thư viện sau:
ESPAsyncWebServer
ESPAsyncTCP
Các thư viện này không có sẵn để cài đặt thông qua Trình quả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
Mã
Đoạn mã sau đây kiểm soát độ sáng của đèn LED tích hợp ESP8266 bằng cách sử dụng thanh trượt trên máy chủ web Nói cách khác, bạn có thể thay đổi chu kỳ nhiệm vụ PWM bằng thanh trượt Điều này có thể hữu ích để kiểm soát độ sáng LED hoặc điều khiển
động cơ servo chẳng hạn
Sao chép mã vào Arduino IDE của bạn Chèn thông tin đăng nhập mạng của bạn và mã
sẽ hoạt động thẳng
Trang 4/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-web-server-slider-pwm/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software
*********/
// Import required libraries
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
const int output = 2;
String sliderValue = "0";
const char* PARAM_INPUT = "value";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ESP Web Server</title>
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
h2 {font-size: 2.3rem;}
p {font-size: 1.9rem;}
body {max-width: 400px; margin:0px auto; padding-bottom: 25px;}
.slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px; background: #FFD65C;
outline: none; -webkit-transition: 2s; transition: opacity 2s;}
.slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none;
width: 35px; height: 35px; background: #003249; cursor: pointer;}
.slider::-moz-range-thumb { width: 35px; height: 35px; background: #003249;
cursor: pointer; }
</style>
</head>
<body>
<h2>ESP Web Server</h2>
<p><span id="textSliderValue">%SLIDERVALUE%</span></p>
<p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="1023" value="%SLIDERVALUE%" step="1" class="slider"></p>
<script>
function updateSliderPWM(element) {
Trang 5var sliderValue = document.getElementById("pwmSlider").value;
document.getElementById("textSliderValue").innerHTML = sliderValue;
console.log(sliderValue);
var xhr = new XMLHttpRequest();
xhr.open("GET", "/slider?value="+sliderValue, true);
xhr.send();
}
</script>
</body>
</html>
)rawliteral";
// Replaces placeholder with button section in your web page
String processor(const String& var){
//Serial.println(var);
if (var == "SLIDERVALUE"){
return sliderValue;
}
return String();
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
analogWrite(output, sliderValue.toInt());
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi ");
}
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
// Send a GET request to <ESP_IP>/slider?value=<inputMessage>
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
// GET input1 value on <ESP_IP>/slider?value=<inputMessage>
if (request->hasParam(PARAM_INPUT)) {
inputMessage = request->getParam(PARAM_INPUT)->value();
sliderValue = inputMessage;
analogWrite(output, sliderValue.toInt());
}
else {
inputMessage = "No message sent";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
Trang 6});
// Start server
server.begin();
}
void loop() {
}
Xem mã thô
Mã hoạt động như thế nào
Tiếp tục đọc để tìm hiểu cách mã hoạt động hoặc chuyển sang phần tiếp theo
Nhập thư viện
Đầu tiên, nhập các thư viện cần thiết ESP8266WiFi, ESPAsyncWebServer và
ESPAsyncTCP là cần thiết để xây dựng máy chủ web
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
Đặt thông tin đăng nhập mạng của bạn
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
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Định nghĩa biến
Chúng tôi sẽ kiểm soát độ sáng của đèn LED tích hợp ESP8266 Đèn LED tích hợp
tương ứng với GPIO 2 Lưu GPIO mà chúng ta muốn kiểm soát trên biến đầu ra
const int output = 2;
Biến sliderValue sẽ giữ giá trị thanh trượt Khi bắt đầu, nó được đặt thành không
String sliderValue = "0";
Thông số đầu vào
Biến PARAM_INPUT sẽ được sử dụng để "tìm kiếm" giá trị thanh trượt theo yêu cầu mà ESP8266 nhận được khi thanh trượt được di chuyển (Hãy nhớ rằng: ESP8266 sẽ nhận được một yêu cầu như thế này GET/slider?value=SLIDERVALUE)
const char* PARAM_INPUT = "value";
Nó sẽ tìm kiếm giá trị trên URL và nhận được giá trị được gán cho nó
Trang 7Xây dựng trang Web
Bây giờ chúng ta hãy tiến hành trang máy chủ web
Trang web cho dự án này khá đơn giản Nó chứa một tiêu đề, một đoạn văn và một đầu vào của phạm vi kiểu
Hãy xem cách trang web được tạo
Tất cả văn bản HTML với các kiểu được bao gồm được lưu trữ trong biến index_html
Bây giờ chúng ta sẽ đi qua văn bản HTML và xem mỗi phần làm gì
Thẻ <meta> sau đây làm cho trang web của bạn đáp ứng trong bất kỳ trình duyệt nào
<meta name="viewport" content="width=device-width, initial-scale=1">
Giữa các thẻ <title> </title> là tiêu đề của máy chủ web của chúng tôi Tiêu đề là văn bản hiển thị trên tab trình duyệt web
Phong cách
Giữa các thẻ <style></style>, chúng tôi thêm một số CSS để tạo kiểu cho trang web
Trang 8<style>
html {font-family: Arial; display: inline-block; text-align: center;}
h2 {font-size: 2.3rem;}
p {font-size: 1.9rem;}
body {max-width: 400px; margin:0px auto; padding-bottom: 25px;}
slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px;
background: #FFD65C;
outline: none; -webkit-transition: 2s; transition: opacity 2s;}
slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none;
width: 35px; height: 35px; background: #003249; cursor: pointer;}
slider::-moz-range-thumb { width: 35px; height: 35px; background: #003249;
cursor: pointer; }
</style>
Về cơ bản, chúng tôi đang thiết lập trang HTML để hiển thị văn bản với phông chữ Arial trong khối không có lề và được căn chỉnh ở giữa
html {font-family: Arial; display: inline-block; text-align: center;}
Các dòng sau đây đặt kích thước phông chữ cho tiêu đề (h2) và đoạn (p)
h2 {font-size: 2.3rem;}
p {font-size: 1.9rem;}
Đặt thuộc tính nội dung HTML
body {max-width: 400px; margin:0px auto; padding-bottom: 25px;}
Các dòng sau đây tùy chỉnh thanh trượt:
.slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px;
background: #FFD65C;
outline: none; -webkit-transition: 2s; transition: opacity 2s;}
.slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; background: #003249; cursor: pointer;}
.slider::-moz-range-thumb { width: 35px; height: 35px; background: #003249;
cursor: pointer; }
Nội dung HTML
Bên trong thẻ <body></body> là nơi chúng tôi thêm nội dung trang web
Thẻ <h2></h2> thêm tiêu đề vào trang web Trong trường hợp này, văn bản "Máy chủ
web ESP", nhưng bạn có thể thêm bất kỳ văn bản nào khác
<h2>ESP Web Server</h2>
Đoạn đầu tiên sẽ chứa giá trị thanh trượt hiện tại Thẻ HTML cụ thể đó có id
textSliderValue gán cho nó, để chúng ta có thể tham chiếu nó sau này
<p><span id="textSliderValue">%SLIDERVALUE%</span></p>
Trang 9%SLIDERVALUE% là chỗ dành sẵn cho giá trị thanh trượt Điều này sẽ được thay thế
bằng ESP8266 bằng một giá trị thực tế khi nó gửi nó đến trình duyệt Điều này rất hữu
ích để hiển thị giá trị hiện tại khi bạn truy cập trình duyệt lần đầu tiên
Tạo thanh trượt
Để tạo thanh trượt trong HTML, bạn sử dụng thẻ <input> Thẻ <input> chỉ định một
trường nơi người dùng có thể nhập dữ liệu
Có rất nhiều loại đầu vào Để xác định thanh trượt, hãy sử dụng thuộc tính "type" với giá trị "range" Trong thanh trượt, bạn cũng cần xác định phạm vi tối thiểu và tối đa bằng
cách sử dụng các thuộc tính "min" và "max" (trong trường hợp này lần lượt là 0 và
1023)
<p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0"
max="1023" value="%SLIDERVALUE%" step="1" class="slider"></p>
Bạn cũng cần xác định các thuộc tính khác như:
Thuộc tính STEP chỉ định khoảng thời gian giữa các số hợp lệ Trong trường hợp
của chúng tôi, nó được đặt thành 1;
lớp để tạo kiểu cho thanh trượt (class = "thanh trượt");
ID để cập nhật vị trí hiện tại được hiển thị trên trang web;
thuộc tính onchange để gọi một hàm (updateSliderPWM(this)) để gửi yêu cầu
HTTP đến ESP8266 khi thanh trượt di chuyển Từ khóa này đề cập đến giá trị hiện tại của thanh trượt
Thêm JavaScript vào tệp HTML
Tiếp theo, bạn cần thêm một số mã JavaScript vào tệp HTML của mình bằng cách sử
dụng thẻ <script> và </script> Bạn cần thêm hàm updateSliderPWM() sẽ đưa ra yêu cầu đến ESP8266 với giá trị thanh trượt hiện tại
<script>
function updateSliderPWM(element) {
var sliderValue = document.getElementById("pwmSlider").value;
document.getElementById("textSliderValue").innerHTML = sliderValue;
console.log(sliderValue);
var xhr = new XMLHttpRequest();
xhr.open("GET", "/slider?value="+sliderValue, true);
xhr.send();
}
</script>
Dòng tiếp theo này lấy giá trị thanh trượt hiện tại bằng id của nó và lưu nó vào biến
JavaScript sliderValue Trước đây, chúng ta đã gán id của thanh trượt cho pwmSlider Vì vậy, chúng tôi nhận được nó như sau:
var sliderValue = document.getElementById("pwmSlider").value;
Trang 10Sau đó, chúng tôi đặt nhãn thanh trượt (có id là textSliderValue) thành giá trị được lưu
trên biến sliderValue
Cuối cùng, thực hiện một yêu cầu HTTP GET
var xhr = new XMLHttpRequest();
xhr.open("GET", "/slider?value="+sliderValue, true);
xhr.send();
Ví dụ: khi thanh trượt là 0, bạn thực hiện một yêu cầu HTTP GET trên URL sau:
http://ESP-IP-ADDRESS/slider?value=0
Và khi giá trị thanh trượt là 200, bạn sẽ có một yêu cầu trên URL theo dõi
http://ESP-IP-ADDRESS/slider?value=200
Bằng cách này, khi ESP8266 nhận được yêu cầu GET, nó có thể truy xuất tham số giá trị trong URL và kiểm soát tín hiệu PWM tương ứng như chúng ta sẽ se trong các phần tiếp theo
Xử lý
Bây giờ, chúng ta cần tạo hàm processor(), hàm này sẽ thay thế các trình giữ chỗ trong văn bản HTML của chúng ta bằng giá trị thanh trượt hiện tại khi bạn truy cập nó lần đầu tiên trong trình duyệt
// Replaces placeholder with button section in your web page
String processor(const String& var){
//Serial.println(var);
if (var == "SLIDERVALUE"){
return sliderValue;
}
return String();
}
Khi trang web được yêu cầu, chúng tôi sẽ kiểm tra xem HTML có bất kỳ trình giữ chỗ nào
không Nếu nó tìm thấy chỗ dành sẵn %SLIDERVALUE%, chúng ta trả về giá trị đã lưu
trên biến sliderValue
Thiết lập()
Trong setup(), khởi tạo Serial Monitor cho mục đích gỡ lỗi
Serial.begin(115200);
Đặt chu kỳ nhiệm vụ của tín hiệu PWM thành giá trị được lưu trên thanh trượt (khi
ESP8266 khởi động, nó được đặt thành 0)
analogWrite(output, sliderValue.toInt());
Trang 11Để tìm hiểu thêm về PWM với ESP8266 , hãy đọc hướng dẫn của chúng tôi: ESP8266
PWM với Arduino IDE (Đầu ra tương tự)
Kết nối với mạng cục bộ của bạn và in địa chỉ IP ESP8266
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi ");
}
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
Xử lý yêu cầu
Cuối cùng, thêm các dòng mã tiếp theo để xử lý máy chủ web
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
// Send a GET request to <ESP_IP>/slider?value=<inputMessage>
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
// GET input1 value on <ESP_IP>/slider?value=<inputMessage>
if (request->hasParam(PARAM_INPUT)) {
inputMessage = request->getParam(PARAM_INPUT)->value();
sliderValue = inputMessage;
ledcWrite(ledChannel, sliderValue.toInt());
}
else {
inputMessage = "No message sent";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});
Khi chúng tôi thực hiện một yêu cầu trên URL gốc, chúng tôi gửi văn bản HTML được lưu trữ trên biến index_html Chúng ta cũng cần truyền hàm processor(), hàm này sẽ thay thế tất cả các placeholder bằng các giá trị phù hợp
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
Chúng tôi cần một bộ xử lý khác sẽ lưu giá trị thanh trượt hiện tại và đặt độ sáng LED
cho phù hợp