基于Arduino的ESP32服务器的温度采集显示与LED远程控制

您所在的位置:网站首页 Arduino控制板加相机 基于Arduino的ESP32服务器的温度采集显示与LED远程控制

基于Arduino的ESP32服务器的温度采集显示与LED远程控制

2023-07-08 02:01| 来源: 网络整理| 查看: 265

前言

 建立一个异步ESP32 Web Server实时接收来自串口1 Serial1的发送的温度值数据,并在ESP32托管网页上实时显示当前温度值,Web客户端可以发送指令至串口1 Serial1远程控制LED。

先前准备 1.ESP32开发板+USB供电线+(C51/STM32:用于采集温度值+控制LED)

 当然,我们也可以不通过C51/STM32去做温度值采集、LED控制,直接通过ESP32就可以完成这些。笔者使用这些,只是某个实习项目必须要求的。

2.开发环境Arduino+VSCode+PlatformIO

 开发环境配置就不在此赘述,google上有相关教程,在此附上一个。

3.依赖库安装

 ESPAsyncWebServer 和 AsyncTCP 库。

使用异步Web Server优势:

1.可以处理多个连接

2.当发送请求同时,可以处理其他请求连接

3.处理请求模板更简单

网页界面

 ESP32网页客户端界面如下:
[

代码架构

 主要文件在./src中。

main.hpp #ifndef MAIN_HPP #define MAIN_HPP #include struct WiFiConfig { /* data */ const char *ssid; const char *password; }; struct ParamConfig { /* data */ const char *PARAM_INPUT_1; const char *PARAM_INPUT_2; }; String read_uart_data(); String processor(const String &var); void server_request(); #endif main.cpp /* Srerial串口: DEBUG用 Serial1串口IO口: RX --------- SD2 TX --------- SD3 */ #include "main.hpp" #include "WiFi.h" #include "AsyncTCP.h" #include "ESPAsyncWebServer.h" WiFiConfig mywifi = { "dxxy16-402-1", "dxxy16402"}; ParamConfig param = { "output", "state"}; char recv_num[100]; // Create AsyncWebServer object on port 80 AsyncWebServer server(80); const char index_html[] PROGMEM = R"rawliteral( ESP Web Server html { font-family: Arial; display: inline-block; text-align: center; margin: 0px auto; } 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: #ccc; border-radius: 6px } .slider:before { position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 3px } input:checked+.slider { background-color: #b30000 } input:checked+.slider:before { -webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px) } .units { font-size: 1.2rem; } .ds-labels { font-size: 1.2rem; vertical-align: middle; padding-bottom: 15px; } %BUTTONPLACEHOLDER%

Temperature Celsius %TEMPERATUREC% °C

function toggleCheckbox(element) { var xhr = new XMLHttpRequest(); if (element.checked) { xhr.open("GET", "/update?output=" + element.id + "&state=1", true); } else { xhr.open("GET", "/update?output=" + element.id + "&state=0", true); } xhr.send(); } setInterval(function () { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { document.getElementById("temperaturec").innerHTML = this.responseText; } }; xhttp.open("GET", "/temperaturec", true); xhttp.send(); }, 20000); )rawliteral"; void setup() { Serial.begin(9600); Serial1.begin(9600); // Connect to Wi-Fi WiFi.begin(mywifi.ssid, mywifi.password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi.."); } // Print ESP Local IP Address Serial.println(WiFi.localIP()); server_request(); } void loop() { } void server_request() { // 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 /update?output=&state= server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request) { String inputMessage1; String inputMessage2; // GET input1 value on /update?output=&state= if (request->hasParam(param.PARAM_INPUT_1) && request->hasParam(param.PARAM_INPUT_2)) { inputMessage1 = request->getParam(param.PARAM_INPUT_1)->value(); inputMessage2 = request->getParam(param.PARAM_INPUT_2)->value(); } else { inputMessage1 = "No message sent"; inputMessage2 = "No message sent"; } Serial.print(inputMessage1+inputMessage2); Serial1.print(inputMessage1+inputMessage2); request->send(200, "text/plain", "OK"); }); server.on("/temperaturec", HTTP_GET, [](AsyncWebServerRequest *request) { request->send_P(200, "text/plain", read_uart_data().c_str()); }); // Start server server.begin(); } // 读取串口数据 String read_uart_data() { unsigned short i = Serial1.available(); // 获取串口接收数据个数 unsigned short count = i; unsigned short j; char temp; if (i != 0) { j = 0; memset(recv_num, 0, sizeof(recv_num)); // 清空我们的目标字符串存储区域 while (i--) { /* code */ temp = Serial1.read(); if (temp == '?') break; if (temp == 'C') break; recv_num[j] = temp; j++; } // Serial1.print(recv_num); } else { NULL; } // DEBUG Serial.print(recv_num); return String(recv_num); } // Replaces placeholder with button section in your web page String processor(const String &var) { // Serial.println(var); if (var == "BUTTONPLACEHOLDER") { String buttons = ""; buttons += "LED0"; buttons += "LED1"; buttons += "Warning"; return buttons; } if (var == "TEMPERATUREC") { return read_uart_data(); } return String(); } 代码如何运作 1.首先,包含必要的库: #include "main.hpp" #include "WiFi.h" #include "AsyncTCP.h" #include "ESPAsyncWebServer.h" 2.定义所需的变量和结构体变量: WiFiConfig mywifi = { "dxxy16-402-1", "dxxy16402"}; ParamConfig param = { "output", "state"}; char recv_num[100]; 3.创建一个 异步网络服务器的 server对象监听 80端口 AsyncWebServer server(80); 4.process()函数

 process()函数会将值赋在我们创建的HTML网页上的占位符上。它接受占位符("BUTTONPLACEHOLDER"和 "TEMPERATUREC")作为参数,并返回一个替代占位符的字符串。

String processor(const String &var) { // Serial.println(var); if (var == "BUTTONPLACEHOLDER") { String buttons = ""; buttons += "LED0"; buttons += "LED1"; buttons += "Warning"; return buttons; } if (var == "TEMPERATUREC") { return read_uart_data(); } return String(); } 5.read_uart_data()函数

 read_uart_data()函数用来将读取串口接受的数据,在本项目中,用于接收串口1发送的温度值数据。

String read_uart_data() { unsigned short i = Serial1.available(); // 获取串口接收数据个数 unsigned short count = i; unsigned short j; char temp; if (i != 0) { j = 0; memset(recv_num, 0, sizeof(recv_num)); // 清空我们的目标字符串存储区域 while (i--) { /* code */ temp = Serial1.read(); if (temp == '?') break; if (temp == 'C') break; recv_num[j] = temp; j++; } // Serial1.print(recv_num); } else { NULL; } // DEBUG Serial.print(recv_num); return String(recv_num); } 6.server_request()函数

 server_request()函数主要用来处理Web服务器请求并启动服务器。

void server_request() { // 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 /update?output=&state= server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request) { String inputMessage1; String inputMessage2; // GET input1 value on /update?output=&state= if (request->hasParam(param.PARAM_INPUT_1) && request->hasParam(param.PARAM_INPUT_2)) { inputMessage1 = request->getParam(param.PARAM_INPUT_1)->value(); inputMessage2 = request->getParam(param.PARAM_INPUT_2)->value(); } else { inputMessage1 = "No message sent"; inputMessage2 = "No message sent"; } Serial.print(inputMessage1+inputMessage2); Serial1.print(inputMessage1+inputMessage2); request->send(200, "text/plain", "OK"); }); server.on("/temperaturec", HTTP_GET, [](AsyncWebServerRequest *request) { request->send_P(200, "text/plain", read_uart_data().c_str()); }); // Start server server.begin(); } 7.setup()函数

 主要用串口的波特率初始化,wifi的连接以及网页服务器的请求与开启。

void setup() { Serial.begin(9600); Serial1.begin(9600); // Connect to Wi-Fi WiFi.begin(mywifi.ssid, mywifi.password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi.."); } // Print ESP Local IP Address Serial.println(WiFi.localIP()); server_request(); } 教程源码链接及其他

Github:https://github.com/Yogurt-994/esp32-project/tree/master/esp32-webserver ESP32官网:https://randomnerdtutorials.com/getting-started-with-esp32/https://randomnerdtutorials.com/getting-started-with-esp32



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3