ESP32/ESP8266TCP异步通讯点灯控制示例程序

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ESP32/ESP8266TCP异步通讯点灯控制示例程序相关的知识,希望对你有一定的参考价值。

【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)\\Arduino\\libraries

📖程序代码

🎈本代码默认定义的是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
  se

以上是关于ESP32/ESP8266TCP异步通讯点灯控制示例程序的主要内容,如果未能解决你的问题,请参考以下文章

ESP32/ESP8266 WebSocket Server:控制引脚输出

ESP32,ESP8266之间WiFi互联实验

ESP8266 + STC15基于AT指令通过TCP通讯协议控制IO状态

3-STM32+ESP8266连接onenet上传数据+远程控制(MQTT)

ESP8266如何实现与服务器的TCP通讯

#yyds干货盘点# 基于STM32+ESP8266+华为云设计的智能家居控制系统