概述
【ESP32/ESP8266】TCP异步通讯点灯控制示例程序
- ✨本示例基于
Arduino
框架下开发。✨ - ????控制演示
????TCP异步和同步说明
????同步连接,是指服务器端在与第一个访问者请求建立连接并通信时,在此期间如果有第二个访问者请求将会被阻塞。然而通过异步连接,就可以实现服务器可以同时响应多个请求。
????所需库说明
- ????esp8266所需库:
- ????
ESPAsyncTCP
:https://github.com/me-no-dev/ESPAsyncTCP
- ???? esp32所需库:
- ????
AsyncTCP
:https://github.com/me-no-dev/AsyncTCP
- ????通用库:
-
ESPAsyncWebServer
:https://github.com/me-no-dev/ESPAsyncWebServer
????将下载下来的库解压后放置到
Arduino
安装目录下的对应库文件夹内,例如:C:Program Files (x86)Arduinolibraries
????程序代码
????本代码默认定义的是esp8266 GPIO引脚,如需修改为esp32只需修改对应的引脚定义即可。
//引入核心库
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>//https://github.com/me-no-dev/AsyncTCP
#else
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>//https://github.com/me-no-dev/ESPAsyncTCP
#endif
#include <ESPAsyncWebServer.h>//https://github.com/me-no-dev/ESPAsyncWebServer
// 填写自己的WiFi信息
const char* ssid = "***";
const char* password = "***";
const char* PARAM_INPUT_1 = "state"; //为输入状态定义字符串参数
//控制引脚定义
const int LED_OUTPUT = 2; // GPIO 27 作为输出引脚
const int Push_Button = 14; // GPIO 26 作为输入引脚
// Variables will change:
int ledState = LOW; // 当前输出引脚状态值
int buttonState; // 读取当前输入引脚的状态
int lastButtonState = LOW; // 存储输入引脚上一次的值
// 定义无符号长整型变量,因为以毫秒为单位的时间很快就会变成一个比存储在int中的时间更大的数字。
unsigned long lastDebounceTime = 0; // 最后一次切换输出引脚时间
unsigned long debounceDelay = 50; // 消抖时间
// 创建异步服务对象,端口号80
AsyncWebServer server(80);
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<meta charset="utf-8">
<title>ESP32-ESP8266 Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
h2 {font-size: 3.0rem;}
p {font-size: 3.0rem;}
body {max-width: 600px; margin:0px auto; padding-bottom: 25px;}
.switch {position: relative; display: inline-block; width: 120px; height: 68px}
.switch input {display: none}
.slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #FF0000; border-radius: 34px}
.slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 68px}
input:checked+.slider {background-color: #008000}
input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
</style>
</head>
<body>
<center><h3 style="color: green;">ESP32-ESP8266网页控制界面</center><hr/>
%BUTTONPLACEHOLDER%
<script>function toggleCheckbox(element) {
var xhr = new XMLHttpRequest();
if(element.checked){ xhr.open("GET", "/update?state=1", true); }
else { xhr.open("GET", "/update?state=0", true); }
xhr.send();
}
setInterval(function ( ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var inputChecked;
var outputStateM;
if( this.responseText == 1){
inputChecked = true;
outputStateM = "On";
}
else {
inputChecked = false;
outputStateM = "Off";
}
document.getElementById("output").checked = inputChecked;
document.getElementById("outputState").innerHTML = outputStateM;
}
};
xhttp.open("GET", "/state", true);
xhttp.send();
}, 1000 ) ;
</script>
</body>
</html>
)rawliteral";
// 将网页中的按钮部分替换为占位符
String processor(const String& var){
//Serial.println(var);
if(var == "BUTTONPLACEHOLDER"){
String buttons ="";
String outputStateValue = outputState();
buttons+= "<h4 style='color: red;'>输出引脚 - GPIO 2 - 当前状态: <span id="outputState"></span></h4><label class="switch"><input type="checkbox" οnchange="toggleCheckbox(this)" id="output" " + outputStateValue + "><span class="slider"></span></label><br/>";
return buttons;
}
return String();
}
String outputState(){
if(digitalRead(LED_OUTPUT)){
return "checked";
}
else {
return "";
}
return "";
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
pinMode(LED_OUTPUT, OUTPUT);
digitalWrite(LED_OUTPUT, LOW);
pinMode(Push_Button, INPUT);//按键控制
//连接 Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
//打印IP地址
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>/update?state=<inputMessage>
server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
String inputParam;
// GET input1 value on <ESP_IP>/update?state=<inputMessage>
if (request->hasParam(PARAM_INPUT_1)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
inputParam = PARAM_INPUT_1;
digitalWrite(LED_OUTPUT, inputMessage.toInt());
ledState = !ledState;
}
else {
inputMessage = "No message sent";
inputParam = "none";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});
// 发送GET请求 <ESP_IP>/state
server.on("/state", HTTP_GET, [] (AsyncWebServerRequest *request) {
request->send(200, "text/plain", String(digitalRead(LED_OUTPUT)).c_str());
});
// Start server
server.begin();
}
void loop() {
//读取开关状态到一个局部变量:
int reading = digitalRead(Push_Button);
//检查一下你是否按了按钮
//(即输入从LOW到HIGH),你已经等待了足够长的时间
//从上次按下按钮开始忽略任何杂音:
// 如果开关改变,判断是否由于干扰或真的按下:开始计时
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
//判断按键是否按下
if ((millis() - lastDebounceTime) > debounceDelay) {
// 判断按键状态是否改变
if (reading != buttonState) {
buttonState = reading;
// 按钮状态为高时切换LED状态
if (buttonState == HIGH) {
ledState = !ledState;
}
}
}
// 设置初始状态
digitalWrite(LED_OUTPUT, ledState);
// 保存状态:
lastButtonState = reading;
}
????程序代码
//引入核心库
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>//https://github.com/me-no-dev/AsyncTCP
#else
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>//https://github.com/me-no-dev/ESPAsyncTCP
#endif
#include <ESPAsyncWebServer.h>//https://github.com/me-no-dev/ESPAsyncWebServer
// 填写自己的WiFi信息
const char* ssid = "***";
const char* password = "***";
const char* PARAM_INPUT_1 = "state"; //为输入状态定义字符串参数
//控制引脚定义
const int LED_OUTPUT = 2; // GPIO 27 作为输出引脚
const int Push_Button = 14; // GPIO 26 作为输入引脚
// Variables will change:
int ledState = LOW; // 当前输出引脚状态值
int buttonState; // 读取当前输入引脚的状态
int lastButtonState = LOW; // 存储输入引脚上一次的值
// 以下变量是无符号长整型变量,因为以毫秒为单位的时间很快就会变成一个比存储在int中的时间更大的数字。
unsigned long lastDebounceTime = 0; // 最后一次切换输出引脚时间
unsigned long debounceDelay = 50; // 消抖时间
// 创建异步服务对象,端口号80
AsyncWebServer server(80);
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<meta charset="utf-8">
<title>ESP32-ESP8266 Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
h2 {font-size: 3.0rem;}
p {font-size: 3.0rem;}
body {max-width: 600px; margin:0px auto; padding-bottom: 25px;}
.switch {position: relative; display: inline-block; width: 120px; height: 68px}
.switch input {display: none}
.slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #FF0000; border-radius: 34px}
.slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 68px}
input:checked+.slider {background-color: #008000}
input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
</style>
</head>
<body>
<center><h3 style="color: green;">ESP32-ESP8266网页控制界面</center><hr/>
%BUTTONPLACEHOLDER%
<script>function toggleCheckbox(element) {
var xhr = new XMLHttpRequest();
if(element.checked){ xhr.open("GET", "/update?state=1", true); }
else { xhr.open("GET", "/update?state=0", true); }
xhr.send();
}
setInterval(function ( ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var inputChecked;
var outputStateM;
if( this.responseText == 1){
inputChecked = true;
outputStateM = "On";
}
else {
inputChecked = false;
outputStateM = "Off";
}
document.getElementById("output").checked = inputChecked;
document.getElementById("outputState").innerHTML = outputStateM;
}
};
xhttp.open("GET", "/state", true);
xhttp.send();
}, 1000 ) ;
</script>
</body>
</html>
)rawliteral";
// 将网页中的按钮部分替换为占位符
String processor(const String& var){
//Serial.println(var);
if(var == "BUTTONPLACEHOLDER"){
String buttons ="";
String outputStateValue = outputState();
buttons+= "<h4 style='color: red;'>输出引脚 - GPIO 2 - 当前状态: <span id="outputState"></span></h4><label class="switch"><input type="checkbox" οnchange="toggleCheckbox(this)" id="output" " + outputStateValue + "><span class="slider"></span></label><br/>";
return buttons;
}
return String();
}
String outputState(){
if(digitalRead(LED_OUTPUT)){
return "checked";
}
else {
return "";
}
return "";
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
pinMode(LED_OUTPUT, OUTPUT);
digitalWrite(LED_OUTPUT, LOW);
pinMode(Push_Button, INPUT);//按键控制
//连接 Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
//打印IP地址
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>/update?state=<inputMessage>
server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
String inputParam;
// GET input1 value on <ESP_IP>/update?state=<inputMessage>
if (request->hasParam(PARAM_INPUT_1)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
inputParam = PARAM_INPUT_1;
digitalWrite(LED_OUTPUT, inputMessage.toInt());
ledState = !ledState;
}
else {
inputMessage = "No message sent";
inputParam = "none";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});
// 发送GET请求 <ESP_IP>/state
server.on("/state", HTTP_GET, [] (AsyncWebServerRequest *request) {
request->send(200, "text/plain", String(digitalRead(LED_OUTPUT)).c_str());
});
// Start server
server.begin();
}
void loop() {
//读取开关状态到一个局部变量:
int reading = digitalRead(Push_Button);
//检查一下你是否按了按钮
//(即输入从LOW到HIGH),你已经等待了足够长的时间
//从上次按下按钮开始忽略任何杂音:
// 如果开关改变,判断是否由于干扰或真的按下:开始计时
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// 判断按键状态是否改变
if (reading != buttonState) {
buttonState = reading;
// 按钮状态为高时切换LED状态
if (buttonState == HIGH) {
ledState = !ledState;
}
}
}
// 设置初始状态
digitalWrite(LED_OUTPUT, ledState);
// 保存状态:
lastButtonState = reading;
}
- 选择
esp8266
-nodemcu1.0
编译信息
使用 1.0 版本的库 ESP8266WiFi 在文件夹: C:UsersAdministratorAppDataLocalArduino15packagesesp8266hardwareesp82663.0.2librariesESP8266WiFi
使用 1.2.2 版本的库 ESPAsyncTCP 在文件夹: C:UsersAdministratorDocumentsArduinolibrariesESPAsyncTCP
使用 1.2.3 版本的库 ESPAsyncWebServer 在文件夹: C:UsersAdministratorDocumentsArduinolibrariesESPAsyncWebServer
使用 1.0 版本的库 Hash 在文件夹: C:UsersAdministratorAppDataLocalArduino15packagesesp8266hardwareesp82663.0.2librariesHash
"C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.4-gcc10.3-1757bed/bin/xtensa-lx106-elf-size" -A "d:\arduino\MyHexDir/ESP_WebServer_Key.ino.elf"
项目使用了 302605 字节,占用了 (28%) 程序存储空间。最大为 1044464 字节。
全局变量使用了30248字节,(36%)的动态内存,余留51672字节局部变量。最大为81920字节。
⛳程序源码资源
链接:https://pan.baidu.com/s/1DKwllDwNbPDmhtBx2kr58g
提取码:zp22
最后
以上就是可靠信封为你收集整理的【ESP32/ESP8266】TCP异步通讯点灯控制示例程序的全部内容,希望文章能够帮你解决【ESP32/ESP8266】TCP异步通讯点灯控制示例程序所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复