1. Trang chủ
  2. » Công Nghệ Thông Tin

ESP8266 Máy chủ Web NodeMCU (WebSocket) với nhiều thanh trượt: Điều khiển độ sáng đèn LED (PWM)

26 3 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 26
Dung lượng 751,59 KB

Nội dung

Hướng dẫn này chỉ ra cách xây dựng một máy chủ web với bảng ESP8266 NodeMCU hiển thị một trang web có nhiều thanh trượt. Các thanh trượt điều khiển chu kỳ làm việc của các tín hiệu PWM khác nhau để kiểm soát độ sáng của nhiều đèn LED. Thay vì đèn LED, bạn có thể sử dụng dự án này để điều khiển động cơ DC hoặc các thiết bị truyền động khác yêu cầu tín hiệu PWM. Giao tiếp giữa máy khách và ESP8266 được thực hiện bằng giao thức WebSocket. Ngoài ra, bất cứ khi nào có thay đổi, tất cả khách hàng sẽ cập nhật đồng thời các giá trị thanh trượt của họ.

ESP8266 Máy chủ Web NodeMCU (WebSocket) với nhiều trượt: Điều khiển độ sáng đèn LED (PWM) Hướng dẫn cách xây dựng máy chủ web với bảng ESP8266 NodeMCU hiển thị trang web có nhiều trượt Các trượt điều khiển chu kỳ làm việc tín hiệu PWM khác để kiểm sốt độ sáng nhiều đèn LED Thay đèn LED, bạn sử dụng dự án để điều khiển động DC thiết bị truyền động khác yêu cầu tín hiệu PWM Giao tiếp máy khách ESP8266 thực giao thức WebSocket Ngồi ra, có thay đổi, tất khách hàng cập nhật đồng thời giá trị trượt họ Bạn sửa đổi mã trình bày hướng dẫn để thêm trượt vào dự án để đặt giá trị ngưỡng giá trị khác mà bạn cần sử dụng mã Đối với dự án này, bo mạch ESP8266 lập trình lõi Arduino Bạn sử dụng Arduino IDE, VS Code với PlatformIO IDE phù hợp khác Để hiểu rõ cách thức hoạt động dự án này, khuyên bạn nên xem hướng dẫn sau: * Dự án cách xây dựng máy chủ web với trượt, sử dụng yêu cầu HTTP — hướng dẫn này, sử dụng giao thức WebSocket Chúng tơi có hướng dẫn tương tự cho bảng ESP32: 1/26 Máy chủ web ESP32 (WebSocket) với nhiều trượt: Điều khiển độ sáng đèn LED (PWM) Tổng quan dự án Hình ảnh sau cho thấy trang web mà xây dựng cho dự án này: Trang web chứa ba thẻ; Mỗi thẻ có đoạn để hiển thị tiêu đề thẻ (Fader 1, Fader 2, Fader 3); Có trượt phạm vi thẻ mà bạn di chuyển để đặt độ sáng đèn LED tương ứng; Trong thẻ, đoạn khác hiển thị độ sáng LED (theo tỷ lệ phần trăm); Khi bạn đặt vị trí cho trượt, cập nhật tất máy khách (nếu bạn mở nhiều tab trình duyệt web (hoặc nhiều thiết bị), chúng cập nhật gần đồng thời có thay đổi) Nó hoạt động nào? ESP lưu trữ máy chủ web hiển thị trang web với ba trượt; Khi bạn đặt vị trí cho trượt, máy khách gửi số trượt giá trị trượt đến máy chủ thơng qua giao thức WebSocket Ví dụ: bạn đặt trượt số thành vị trí số 40, gửi thơng báo 3s40 đến máy chủ 2/26 Máy chủ (ESP) nhận số trượt giá trị tương ứng điều chỉnh chu kỳ nhiệm vụ PWM cho phù hợp Ngồi ra, thơng báo cho tất máy khách khác với giá trị trượt — điều cho phép cập nhật tất máy khách gần 3/26 ESP8266 xuất tín hiệu PWM với chu kỳ làm việc tương ứng để kiểm sốt độ sáng LED Chu kỳ làm việc 0% có nghĩa đèn LED tắt hoàn toàn, chu kỳ làm việc 50% có nghĩa đèn LED sáng nửa chu kỳ làm việc 100% có nghĩa đèn LED sáng; Bất bạn mở cửa sổ trình duyệt web (đây máy khách kết nối), gửi tin nhắn đến ESP8266 (cũng thông qua giao thức WebSocket) với thông báo getValues Khi ESP8266 nhận thơng báo này, gửi giá trị trượt Bằng cách này, bạn mở tab mới, ln hiển thị giá trị cập nhật Điều kiện tiên Trước tiếp tục với hướng dẫn này, đảm bảo bạn kiểm tra tất điều kiện tiên sau 1) Các phận cần thiết Để theo dõi dự án này, bạn cần: 4/26 Bảng mạch ESP8266 NodeMCU - đọc Bảng phát triển Wi-Fi ESP8266 tốt Hướng dẫn mua 3x đèn LED Điện trở 3x 220Ohm Breadboard Dây nhảy Bạn không cần ba đèn LED để kiểm tra dự án này, bạn cần xem kết Màn hình nối tiếp sử dụng thiết bị truyền động khác yêu cầu tín hiệu PWM để hoạt động Bạn sử dụng liên kết trước truy cập trực tiếp vào MakerAdvisor.com/tools để tìm tất phần cho dự án với giá tốt nhất! 2) Tiện ích bổ sung bảng Arduino IDE ESP8266 Chúng tơi lập trình ESP8266 Arduino IDE Vì vậy, bạn phải cài đặt tiện ích bổ sung ESP8266 Thực theo hướng dẫn bạn chưa có: Cài đặt bo mạch ESP8266 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, làm theo hướng dẫn để tìm hiểu cách lập trình ESP8266: Bắt đầu với VS Code PlatformIO IDE cho ESP32 ESP8266 (Windows, Mac OS X, Linux Ubuntu) 3) Plugin tải lên hệ thống tệp Để tải lên tệp HTML, CSS JavaScript cần thiết để xây dựng dự án lên nhớ flash ESP8266 (LittleFS), sử dụng plugin cho trình tải lên hệ thống tệp Arduino IDE: LittleFS Làm theo hướng dẫn để cài đặt plugin tải lên hệ thống tệp bạn chưa có: Cài đặt ESP8266 NodeMCU LittleFS Filesystem Uploader Arduino IDE Nếu bạn sử dụng VS Code với tiện ích mở rộng PlatformIO, đọ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 PlatformIO: Tải tệp lên hệ thống tệp (LittleFS) 4) Thư viện Để xây dựng dự án này, bạn cần cài đặt thư viện sau: 5/26 Bạn cài đặt thư viện Trình quản lý thư viện Arduino Đi tới Sketch > Include Library > Manage Libraries tìm kiếm tên thư viện Các thư viện ESPAsyncWebServer ESPAsynTCP khơng có sẵn để cài đặt thơng qua Trình quản lý thư viện Arduino, bạn cần chép tệp thư viện vào thư mục Thư viện cài đặt Arduino Ngoài ra, Arduino IDE, bạn vào Sketch> Include Library > Add zip Library chọn thư viện bạn vừa tải xuống Cài đặt thư viện (VS Code + PlatformIO) Nếu bạn lập trình ESP8266 PlatformIO, bạn nên thêm dòng sau vào tệp platformio.ini để bao gồm thư viện (cũng thay đổi tốc độ Serial Monitor thành 115200 đặt hệ thống tệp littleFS): monitor_speed = 115200 board_build.filesystem = littlefs lib_deps = ESP Async WebServer arduino-libraries/Arduino_JSON @ 0.1.0 Sơ đồ Nối ba đèn LED với ESP8266 Chúng sử dụng GPIO 12 (D6), 13 (D7) 14 (D5) Bạn sử dụng GPIO phù hợp khác 6/26 Đề xuất đọc: Tham khảo sơ đồ chân ESP8266: Bạn nên sử dụng chân GPIO nào? Sắp xếp tệp bạn Để giữ cho dự án tổ chức dễ hiểu hơn, tạo bốn tệp để xây dựng máy chủ web: Bản phác thảo Arduino xử lý máy chủ web; index.html: để xác định nội dung trang web; 7/26 Sytle.css: để tạo kiểu cho trang web; script.js: để lập trình hành vi trang web—xử lý xảy bạn di chuyển trượt, gửi, nhận giải thích tin nhắn nhận qua giao thức WebSocket Bạn nên lưu tệp HTML, CSS JavaScript bên thư mục gọi liệu bên thư mục phác thảo Arduino, thể sơ đồ trước Chúng tải tệp lên hệ thống tệp ESP8266 (LittleFS) Bạn tải xuống tất tệp dự án: Tải xuống tất tệp dự án Arduino Tệp HTML Sao chép nội dung sau vào tệp html mục 8/26 ESP IOT DASHBOARD Multiple Sliders

Fader 1

Brightness: %

Fader 2

Brightness: %

Fader 3

Brightness: %

Xem mã thơ Chúng ta xem nhanh phần có liên quan tệp HTML Tạo trượt 9/26 Các thẻ sau tạo thẻ cho trượt (Fader 1)

Fader 1

Brightness: %

Đoạn hiển thị tiêu đề cho thẻ (Fader 1) Bạn thay đổi văn thành điều bạn muốn

Fader 1

Để tạo trượt HTML, bạn sử dụng thẻ Thẻ định trường nơi người dùng nhập liệu Có nhiều loại đầu vào Để xác định trượt, dùng thuộc tính type với giá trị range Trong trượt, bạn cần xác định phạm vi tối thiểu tối đa cách sử dụng thuộc tính tối thiểu tối đa (trong trường hợp 100, tương ứng) Bạn cần xác định thuộc tính khác như: Thuộc tính STEP định khoảng thời gian số hợp lệ Trong trường hợp chúng tơi, chúng tơi đặt thành 1; lớp để tạo kiểu cho trượt (class = "thanh trượt"); id để thao tác với giá trị trượt JavaScript (id = "slider1"); thuộc tính onchange để gọi hàm (updateSliderPWM(this)) bạn đặt vị trí cho trượt Hàm (được định nghĩa tệp JavaScript) gửi giá trị trượt thông qua giao thức WebSocket đến máy khách Từ khóa đề cập đến phần tử trượt HTML Thanh trượt nằm bên đoạn văn với tên lớp chuyển đổi Vì vậy, thẻ thực tạo trượt

Cuối cùng, có đoạn văn với thẻ , để chèn giá trị trượt vào đoạn cách tham chiếu đến id (id = "sliderValue1")

Brightness: %

Tạo thêm trượt 10/26 /* Complete project details: https://randomnerdtutorials.com/esp8266-nodemcu-webserver-websocket-sliders/ */ html { font-family: Arial, Helvetica, sans-serif; display: inline-block; text-align: center; } h1 { font-size: 1.8rem; color: white; } p { font-size: 1.4rem; } topnav { overflow: hidden; background-color: #0A1128; } body { margin: 0; } content { padding: 30px; } card-grid { max-width: 700px; margin: auto; display: grid; grid-gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } card { background-color: white; box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5); } card-title { font-size: 1.2rem; font-weight: bold; color: #034078 } state { font-size: 1.2rem; color:#1282A2; } slider { -webkit-appearance: none; margin: auto; width: 100%; height: 15px; border-radius: 10px; background: #FFD65C; outline: none; } slider::-webkit-slider-thumb { -webkit-appearance: none; 12/26 appearance: none; width: 30px; height: 30px; border-radius: 50%; background: #034078; cursor: pointer; } slider::-moz-range-thumb { width: 30px; height: 30px; border-radius: 50% ; background: #034078; cursor: pointer; } switch { padding-left: 5%; padding-right: 5%; } Xem mã thơ Chúng ta xem nhanh phần có liên quan tệp CSS tạo kiểu cho trượt Trong ví dụ này, cần sử dụng tiền tố vendor cho thuộc tính appearance .slider { -webkit-appearance: none; margin: auto; width: 100%; height: 15px; border-radius: 10px; background: #FFD65C; outline: none; } slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 30px; height: 30px; border-radius: 50%; background: #034078; cursor: pointer; } slider::-moz-range-thumb { width: 30px; height: 30px; border-radius: 50% ; background: #034078; cursor: pointer; } switch { padding-left: 5%; padding-right: 5%; } Tiền tố nhà cung cấp 13/26 Tiền tố nhà cung cấp cho phép trình duyệt hỗ trợ tính CSS trước chúng hỗ trợ đầy đủ Các trình duyệt sử dụng phổ biến sử dụng tiền tố sau: -webkit- Chrome, Safari, phiên Opera hơn, hầu hết tất trình duyệt iOS, -moz- Firefox, -o- Phiên cũ Opera, -ms- Microsoft Edge Internet Explorer Tiền tố nhà cung cấp tạm thời Khi thuộc tính hỗ trợ đầy đủ trình duyệt bạn sử dụng, bạn khơng cần chúng Bạn sử dụng tham chiếu sau để kiểm tra xem thuộc tính bạn sử dụng có cần tiền tố hay khơng: http://shouldiprefix.com/ Chúng ta xem chọn slider (tạo kiểu cho trượt): slider { -webkit-appearance: none; margin: auto; width: 100%; height: 15px; border-radius: 10px; background: #FFD65C;outline: none; } Đặt -webkit-appearance thành none ghi đè kiểu CSS mặc định áp dụng cho trượt trình duyệt Google Chrome, Safari Android -webkit-appearance: none; Đặt lề thành tự động chỉnh trượt bên vùng chứa margin: auto; Chiều rộng trượt đặt thành 100% chiều cao thành 15px Bán kính viền đặt thành 10px margin: auto; width: 100%; height: 15px; border-radius: 10px; Đặt màu cho trượt đặt đường viền thành khơng có background: #FFD65C; outline: none; Sau đó, định dạng núm điều khiển trượt Sử dụng -webkit- cho trình duyệt web Chrome, Opera, Safari Edge -moz- cho Firefox 14/26 .slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 30px; height: 30px; border-radius: 50%; background: #034078; cursor: pointer; } slider::-moz-range-thumb { width: 30px; height: 30px; border-radius: 50% ; background: #034078; cursor: pointer; } Đặt thuộc tính -webkit-appearance appearance thành none để ghi đè thuộc tính mặc định -webkit-appearance: none; appearance: none; Đặt chiều rộng, chiều cao bán kính đường viền cụ thể cho trình xử lý Đặt chiều rộng chiều cao với bán kính đường viền 50% tạo vòng tròn width: 30px; height: 30px; border-radius: 50%; Sau đó, đặt màu cho đặt trỏ thành trỏ background: #034078; cursor: pointer; Hãy thoải mái chơi với thuộc tính trượt để tạo cho nhìn khác Tệp JavaScript Sao chép nội dung sau vào tập lệnh.js tệp 15/26 // Complete project details: https://randomnerdtutorials.com/esp8266-nodemcu-webserver-websocket-sliders/ var gateway = `ws://${window.location.hostname}/ws`; var websocket; window.addEventListener('load', onload); function onload(event) { initWebSocket(); } function getValues(){ websocket.send("getValues"); } function initWebSocket() { console.log('Trying to open a WebSocket connection…'); websocket = new WebSocket(gateway); websocket.onopen = onOpen; websocket.onclose = onClose; websocket.onmessage = onMessage; } function onOpen(event) { console.log('Connection opened'); getValues(); } function onClose(event) { console.log('Connection closed'); setTimeout(initWebSocket, 2000); } function updateSliderPWM(element) { var sliderNumber = element.id.charAt(element.id.length-1); var sliderValue = document.getElementById(element.id).value; document.getElementById("sliderValue"+sliderNumber).innerHTML = sliderValue; console.log(sliderValue); websocket.send(sliderNumber+"s"+sliderValue.toString()); } function onMessage(event) { console.log(event.data); var myObj = JSON.parse(event.data); var keys = Object.keys(myObj); for (var i = 0; i < keys.length; i++){ var key = keys[i]; document.getElementById(key).innerHTML = myObj[key]; document.getElementById("slider"+ (i+1).toString()).value = myObj[key]; } } Xem mã thô Dưới danh sách chức mã này: 16/26 khởi tạo kết nối WebSocket với máy chủ; gửi tin nhắn đến máy chủ để nhận giá trị trượt tại; sử dụng phản hồi để cập nhật giá trị trượt trang web; xử lý trao đổi liệu thông qua giao thức WebSocket Chúng ta xem mã JavaScript để xem hoạt động Cổng điểm vào giao diện WebSocket window.location.hostname lấy địa trang (địa IP máy chủ web) var gateway = ws://${window.location.hostname}/ws; Tạo biến toàn cục gọi websocket var websocket; Thêm trình nghe kiện gọi hàm onload trang web tải window.addEventListener('load', onload); Hàm onload() gọi hàm initWebSocket() để khởi tạo kết nối WebSocket với máy chủ function onload(event) { initWebSocket(); } Hàm initWebSocket() khởi tạo kết nối WebSocket cổng xác định trước Chúng tơi gán số chức gọi lại kết nối WebSocket mở, đóng nhận tin nhắn function initWebSocket() { console.log('Trying to open a WebSocket connection…'); websocket = new WebSocket(gateway); websocket.onopen = onOpen; websocket.onclose = onClose; websocket.onmessage = onMessage; } Lưu ý kết nối websocket mở ra, gọi hàm getValues function onOpen(event) { console.log('Connection opened'); getValues(); } Hàm getValues() gửi thông báo đến máy chủ getValues để lấy giá trị tất trượt Sau đó, phải xử lý xảy nhận thơng báo phía máy chủ (ESP8266) function getStates(){ websocket.send("getValues"); } 17/26 Chúng xử lý tin nhắn nhận qua giao thức websocket hàm onMessage() function onMessage(event) { console.log(event.data); var myObj = JSON.parse(event.data); var keys = Object.keys(myObj); for (var i = 0; i < keys.length; i++){ var key = keys[i]; document.getElementById(key).innerHTML = myObj[key]; document.getElementById("slider"+ (i+1).toString()).value = myObj[key]; } } Máy chủ gửi trạng thái định dạng JSON, ví dụ: { sliderValue1: 20; sliderValue2: 50; sliderValue3: 0; } Hàm onMessage() đơn giản qua tất giá trị đặt chúng vào vị trí tương ứng trang HTML Hàm updateSliderPWM() chạy bạn di chuyển trượt function updateSliderPWM(element) { var sliderNumber = element.id.charAt(element.id.length-1); var sliderValue = document.getElementById(element.id).value; document.getElementById("sliderValue"+sliderNumber).innerHTML = sliderValue; console.log(sliderValue); websocket.send(sliderNumber+"s"+sliderValue.toString()); } Hàm lấy giá trị từ trượt cập nhật đoạn tương ứng với giá trị phù hợp Chức gửi tin nhắn đến máy chủ để ESP8266 cập nhật độ sáng LED websocket.send(sliderNumber+"s"+sliderValue.toString()); Tin nhắn gửi theo định dạng sau: trượtsốsthanh trượt Ví dụ: bạn di chuyển trượt số đến vị trí 40, gửi thơng báo sau: 3s40 Bản phác thảo Arduino Sao chép mã sau vào Arduino IDE bạn vào tệp chính.cpp bạn sử dụng PlatformIO 18/26 /* Rui Santos Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-webserver-websocket-sliders/ 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 */ #include #include #include #include #include #include "LittleFS.h" // 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 AsyncWebServer server(80); // Create a WebSocket object AsyncWebSocket ws("/ws"); // Set LED GPIO const int ledPin1 = 14; const int ledPin2 = 12; const int ledPin3 = 13; String String String String message = ""; sliderValue1 = "0"; sliderValue2 = "0"; sliderValue3 = "0"; int dutyCycle1; int dutyCycle2; int dutyCycle3; //Json Variable to Hold Slider Values JSONVar sliderValues; //Get Slider Values String getSliderValues(){ sliderValues["sliderValue1"] = String(sliderValue1); sliderValues["sliderValue2"] = String(sliderValue2); sliderValues["sliderValue3"] = String(sliderValue3); String jsonString = JSON.stringify(sliderValues); return jsonString; } // Initialize LittleFS 19/26 void initFS() { if (!LittleFS.begin()) { Serial.println("An error has occurred while mounting LittleFS"); } else{ Serial.println("LittleFS mounted successfully"); } } // Initialize WiFi void initWiFi() { WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.print("Connecting to WiFi "); while (WiFi.status() != WL_CONNECTED) { Serial.print('.'); delay(1000); } Serial.println(WiFi.localIP()); } void notifyClients(String sliderValues) { ws.textAll(sliderValues); } void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) { AwsFrameInfo *info = (AwsFrameInfo*)arg; if (info->final && info->index == && info->len == len && info->opcode == WS_TEXT) { data[len] = 0; message = (char*)data; if (message.indexOf("1s") >= 0) { sliderValue1 = message.substring(2); dutyCycle1 = map(sliderValue1.toInt(), 0, 100, 0, 1023); Serial.println(dutyCycle1); Serial.print(getSliderValues()); notifyClients(getSliderValues()); } if (message.indexOf("2s") >= 0) { sliderValue2 = message.substring(2); dutyCycle2 = map(sliderValue2.toInt(), 0, 100, 0, 1023); Serial.println(dutyCycle2); Serial.print(getSliderValues()); notifyClients(getSliderValues()); } if (message.indexOf("3s") >= 0) { sliderValue3 = message.substring(2); dutyCycle3 = map(sliderValue3.toInt(), 0, 100, 0, 1023); Serial.println(dutyCycle3); Serial.print(getSliderValues()); notifyClients(getSliderValues()); } if (strcmp((char*)data, "getValues") == 0) { notifyClients(getSliderValues()); } } 20/26

Ngày đăng: 09/04/2023, 19:20

w