23 подписчика

ESP8266 асинхронный веб-сервер

Рассмотрим программу скелет для микроконтроллера ESP8266, которую в дальнейшем можно будет использовать для своих проектов. Программа выполняет условия:   1. Подключение к WiFi сети
  2.

Рассмотрим программу скелет для микроконтроллера ESP8266, которую в дальнейшем можно будет использовать для своих проектов. Программа выполняет условия:

1. Подключение к WiFi сети
2. Управление через веб сервер
3. Одновременный доступ с разных устройств
4. Текущее состояние в реальном времени отображается на всех устройствах

Будем включать/отключать встроенный светодиод на плате. Регулировать его яркость

Рассмотрим программу скелет для микроконтроллера ESP8266, которую в дальнейшем можно будет использовать для своих проектов. Программа выполняет условия:   1. Подключение к WiFi сети
  2.-2

Прочитать про ESP8266 - тут
Как подключить плату к Arduino IDE -
тут

Чтобы к устройству могли подключаться несколько клиентов нужно установить библиотеки

ESPAsyncTCP - https://github.com/me-no-dev/ESPAsyncTCP
ESPAsyncWebServer -
https://github.com/me-no-dev/ESPAsyncWebServer

Встроенный светодиод (LED_BUILTIN) находится на пине GPIO2 и его поведение инвертировано. При подаче LOW он включается и наоборот

Скетч

Написан в среде Arduino IDE

// подключение библиотек
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>


// объявление переменных и констант
const char* NetworkName = "*"; // имя сети
const char* Password = "*"; // пароль доступа

byte attempts = 10; // кол-во попыток подключения к сети
int ledState = HIGH; // состояние светодиода
int brightness = 0; // состояние яркости светодиода

// веб сервер на 80 порту
AsyncWebServer server(80);

// страничка HTML, которая будет отображается при обращение через браузер

Рассмотрим программу скелет для микроконтроллера ESP8266, которую в дальнейшем можно будет использовать для своих проектов. Программа выполняет условия:   1. Подключение к WiFi сети
  2.-3

// PROGMEM – записывается на флеш память
// в <style> задаем размер чекбокса
// %CHECKBOXPLACEHOLDER%, %RANGEPLACEHOLDER% - сюда при заходе
// на сервер
// будут помещаться компоненты с текущим состоянием
// toggleCheckbox – функция AJAX для вкл/выкл светодиода
// toggleRange - функция AJAX для изменения яркости светодиода
// +две функции которые через AJAX будут получать текущие состояние
// светодиода,
// и менять параметры на странице, если произошло изменение на другом
// клиенте
// одна будет выполняться с интервалом в 1 сек, другая 5 сек

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<meta charset="UTF-8">
<title>LED_1</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
#output1{
transform:scale(1.3);
opacity:0.9;
cursor:pointer;
}

</style></head>
<body>
<p><big>Лампочка1:</big>&nbsp;&nbsp;%CHECKBOXPLACEHOLDER%</p>
<p><big>Яркость:</big>&nbsp;&nbsp;%RANGEPLACEHOLDER%</p>

<script>
function toggleCheckbox(element) {
var xhr = new XMLHttpRequest();
if(element.checked){ xhr.open("GET", "/update?state1=1", true); }
else { xhr.open("GET", "/update?state1=0", true); }
xhr.send();
}
setInterval(function ( ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var inputChecked;
if( this.responseText == 1){
inputChecked = false;
}
else {
inputChecked = true;
}
document.getElementById("output1").checked = inputChecked;
}
};
xhttp.open("GET", "/state1", true);
xhttp.send();
}, 1000 ) ;

function toggleRange(element) {
var xhr = new XMLHttpRequest();
if(document.getElementById("output1").checked){ xhr.open("GET", "/update?state2="+document.getElementById("output2").value, true); }
xhr.send();
}

setInterval(function ( ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var inputChecked = this.responseText;
document.getElementById("output2").value = inputChecked;
}
};
xhttp.open("GET", "/state2", true);
xhttp.send();
}, 5000 ) ;

</script></body></html>
)rawliteral";

// функция берет текущие значения состояния светодиода,
// и проставляет при загрузке на страницу,
// вместе с созданием компонентов
String processor(const String& var){
String buttons ="";
if(var == "CHECKBOXPLACEHOLDER"){
String outputStateValue = outputState1();
buttons+= "<input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"output1\" " + outputStateValue + ">";
return buttons;
} else
if(var == "RANGEPLACEHOLDER"){
buttons+= "<input type=\"range\" onchange=\"toggleRange(this)\" id=\"output2\" min=\"0\" max=\"200\" value=\""+String(brightness)+"\" >";
return buttons;
}
return String();
}


// получить состояние светодиода
String outputState1(){
if(ledState == HIGH){
return "";
}
else {
return "checked";
}
return "";
}


//константы для функции update
const char* PARAM_INPUT_1 = "state1";
const char* PARAM_INPUT_2 = "state2";

void setup() {
pinMode(LED_BUILTIN, OUTPUT);

Serial.begin(115200);

// подключаемся к сети WiFi
// attempts - попыток

WiFi.begin(NetworkName,Password);
while(--attempts && WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}


// если подключение прошло удачно выводим ip адрес
if(WiFi.status() != WL_CONNECTED){
Serial.println("");
Serial.println("Non Connecting");
} else {
Serial.println("");
Serial.println("Connected");
Serial.print("IP:");
Serial.println(WiFi.localIP());
}

// первоначальное состояние светодиода
digitalWrite(LED_BUILTIN, ledState);

// при переходе на сервер по ссылке name получим имя нашего проекта
// в следующей статье напишу пример приложения для телефона для поиска
// объектов в сети

server.on("/name", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "LED_1");
});


// формирование главной страницы
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});


// обновляем значения состояния светодиода. Получаем их от клиента
// PARAM_INPUT_1 – вкл/выкл
// PARAM_INPUT_2 - яркость

server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
if (request->hasParam(PARAM_INPUT_1)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
digitalWrite(LED_BUILTIN, !inputMessage.toInt());
ledState = !ledState;
brightness = 0;
} else
if (request->hasParam(PARAM_INPUT_2)) {
inputMessage = request->getParam(PARAM_INPUT_2)->value();
int brig = inputMessage.toInt();
Serial.println(String(brig));
if(brig<0) brig =0;
if(brig>255) brig =255;
analogWrite(LED_BUILTIN,brig);
brightness = brig;
}
else {
inputMessage = "No message sent";
}
request->send(200, "text/plain", "OK");
});


// текущие состояние вкл/выкл
server.on("/state1", HTTP_GET, [] (AsyncWebServerRequest *request) {
if(ledState == HIGH) request->send(200, "text/plain", "1");
else request->send(200, "text/plain", "0");
});


// текущие состояние яркости
server.on("/state2", HTTP_GET, [] (AsyncWebServerRequest *request) {
request->send(200, "text/plain", String(brightness).c_str());
});


//запуск сервера
server.begin();
}
void loop() {}

Что можно сделать?

С помощью этого примера сделаю уличную светодиодную лампочку, управляемую через телефон. С возможностями вкл/выкл, управление яркостью, отображением температуры

Ссылки

ESP8266
https://aliexpress.ru/item/32831353752.html https://aliexpress.ru/item/1005001621784437.html https://aliexpress.ru/item/32635160765.html

Скетч - https://disk.yandex.ru/d/BKBgK9hJ5vjT2w