源码
#include <WiFi.h>
#include <WebServer.h>// 替换为你的WiFi网络名称和密码
const char* ssid = "123";
const char* password = "1234678901";WebServer server(80); // 创建一个Web服务器对象,监听80端口// 定义ADC引脚
const int adcPin = 2; // 使用GPIO 2作为ADC输入void setup() {Serial.begin(115200);// 连接WiFiWiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {delay(500);Serial.print(".");}Serial.println("WiFi connected.");Serial.println("IP address: ");Serial.println(WiFi.localIP());// 设置服务器路由server.on("/", handleRoot); // 当访问根目录时调用handleRoot函数server.on("/readADC", handleReadADC); // 当访问/readADC时调用handleReadADC函数// 启动服务器server.begin();
}void loop() {server.handleClient(); // 处理客户端请求
}void handleRoot() {String html = "<html><head><style>body { background-color: #ADD8E6; }</style>";html += "<script>";html += "function updateADC() {";html += " var xhr = new XMLHttpRequest();";html += " xhr.onreadystatechange = function() {";html += " if (this.readyState == 4 && this.status == 200) {";html += " document.getElementById('adcValue').innerHTML = this.responseText;";html += " }";html += " };";html += " xhr.open('GET', '/readADC', true);";html += " xhr.send();";html += "}";html += "setInterval(updateADC, 1000);"; // 每秒更新一次html += "</script>";html += "</head><body>";html += "<h1>ESP32-C3 ADC Readings</h1>";html += "<p>Voltage: <span id='adcValue'>0</span> V</p>";html += "</body></html>";server.send(200, "text/html", html); // 发送网页内容
}void handleReadADC() {int adcValue = analogRead(adcPin); // 读取ADC值float voltage = (adcValue * 3.3) / 4095.0; // 转换ADC值为电压server.send(200, "text/plain", String(voltage, 2)); // 发送电压值,保留两位小数
}
网页实现数据显示的思路
-
数据采集:首先,需要确定你想要显示的数据来源。在ESP32-C3的情况下,这可能是一个ADC读取、GPIO状态、传感器数据等。
-
数据格式化:采集到的数据需要被格式化成可以发送给客户端(通常是浏览器)的格式,通常是JSON或纯文本。
-
服务器端设置:
- 创建一个Web服务器,用于处理来自客户端的请求。
- 定义路由,这些路由会响应对特定URL的请求。
- 在路由的处理函数中,采集数据,并将其格式化后发送给客户端。
-
客户端(网页)设计:
- 创建HTML页面,用于显示数据和提供用户界面。
- 使用CSS来美化网页,使其更加友好和易于使用。
- 使用JavaScript来处理用户交互和从服务器动态获取数据。
数据如何更新的思路
服务器端:
-
数据源:确保服务器端有实时或定期更新的数据源,例如数据库、传感器、API等。
-
数据监听:服务器端需要监听数据源的变化,或者定期检查数据是否更新。
-
数据推送:
- 轮询(Polling):客户端定期发送请求到服务器,询问是否有新数据。
- 长轮询(Long Polling):客户端发送请求到服务器,服务器保持连接打开直到有新数据可发送。
- 服务器发送事件(Server-Sent Events, SSE):服务器主动向客户端推送数据。
- WebSocket:建立一个持久的连接,服务器可以在任何时间向客户端发送数据。
客户端:
-
初始化:客户端加载页面并初始化数据展示。
-
数据请求:根据采用的更新策略,客户端发送请求到服务器。
-
数据处理:
- 接收服务器响应的数据。
- 更新页面上的数据展示。
以下是不同更新策略的具体实现思路:
轮询(Polling):(实现的)
- 客户端:使用
setInterval
或setTimeout
在JavaScript中定期发送AJAX请求到服务器。
function fetchData() {fetch('/data').then(response => response.json()).then(data => {updateUI(data);setTimeout(fetchData, 5000); // 每5秒请求一次});
}fetchData();
- 服务器端:处理请求并返回当前数据。
void handleData() {// 获取数据String jsonData = getLatestData();server.send(200, "application/json", jsonData);
}
长轮询(Long Polling):
- 客户端:发送请求到服务器,并等待直到服务器有新数据返回。
function longPolling() {fetch('/data').then(response => response.json()).then(data => {updateUI(data);longPolling(); // 重新发起长轮询});
}longPolling();
- 服务器端:保持连接打开,直到有新数据可发送。
void handleData() {// 等待直到有新数据String jsonData = waitForNewData();server.send(200, "application/json", jsonData);
}
服务器发送事件(Server-Sent Events, SSE):
- 客户端:创建一个
EventSource
来监听服务器发送的事件。
var eventSource = new EventSource('/events');
eventSource.onmessage = function(event) {var data = JSON.parse(event.data);updateUI(data);
};
- 服务器端:发送事件到客户端。
void handleEvents() {// 发送新数据作为事件String eventData = getEventData();server.sendContent("data: " + eventData + "\n\n");
}
WebSocket:
- 客户端:建立WebSocket连接,并监听消息。
var socket = new WebSocket('ws://example.com/socket');
socket.onmessage = function(event) {var data = JSON.parse(event.data);updateUI(data);
};
- 服务器端:处理WebSocket连接,并在有新数据时发送消息。
void onWebSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {if (type == WStype_TEXT) {// 发送新数据String data = getWebSocketData();webSocket.sendTXT(num, data);}
}
选择哪种策略取决于应用的需求,例如数据更新频率、延迟敏感度、服务器和客户端的资源限制等。轮询是最简单的方法,但可能不是最高效的;WebSocket提供了全双工通信,但实现起来相对复杂。