ESP32 Arduino网页上传数据代码解释
包含必要的库
#include <WiFi.h>
#include <WebServer.h>
WiFi.h
: 用于处理ESP32与Wi-Fi网络的连接。WebServer.h
: 允许ESP32充当Web服务器,处理HTTP请求。
设置Wi-Fi凭据
const char* ssid = "yourSSID";
const char* password = "yourPASSWORD";
- 这里定义了连接Wi-Fi所需的网络SSID和密码。您需要将这些字符串替换为您自己网络的实际SSID和密码。
创建Web服务器实例
WebServer server(80);
- 这行代码创建了一个Web服务器,监听80端口(HTTP的标准端口)。
定义土壤湿度传感器接口
int sensorPin = 34;
- 这里指定了土壤湿度传感器连接到ESP32的GPIO引脚号(这里使用GPIO34)。
初始化设置
void setup() {
// 初始化串口通信,连接到Wi-Fi,设置Web服务器的路由,然后启动服务器。
}
void loop() {
// 循环检查并响应客户端请求。
}
setup()
函数用于设置串口,连接Wi-Fi,定义HTTP路由,并启动服务器。loop()
函数持续监测和处理来自客户端的请求。
处理HTTP请求
server.on("/", HTTP_GET, handle_OnConnect);
server.on("/moisture", HTTP_GET, handle_MoistureData);
- 这些代码定义了服务器的路由。当用户访问网站的根目录("/")时,调用
handle_OnConnect
函数。当访问"/moisture"时,调用handle_MoistureData
函数。
JavaScript代码解释
JavaScript代码嵌入在HTML中,用于在客户端(用户的浏览器)上执行,以实现数据的实时更新。
<script>
setInterval(()=>{
fetch('/moisture').then(response => response.text()).then(data => document.getElementById('moisture').innerHTML = data);
}, 2000);
</script>
setInterval(()=>{...}, 2000)
: 这是一个定时器函数,每2000毫秒(即2秒)执行一次包裹在内部的函数。这种重复执行机制用于定期从服务器获取最新数据。
fetch
fetch
是一种JavaScript API,用于进行网络请求。它是一个强大且灵活的方法,用于向指定的URL发起请求并获取数据。在您的代码中,fetch
用于从ESP32的特定路由(如 "/moisture")请求数据。
- 语法:
fetch(url)
- 功能: 它向给定的URL发起一个网络请求。在这个案例中,它向ESP32服务器上的"/moisture"路径发送请求。
- 返回值:
fetch
返回一个Promise对象,这个对象代表着请求的未来结果。
.then()
.then()
是Promise对象上的一个方法。当使用Promise(如fetch
返回的Promise)时,.then()
用于处理Promise解析后的结果。
语法:
promise.then(onFulfilled, onRejected)
功能:
onFulfilled
是一个函数,当Promise成功解析时调用,即请求成功并获得了响应。onRejected
是一个可选的函数,当Promise被拒绝(比如网络错误)时调用。
代码中:
- 第一个
.then(response => response.text())
处理fetch请求的响应,并将响应体转换为文本。 - 第二个
.then(data => document.getElementById('moisture').innerHTML = data)
接收转换后的文本(即土壤湿度数据),并更新网页上相应元素的内容。
- 第一个
总结
fetch('/moisture')
: 向ESP32服务器的"/moisture"路由发起请求,获取土壤湿度数据。.then(response => response.text())
: 处理响应,将响应内容(原始数据)转换为文本格式。.then(data => document.getElementById('moisture').innerHTML = data)
: 将转换后的文本(土壤湿度值)设置到网页上的指定元素中,以便显示。
HTML结构
<h1>土壤湿度值: <span id='moisture'></span></h1>
- 这是网页的HTML结构,其中包含一个标题。标题中有一个
<span>
标签,其ID设置为moisture
。JavaScript将使用这个ID来找到该元素并更新其内容(即土壤湿度值)。
JS
js关键字
JavaScript代码解释
1. setInterval
函数
setInterval(()=>{
// ...代码...
}, 2000);
setInterval
是一个JavaScript内置函数,用于定时执行某段代码。- 它接受两个参数:一个函数和一个时间间隔(以毫秒为单位)。
- 这里的时间间隔设置为2000毫秒,即2秒。这意味着里面的代码每2秒执行一次。
- 传入的函数(
()=>{...}
)称为“箭头函数”,这是一种简洁的函数表达方式。
2. fetch
函数
fetch('/moisture')
fetch
是一个用于发送HTTP请求的函数,常用于与服务器交互。- 这里它向
'/moisture'
发送请求,这个URL对应ESP32上的一个路由。 fetch
返回一个“Promise”,这是一种表示异步操作最终完成或失败的对象。
3. .then
方法和链式调用
.then(response => response.text())
.then(data => document.getElementById('moisture').innerHTML = data);
.then
方法用于处理Promise的结果。- 当
fetch
请求成功完成时,它会收到一个“响应对象”(response
)。 response.text()
是一个方法,它读取响应体的文本内容并再次返回一个Promise。- 第二个
.then
方法用于处理response.text()
的结果,这里是服务器返回的实际数据(data
)。
4. 更新网页内容
document.getElementById('moisture').innerHTML = data;
- 这行代码用于更新网页上的内容。
document.getElementById('moisture')
查找ID为moisture
的HTML元素(在这个例子中是一个<span>
标签)。.innerHTML
是这个HTML元素的一个属性,它代表元素内的HTML内容。= data
将data
(从服务器获取的土壤湿度值)赋值给innerHTML
,从而更新显示的内容。
示例 1: 使用 innerHTML
innerHTML
属性用于获取或设置HTML元素的内部HTML内容。
示例代码:
<!DOCTYPE html>
<html>
<body>
<h1 id="example">Hello, world!</h1>
<script>
document.getElementById("example").innerHTML = "Welcome to JavaScript!";
</script>
</body>
</html>
解释:
document.getElementById("example")
: 这个方法返回ID为“example”的HTML元素。.innerHTML = "Welcome to JavaScript!"
: 这将<h1>
标签中的内容从“Hello, world!”更改为“Welcome to JavaScript!”。
示例 2: 使用 getElementById
getElementById
是一个方法,用于根据提供的ID查找HTML元素。
示例代码:
<!DOCTYPE html>
<html>
<body>
<p id="paragraph">This is a paragraph.</p>
<script>
var para = document.getElementById("paragraph");
alert(para.innerHTML);
</script>
</body>
</html>
解释:
document.getElementById("paragraph")
: 查找ID为“paragraph”的元素。para.innerHTML
: 获取该元素的内部HTML,即段落的文本内容。alert(para.innerHTML)
: 弹出一个包含段落内容的警告框。
示例 3: 使用 getElementsByTagName
getElementsByTagName
方法返回一个包含所有指定标签名称的元素的集合。
示例代码:
<!DOCTYPE html>
<html>
<body>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<script>
var paragraphs = document.getElementsByTagName("p");
alert(paragraphs[1].innerHTML);
</script>
</body>
</html>
解释:
document.getElementsByTagName("p")
: 查找所有<p>
标签的元素。paragraphs[1].innerHTML
: 获取第二个段落的内容(索引从0开始)。alert(paragraphs[1].innerHTML)
: 弹出一个警告框显示第二个段落的内容。
关键字解释
- innerHTML: 用于获取或设置HTML元素的内部HTML内容。它是元素的属性之一。
- getElementById: 这个方法接受一个字符串参数(元素的ID),返回文档中具有该ID的第一个元素。如果没有找到匹配的元素,它将返回
null
。 - getElementsByTagName: 这个方法接受一个标签名(如 "p"、"div")作为参数,并返回一个包含所有具有该标签名的元素的HTML集合。
1. setInterval
结合HTML使用示例
示例代码
<!DOCTYPE html>
<html>
<head>
<title>定时器示例</title>
</head>
<body>
<h2>当前时间</h2>
<p id="time"></p>
<script>
setInterval(() => {
const now = new Date();
document.getElementById("time").innerHTML = now.toLocaleTimeString();
}, 1000);
</script>
</body>
</html>
使用方法和解释
- 这个HTML页面包含一个段落(
<p>
标签),用于显示当前时间。 - JavaScript的
setInterval
函数每秒钟更新这个段落的内容。 - 每次调用时,它创建一个新的
Date
对象(const now = new Date();
),代表当前时间。 document.getElementById("time").innerHTML = now.toLocaleTimeString();
这行代码找到ID为time
的元素,并将其内容设置为当前时间的字符串表示。
应用场景
这个示例适用于需要定期更新页面内容的情况,如显示实时时钟。
2. fetch
结合HTML使用示例
示例代码
<!DOCTYPE html>
<html>
<head>
<title>Fetch API 示例</title>
</head>
<body>
<h2>从服务器获取数据</h2>
<button id="fetchButton">获取数据</button>
<p id="data"></p>
<script>
document.getElementById("fetchButton").onclick = function() {
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(data => {
document.getElementById("data").innerHTML = JSON.stringify(data);
});
};
</script>
</body>
</html>
使用方法和解释
- 这个页面包含一个按钮和一个用于显示数据的段落。
- 当用户点击按钮时,会触发一个函数,该函数使用
fetch
从指定URL获取数据。 - 获取到的数据先转换为JSON,然后显示在段落中(
JSON.stringify(data)
)。
本节课源码
#include <WiFi.h>
#include <WebServer.h>
const char* ssid = "2333";
const char* password = "88888888";
WebServer server(80);
int sensorPin = 34; // 土壤湿度传感器接到GPIO34
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println(WiFi.localIP());
server.on("/", HTTP_GET, handle_OnConnect);
server.on("/moisture", HTTP_GET, handle_MoistureData);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
}
void handle_OnConnect() {
String html = "<html><head><meta charset='UTF-8'><script>setInterval(()=>{fetch('/moisture').then(response => response.text()).then(data => document.getElementById('moisture').innerHTML = data);}, 2000);</script></head><body><h1>土壤湿度值: <span id='moisture'></span></h1></body></html>";
server.send(200, "text/html", html);
}
void handle_MoistureData() {
int soilMoistureValue = analogRead(sensorPin);
server.send(200, "text/plain", String(soilMoistureValue));
}