Tải bản đầy đủ (.pdf) (26 trang)

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

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (751.59 KB, 26 trang )

ESP8266 Máy chủ Web NodeMCU (WebSocket) với
nhiều thanh trượt: Điều khiển độ sáng đèn LED (PWM)
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ọ.

Bạn cũng có thể sửa đổi mã được trình bày trong hướng dẫn này để thêm thanh trượt
vào 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.
Đối với dự án này, bo mạch ESP8266 sẽ được lập trình bằng lõi Arduino. Bạn có thể sử
dụng Arduino IDE, VS Code với PlatformIO hoặc bất kỳ IDE phù hợp nào khác.
Để hiểu rõ hơn về cách thức hoạt động của dự án này, chúng tôi khuyên bạn nên xem
các hướng dẫn sau:
* Dự án này chỉ ra cách xây dựng một máy chủ web với một thanh trượt, nhưng nó sử
dụng các yêu cầu HTTP — trong hướng dẫn này, chúng ta sẽ sử dụng giao thức
WebSocket.
Chúng tơi có một hướng dẫn tương tự cho bảng ESP32:
1/26


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

Tổng quan dự án
Hình ảnh sau đây cho thấy trang web mà chúng ta sẽ xây dựng cho dự án này:

Trang web chứa ba thẻ;


Mỗi thẻ có một đoạn để hiển thị tiêu đề thẻ (Fader 1, Fader 2, Fader 3);
Có một thanh trượt phạm vi trong mỗi thẻ mà bạn có thể di chuyển để đặt độ sáng
của đèn LED tương ứng;
Trong mỗi thẻ, một đoạn khác hiển thị độ sáng LED hiện tại (theo tỷ lệ phần trăm);
Khi bạn đặt vị trí mới cho thanh trượt, nó sẽ cập nhật tất cả các 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 sẽ cập nhật gần
như đồng thời bất cứ khi nào có thay đổi).

Nó hoạt động như thế nào?
ESP lưu trữ một máy chủ web hiển thị một trang web với ba thanh trượt;
Khi bạn đặt vị trí mới cho thanh trượt, máy khách sẽ gửi số thanh trượt và giá trị
thanh trượt đến máy chủ thông qua giao thức WebSocket. Ví dụ: nếu bạn đặt thanh
trượt số 3 thành vị trí số 40, nó sẽ gửi thông báo này 3s40 đến máy chủ.

2/26


Máy chủ (ESP) nhận số thanh trượt và giá trị tương ứng và điều chỉnh chu kỳ
nhiệm vụ PWM cho phù hợp. Ngồi ra, nó cũng thơng báo cho tất cả các máy
khách khác với các giá trị thanh trượt hiện tại mới — điều này cho phép chúng tôi
cập nhật tất cả các máy khách gần như ngay lập tức.

3/26


ESP8266 xuất tín hiệu PWM với chu kỳ làm việc tương ứng để kiểm soát độ sáng
LED. Chu kỳ làm việc 0% có nghĩa là đèn LED tắt hồn tồn, chu kỳ làm việc 50%
có nghĩa là đèn LED sáng một nửa và chu kỳ làm việc 100% có nghĩa là đèn LED
sáng;


Bất cứ khi nào bạn mở một cửa sổ trình duyệt web mới (đây là khi một máy khách
mới kết nối), nó sẽ gửi một 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 được thơng báo này, nó
sẽ gửi các giá trị thanh trượt hiện tại. Bằng cách này, bất cứ khi nào bạn mở một
tab mới, nó ln hiển thị các giá trị hiện tại và cập nhật.

Điều kiện tiên quyết
Trước khi tiếp tục với hướng dẫn này, hãy đảm bảo bạn kiểm tra tất cả các điều kiện tiên
quyết sau.

1) Các bộ 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 nhấ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 chỉ cần xem kết quả trong Màn
hình nối tiếp hoặc sử dụng các thiết bị truyền động khác u cầu tín hiệu PWM để hoạt
động.
Bạn có thể sử dụng các liên kết trước đó hoặc truy cập trực tiếp vào
MakerAdvisor.com/tools để tìm tất cả các phần cho các dự án của mình với giá tốt nhất!

2) Tiện ích bổ sung bảng Arduino IDE và ESP8266
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:
Bắt đầu với VS Code và PlatformIO IDE cho ESP32 và ESP8266 (Windows, Mac
OS X, Linux Ubuntu)

3) Plugin tải lên hệ thống tệp
Để tải lên các tệp HTML, CSS và JavaScript cần thiết để xây dựng dự án này 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 nếu bạn chưa có:
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)

4) Thư viện
Để xây dựng dự án này, bạn cần cài đặt các thư viện sau:

5/26


Bạn có thể cài đặt 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à ESPAsynTCP 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.
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ệp

platformio.ini để bao gồm các thư viện (cũng thay đổi tốc độ Serial Monitor thành 115200
và đặ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 tôi đang sử dụng GPIO 12 (D6), 13 (D7) và 14
(D5). Bạn có thể sử dụng bất kỳ GPIO phù hợp nào 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 các tệp của bạn
Để giữ cho dự án được tổ chức và dễ hiểu hơn, chúng tôi sẽ 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 của trang web;

7/26


Sytle.css: để tạo kiểu cho trang web;
script.js: để lập trình hành vi của trang web—xử lý những gì xảy ra khi bạn di

chuyển thanh trượt, gửi, nhận và giải thích các tin nhắn nhận được qua giao thức
WebSocket.

Bạ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.

8/26


<!-- Complete project details: -->

<!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">


</head>

<body>

<div class="topnav">

Multiple Sliders



</div>

<div class="content">

<div class="card-grid">

<div class="card">

Fader 1





id="slider1" min="0" max="100" step="1" value ="0" class="slider">



Brightness: <span id="sliderValue1"></span>
%



</div>


<div class="card">

Fader 2





id="slider2" min="0" max="100" step="1" value ="0" class="slider">



Brightness: <span id="sliderValue2"></span>
%



</div>

<div class="card">

Fader 3





id="slider3" min="0" max="100" step="1" value ="0" class="slider">



Brightness: <span id="sliderValue3"></span>
%




</div>

</div>

</div>

<script src="script.js"></script>

</body>

</html>

Xem mã thơ
Chúng ta hãy xem nhanh các phần có liên quan nhất của tệp HTML.

Tạo thanh trượt
9/26


Các thẻ sau tạo thẻ cho thanh trượt đầu tiên (Fader 1).
<div class="card">

Fader 1





max="100" step="1" value ="0" class="slider">




Brightness: <span id="sliderValue1"></span> %



</div>

Đoạn đầu tiên hiển thị tiêu đề cho thẻ (Fader 1). Bạn có thể thay đổi văn bản thành bất
cứ điều gì bạn muốn.

Fader 1



Để 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 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 tối thiểu và tối đa (trong trường hợp này là 0 và 100, tương ứng).
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, chúng tơi đặt nó thành 1;
lớp để tạo kiểu cho thanh trượt (class = "thanh trượt");
id để chúng ta có thể thao tác với giá trị thanh trượt bằng JavaScript (id = "slider1");
thuộc tính onchange để gọi một hàm (updateSliderPWM(this)) khi bạn đặt vị trí mới
cho thanh trượt. Hàm này (được định nghĩa trong tệp JavaScript) gửi giá trị thanh
trượt hiện tại thông qua giao thức WebSocket đến máy khách. Từ khóa này đề cập
đến phần tử thanh trượt HTML.
Thanh trượt nằm bên trong một đoạn văn với tên lớp chuyển đổi. Vì vậy, đây là các thẻ
thực sự tạo thanh trượt.



max="100" step="1" value ="0" class="slider">





Cuối cùng, có một đoạn văn với thẻ <span>, để chúng ta có thể chèn giá trị thanh trượt
hiện tại vào đoạn đó bằng cách tham chiếu đến id của nó (id = "sliderValue1").

Brightness: <span id="sliderValue1"></span> %



Tạo thêm thanh trượt

10/26


Để tạo thêm thanh trượt, bạn cần sao chép tất cả các thẻ HTML tạo thẻ hoàn chỉnh. Tuy
nhiên, trước tiên, bạn cần xem xét rằng bạn cần một id duy nhất cho mỗi giá trị thanh
trượt và thanh trượt. Trong trường hợp của chúng tơi, chúng tơi có ba thanh trượt với các
id sau: slider1, slider2, slider3 và ba trình giữ chỗ cho giá trị thanh trượt với các id sau:
sliderValue1, sliderValue2, sliderValue3.
Ví dụ: đây là thẻ cho thanh trượt số 2.
<div class="card">

Fader 2





max="100" step="1" value ="0" class="slider">



Brightness: <span id="sliderValue2"></span> %




</div>

Tệp CSS
Sao chép nội dung sau vào tệp .css kiểu.

11/26


/* Complete project details: */

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: 0 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: 0 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 hãy xem nhanh các phần có liên quan của tệp CSS tạo kiểu cho thanh trượt.
Trong ví dụ này, chúng ta cần sử dụng tiền tố vendor cho thuộc tính appearance.
.slider {

-webkit-appearance: none;

margin: 0 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ố của nhà cung cấp cho phép trình duyệt hỗ trợ các tính năng CSS mới trước khi
chúng được hỗ trợ đầy đủ. Các trình duyệt được sử dụng phổ biến nhất sử dụng các tiền
tố sau:
-webkit- Chrome, Safari, các phiên bản Opera mới hơn, hầu hết tất cả các trình
duyệt iOS,
-moz- Firefox,
-o- Phiên bản cũ của Opera,
-ms- Microsoft Edge và Internet Explorer.
Tiền tố nhà cung cấp là tạm thời. Khi các thuộc tính được hỗ trợ đầy đủ bởi trình duyệt
bạn sử dụng, bạn khơng cần chúng. Bạn có thể sử dụng tham chiếu sau để kiểm tra xem
thuộc tính bạn đang sử dụng có cần tiền tố hay không: />Chúng ta hãy xem bộ chọn .slider (tạo kiểu cho thanh trượt):
.slider {

-webkit-appearance: none;

margin: 0 auto;


width: 100%;

height: 15px;

border-radius: 10px;

background: #FFD65C;outline: none;

}

Đặt -webkit-appearance thành none sẽ ghi đè các kiểu CSS mặc định được áp dụng cho
thanh trượt trong trình duyệt Google Chrome, Safari và Android.
-webkit-appearance: none;

Đặt lề thành 0 tự động căn chỉnh thanh trượt bên trong vùng chứa chính của nó.
margin: 0 auto;

Chiều rộng của thanh trượt được đặt thành 100% và chiều cao thành 15px. Bán kính
viền được đặt thành 10px.
margin: 0 auto;

width: 100%;

height: 15px;

border-radius: 10px;

Đặt màu nền cho thanh trượt và đặt đường viền thành không có.
background: #FFD65C;


outline: none;

Sau đó, định dạng núm điều khiển thanh trượt. Sử dụng -webkit- cho các trình duyệt web
Chrome, Opera, Safari và Edge và -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 và appearance thành none để ghi đè các thuộc tính
mặc định.
-webkit-appearance: none;

appearance: none;

Đặt chiều rộng, chiều cao và bán kính đường viền cụ thể cho trình xử lý. Đặt cùng chiều
rộng và chiều cao với bán kính đường viền 50% sẽ tạo ra một vịng trịn.
width: 30px;

height: 30px;

border-radius: 50%;

Sau đó, đặt màu cho nền và đặt con trỏ thành con trỏ.
background: #034078;

cursor: pointer;

Hãy thoải mái chơi với các thuộc tính thanh trượt để tạo cho nó một cái 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: />
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 đây là danh sách chức năng của 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 các giá trị thanh trượt hiện tại;
sử dụng phản hồi để cập nhật các giá trị thanh trượt trên trang web;
xử lý trao đổi dữ liệu thông qua giao thức WebSocket.
Chúng ta hãy xem mã JavaScript này để xem nó hoạt động như thế nào.
Cổng là điểm vào giao diện WebSocket. window.location.hostname lấy địa chỉ trang hiện
tại (địa chỉ IP máy chủ web).
var gateway = ws://${window.location.hostname}/ws;

Tạo một biến toàn cục mới gọi là websocket.
var websocket;

Thêm trình nghe sự kiện sẽ gọi hàm onload khi 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 trên cổng được xác định trước đó.
Chúng tơi cũng gán một số chức năng gọi lại khi kết nối WebSocket được mở, đóng hoặc
khi nhận được 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 ý rằng khi kết nối websocket mở ra, chúng ta sẽ gọi hàm getValues.
function onOpen(event) {

console.log('Connection opened');

getValues();

}

Hàm getValues() gửi một thông báo đến máy chủ getValues để lấy giá trị hiện tại của tất
cả các thanh trượt. Sau đó, chúng ta phải xử lý những gì xảy ra khi chúng ta nhận được
thơng báo đó ở phía máy chủ (ESP8266).
function getStates(){

websocket.send("getValues");


}

17/26


Chúng tôi xử lý các tin nhắn nhận được qua giao thức websocket trên 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 các trạng thái ở định dạng JSON, ví dụ:
{

sliderValue1: 20;


sliderValue2: 50;

sliderValue3: 0;

}

Hàm onMessage() chỉ đơn giản là đi qua tất cả các giá trị và đặt chúng vào các vị trí
tương ứng trên trang HTML.
Hàm updateSliderPWM() chạy khi bạn di chuyển thanh 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 này lấy giá trị từ thanh trượt và cập nhật đoạn tương ứng với giá trị phù hợp. Chức
năng này cũng 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 được gửi theo định dạng sau:
thanh trượtsốsthanh trượt

Ví dụ: nếu bạn di chuyển thanh trượt số 3 đến vị trí 40, nó sẽ gửi thơng báo sau:
3s40

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.

18/26


/*

Rui Santos

Complete project details at />
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


<Arduino.h>

<ESP8266WiFi.h>

<ESPAsyncTCP.h>

<ESPAsyncWebServer.h>

"LittleFS.h"

<Arduino_JSON.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 == 0 && 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



×