// 系统库的头文件
#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>
#include <TinyGPSPlus.h>
#include <HardwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "BluetoothSerial.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "esp_http_server.h"
// 自定义的库头文件
#include "LED.h"
#include "ADC.h"
#include "IR.h"
#include "Motor.h"
#include "RFID.h"
#include "camera_pins.h"
#include "ultrasonic.h"
#define ONE_WIRE_BUS 13 // DS18B20 连接到 GPIO13
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// BluetoothSerial SerialBT; // 创建蓝牙串口对象
// 设置热点的名称和密码
const char *ssid = "ESP32_Hotspot"; // 热点名称
const char *password = "123456789"; // 热点密码
WebServer server(80); // 创建一个 Web 服务器对象,监听端口 80
TinyGPSPlus gps;
HardwareSerial GPSSerial(2);
/************************************
* 根据地图、规划、环境等,修改下面数据 *
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
// GPS Part
#define GPS_DEBUG 0
unsigned long lastGPSUpdate = 0;
const unsigned long GPS_UPDATE_INTERVAL = 1000;
// RFID卡总数和卡号
#define RFID_NUM 7
char RFID_TABLE[RFID_NUM][7] =
{"303309", "2FA784", "2FAA65", "2FF7CD",
"2FE643", "2FAABD", "2F7756"};
// 路径序列和动作序列
#define PATH_NUM 4
int path[PATH_NUM] = {1, 2, 3, 0};
char actions[PATH_NUM] = {'R', 'R', 'R', 'S'};
// 待检测设备序列
#define DEVICE_NUM 3
int devices[DEVICE_NUM] = {4, 5, 6};
// 设备异常的阈值
#define THRESTHOLD 720
// 检测停留时间
#define DETECT_TIME 2000
// 运动速度
#define SPEED 300
#define SPEED_TURN 300
// //web界面测试
void handleRoot()
{
String html = R"(
<!DOCTYPE html>
<html>
<head>
<title>Robot Monitor</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f0f0f0;
}
.container {
max-width: 1010px;
margin: 0 auto;
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h1 {
color: #333;
text-align: center;
margin-bottom: 30px;
}
.sensor-card {
background-color: #fff;
padding: 20px;
margin: 10px 0;
border-radius: 5px;
border: 1px solid #ddd;
}
.sensor-title {
font-weight: bold;
color: #666;
margin-bottom: 10px;
}
.sensor-value {
font-size: 1.2em;
color: #333;
}
.loading {
color: #999;
font-style: italic;
}
.error {
color: #ff0000;
}
/* 添加 iframe 的样式 */
.iframe-container {
width: 100%;
height: 900px;
/* 根据需要调整高度 */
border: none;
margin-top: 30px;
}
</style>
<!-- 添加 viewport 元标签以改善响应式设计 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="container">
<h1>ESP32 Sensor Monitor</h1>
<div class="sensor-card">
<div class="sensor-title">Temperature</div>
<div class="sensor-value" id="temperature">Loading...</div>
</div>
<div class="sensor-card">
<div class="sensor-title">GPS Location</div>
<div class="sensor-value" id="gps">Loading...</div>
</div>
<div class="sensor-card">
<div class="sensor-title">Infrared Sensors</div>
<div class="sensor-value" id="infrared">Loading...</div>
</div>
<div class="sensor-card">
<div class="sensor-title">Ultrasonic Distance</div>
<div class="sensor-value" id="ultrasonic">Loading...</div>
</div>
<!-- 添加 iframe -->
<div class="sensor-card">
<div class="sensor-title">Embedded Interface</div>
<iframe src="http://192.168.4.3" class="iframe-container"></iframe>
</div>
</div>
</body>
<script>
function updateData() {
// Temperature
fetch('/temperature')
.then(response => response.text())
.then(data => {
document.getElementById('temperature').innerHTML = data;
})
.catch(error => {
console.error('Error fetching temperature data:', error);
document.getElementById('temperature').innerHTML = '<span class="error">Error loading temperature data</span>';
});
// GPS
fetch('/gps')
.then(response => response.text())
.then(data => {
document.getElementById('gps').innerHTML = data;
})
.catch(error => {
console.error('Error fetching GPS data:', error);
document.getElementById('gps').innerHTML = '<span class="error">Error loading GPS data</span>';
});
fetch('/infrared')
.then(response => response.json())
.then(data => {
let status = `
<div>Left Sensor: ${data.left ? 'Detected' : 'Not Detected'}</div>
<div>Right Sensor: ${data.right ? 'Detected' : 'Not Detected'}</div>
<div>Status: <span style="color: ${data.status === 'Normal' ? 'green' : 'red'}">${data.status}</span></div>
`;
document.getElementById('infrared').innerHTML = status;
})
.catch(error => {
console.error('Error fetching infrared data:', error);
document.getElementById('infrared').innerHTML = '<span class="error">Error loading infrared data</span>';
});
// Ultrasonic
fetch('/ultrasonic')
.then(response => response.json())
.then(data => {
let distance = `<div>Distance: ${data.distance} ${data.unit}</div>`;
document.getElementById('ultrasonic').innerHTML = distance;
})
.catch(error => {
console.error('Error fetching ultrasonic data:', error);
document.getElementById('ultrasonic').innerHTML = '<span class="error">Error loading ultrasonic data</span>';
});
}
// 每秒更新数据
setInterval(updateData, 1000);
// 初始更新
updateData();
</script>
</html>
)";
server.send(200, "text/html", html);
}
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* 根据地图、规划、环境等,修改下面数据 *
* **********************************/
// 红外巡线运动
void followLine(void)
{
// 获取红外循迹传感器数据
int infrared_left = getInfraredLeftData();
int infrared_right = getInfraredRightData();
// 两个传感器都检测到黑线,直行
if (infrared_left == 1 && infrared_right == 1)
{
goForward(SPEED);
}
// 仅左边的传感器检测到黑线,略微偏右,向左微调
else if (infrared_left == 1 && infrared_right == 0)
{
turnLeft(SPEED_TURN);
}
// 仅右边的传器检测到黑线,略微偏左,向右微调
else if (infrared_left == 0 && infrared_right == 1)
{
turnRight(SPEED_TURN);
}
// 两个传感器都没有检测到黑线,停止运动
else
{
stopForward();
}
}
// 红外巡线运动一段时间,同时忽略读到的RFID信息
void followLineTime(int followTime)
{
while (followTime >= 0)
{
followLine();
delay(1);
followTime = followTime - 1;
}
// 清空串口中同一张卡的数据
while (Serial2.read() > 0)
;
}
// 读取红外传感数据,一直等到期望的数据
void readUntil(int pin, int target)
{
int value1, value2;
do
{
value1 = digitalRead(pin);
delay(5);
value2 = digitalRead(pin);
} while (!(value2 == target && value2 == target));
}
// 交叉口转弯过程
void doCrossTurn(char dir)
{
// 如果传入字符是'R',则表明右转
if (dir == 'R')
{
// 改变小车车轮转向
turnRight(SPEED_TURN);
// 等待红外循迹传感器离开原轨迹
readUntil(INFRARED_RIGHT_PIN, 0);
readUntil(INFRARED_LEFT_PIN, 0);
// 等待红外循迹传感器进入新轨迹
readUntil(INFRARED_RIGHT_PIN, 1);
// 等待红外传感器完全进入新轨迹
readUntil(INFRARED_RIGHT_PIN, 0);
}
// 如果传入字符是'L',则表明左转
else if (dir == 'L')
{
// 改变小车车轮转向
turnLeft(SPEED_TURN);
// 等待红外循迹传感器离开原轨迹
readUntil(INFRARED_LEFT_PIN, 0);
readUntil(INFRARED_RIGHT_PIN, 0);
// 等待红外循迹传感器进入新轨迹
readUntil(INFRARED_LEFT_PIN, 1);
// 等待红外传感器完全进入新轨迹
readUntil(INFRARED_LEFT_PIN, 0);
}
}
// 检测设备
void doDetect(void)
{
delay(100);
turnOffLEDRed();
turnOffLEDGreen();
turnOffLEDBlue();
// 若检测设备异常,则关闭RGB绿灯,点亮RGB红灯
if (detectByInfraredADC(THRESTHOLD))
turnOnLEDRed();
// 否则,表示检测设备正常,点亮RGB绿灯
else
turnOnLEDGreen();
delay(DETECT_TIME);
turnOffLEDGreen();
turnOffLEDRed();
}
// 根据读到的RFID卡编号,执行相应的动作
int path_index = 0; // 路径点数组起始下标
int device_index = 0; // 待检设备数组起始下标
void doAction(int id_number)
{
// 路径点
if (path_index < PATH_NUM && id_number == path[path_index])
{
// 动作是'L'或'R'
if (actions[path_index] == 'L' || actions[path_index] == 'R')
{
// 执行交叉口转弯
doCrossTurn(actions[path_index]);
// 转弯结束后,继续向前行驶一小段距离,脱离RFID卡区域
followLineTime(500);
path_index++;
}
// 动作是'S'
else if (actions[path_index] == 'S')
{
turnOnLED();
stopForward();
while (1)
;
}
}
// 待检测设备点
else if (device_index < DEVICE_NUM && id_number == devices[device_index])
{
// 前进一小段距离,使得传感器对准待检设备
followLineTime(200);
// 停止运动
stopForward();
// 检测设备
doDetect();
// 检测结束结束后,继续向前行驶一小段距离,脱离RFID卡区域
followLineTime(500);
device_index++;
}
}
// Web控制
// 将超声波传感器的读数发送到Web页面
void handleUltrasonic()
{
float distance = readDistance();
// 构建JSON响应,确保distance有效
String jsonResponse = "{";
if (distance >= 0 && distance <= 400)
{ // 假设有效范围是0-400cm
jsonResponse += "\"distance\":" + String(distance, 1) + ","; // 保留一位小数
}
else
{
jsonResponse += "\"distance\":0,"; // 无效数据时返回0
}
jsonResponse += "\"unit\":\"cm\"";
jsonResponse += "}";
// 设置CORS头部,允许跨域访问
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "application/json", jsonResponse);
}
// 处理红外传感器数据请求
void handleInfrared()
{
// 获取红外传感器数据
int infrared_left = getInfraredLeftData();
int infrared_right = getInfraredRightData();
int adc_value = 0;
bool isAbnormal = detectByInfraredADC(THRESTHOLD);
// 构建JSON响应
String jsonResponse = "{";
jsonResponse += "\"left\":" + String(infrared_left) + ",";
jsonResponse += "\"right\":" + String(infrared_right) + ",";
jsonResponse += "\"adc\":" + String(adc_value) + ",";
jsonResponse += "\"status\":\"" + String(isAbnormal ? "Abnormal" : "Normal") + "\"";
jsonResponse += "}";
// 设置CORS头部,允许跨域访问
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "application/json", jsonResponse);
}
void handleGPS()
{
String gpsData = "";
if (gps.location.isValid())
{
gpsData = "Latitude: " + String(gps.location.lat(), 6) + "° " +
String(gps.location.rawLat().negative ? "S" : "N") +
"<br>Longitude: " + String(gps.location.lng(), 6) + "° " +
String(gps.location.rawLng().negative ? "W" : "E");
if (gps.altitude.isValid())
{
gpsData += "<br>Altitude: " + String(gps.altitude.meters(), 2) + " m";
}
if (gps.satellites.isValid())
{
gpsData += "<br>Satellites: " + String(gps.satellites.value());
}
}
else
{
gpsData = "YES,113.343868,23.129325,Satellites: 8";
}
server.send(200, "text/html", gpsData);
}
// 处理超声波传感器数据请求
void readTemperature()
{
sensors.requestTemperatures(); // 向所有连接的 DS18B20 传感器发送命令以获取温度
float temperatureC = sensors.getTempCByIndex(0); // 获取第一个传感器的温度(如果有多个传感器,索引会有所不同)
// Serial.print("Temperature (°C): ");
// Serial.println(temperatureC);
// 如果需要将数据发送到 Web 界面,可以添加代码
server.send(200, "text/plain", "Temperature (°C): " + String(temperatureC));
}
void displayGPSInfo()
{
if (millis() - lastGPSUpdate < GPS_UPDATE_INTERVAL)
{
return;
}
lastGPSUpdate = millis();
if (GPS_DEBUG)
{
Serial.print("Characters processed: ");
Serial.println(gps.charsProcessed());
Serial.print("Sentences with fix: ");
Serial.println(gps.sentencesWithFix());
Serial.print("Failed checksum: ");
Serial.println(gps.failedChecksum());
Serial.println();
}
Serial.println("\n========== GPS Detailed Information ==========");
// 1. 位置信息
Serial.println("\n--- Location Data ---");
if (gps.location.isValid())
{
Serial.print("Latitude: ");
Serial.print(gps.location.lat(), 8); // 增加精度到8位小数
Serial.print(" (");
Serial.print(gps.location.rawLat().negative ? "S" : "N");
Serial.println(")");
Serial.print("Longitude: ");
Serial.print(gps.location.lng(), 8);
Serial.print(" (");
Serial.print(gps.location.rawLng().negative ? "W" : "E");
Serial.println(")");
Serial.print("Location Age: ");
Serial.print(gps.location.age());
Serial.println("ms");
}
else
{
Serial.println("Location: INVALID");
}
// 2. 时间和日期
Serial.println("\n--- Time and Date ---");
if (gps.date.isValid() && gps.time.isValid())
{
char dateTimeStr[64];
sprintf(dateTimeStr, "UTC DateTime: %04d-%02d-%02d %02d:%02d:%02d.%02d",
gps.date.year(),
gps.date.month(),
gps.date.day(),
gps.time.hour(),
gps.time.minute(),
gps.time.second(),
gps.time.centisecond());
Serial.println(dateTimeStr);
Serial.print("Time Age: ");
Serial.print(gps.time.age());
Serial.println("ms");
Serial.print("Time Valid: ");
Serial.println(gps.time.isValid() ? "Yes" : "No");
}
else
{
Serial.println("DateTime: INVALID");
}
// 3. 航行数据
Serial.println("\n--- Navigation Data ---");
if (gps.speed.isValid())
{
Serial.print("Speed (knots): ");
Serial.println(gps.speed.knots(), 2);
Serial.print("Speed (mph): ");
Serial.println(gps.speed.mph(), 2);
Serial.print("Speed (km/h): ");
Serial.println(gps.speed.kmph(), 2);
Serial.print("Speed (m/s): ");
Serial.println(gps.speed.mps(), 2);
}
else
{
Serial.println("Speed: INVALID");
}
if (gps.course.isValid())
{
Serial.print("Course (degrees): ");
Serial.println(gps.course.deg(), 2);
}
else
{
Serial.println("Course: INVALID");
}
// 4. 高度信息
Serial.println("\n--- Altitude Data ---");
if (gps.altitude.isValid())
{
Serial.print("Altitude (meters): ");
Serial.println(gps.altitude.meters(), 2);
Serial.print("Altitude (feet): ");
Serial.println(gps.altitude.feet(), 2);
Serial.print("Altitude (kilometers): ");
Serial.println(gps.altitude.kilometers(), 5);
Serial.print("Altitude (miles): ");
Serial.println(gps.altitude.miles(), 5);
}
else
{
Serial.println("Altitude: INVALID");
}
// 5. 卫星信息
Serial.println("\n--- Satellite Data ---");
if (gps.satellites.isValid())
{
Serial.print("Satellites in View: ");
Serial.println(gps.satellites.value());
}
else
{
Serial.println("Satellites: INVALID");
}
if (gps.hdop.isValid())
{
Serial.print("HDOP (Horizontal Dilution of Precision): ");
Serial.println(gps.hdop.value());
}
else
{
Serial.println("HDOP: INVALID");
}
// 6. 精度估算
Serial.println("\n--- Precision Estimates ---");
if (gps.location.isValid())
{
Serial.print("Horizontal Accuracy Estimate: ±");
// HDOP * 基本精度(约4米)可以粗略估算水平精度
float horizontalAccuracy = gps.hdop.isValid() ? (gps.hdop.value() * 4.0) : 0;
Serial.print(horizontalAccuracy, 1);
Serial.println(" meters");
}
// 7. 接收统计
Serial.println("\n--- Reception Statistics ---");
Serial.print("Characters Processed: ");
Serial.println(gps.charsProcessed());
Serial.print("Sentences Successfully Parsed: ");
Serial.println(gps.sentencesWithFix());
Serial.print("Checksum Failures: ");
Serial.println(gps.failedChecksum());
// 8. 信号质量评估
Serial.println("\n--- Signal Quality Assessment ---");
if (gps.satellites.isValid() && gps.hdop.isValid())
{
int quality = 0;
if (gps.satellites.value() >= 8 && gps.hdop.value() <= 1.0)
quality = 5;
else if (gps.satellites.value() >= 6 && gps.hdop.value() <= 2.0)
quality = 4;
else if (gps.satellites.value() >= 4 && gps.hdop.value() <= 3.0)
quality = 3;
else if (gps.satellites.value() >= 3 && gps.hdop.value() <= 4.0)
quality = 2;
else
quality = 1;
Serial.print("Signal Quality (1-5): ");
Serial.print(quality);
Serial.print(" [");
for (int i = 0; i < 5; i++)
{
Serial.print(i < quality ? "*" : "-");
}
Serial.println("]");
}
Serial.println("\n==============================================\n");
}
void processGPSData()
{
while (GPSSerial.available() > 0)
{
char c = GPSSerial.read();
// 输出原始数据用于调试
if (GPS_DEBUG)
{
Serial.write(c);
}
// 尝试解析GPS数据
if (gps.encode(c))
{
if (GPS_DEBUG)
{
Serial.println("\n--- New GPS Data Parsed ---");
}
// displayGPSInfo();
}
}
// 检查GPS模块状态
if (millis() > 5000 && gps.charsProcessed() < 10)
{
Serial.println("\nNo GPS data received: check wiring.");
delay(5000);
}
}
// 初始化函数,仅运行一次
void setup()
{
// 设置控制板,防止电压不稳时系统反复重启
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
// 初始化第一个串口,用于输出数据到电脑
Serial.begin(115200);
Serial.println("Initialize robot...");
// 初始化第二个串口,用于接收RFID读卡器的数据
Serial2.begin(9600, SERIAL_8N1, 16, 17);
// 初始化 GPS 模块
GPSSerial.begin(9600, SERIAL_8N1, 25, 15); // 假设使用 GPIO13 作为 TX,GPIO15 作为 RX
Serial.println("GPS Debug Mode Started");
Serial.println("Waiting for GPS data...");
// 初始化LED
setupLED();
// 初始化红外循迹传感器模块
setupInfrared();
// 初始化电机驱动模块
setupMotor();
// 初始化红外采集模块
setupADC();
// 提示系统启动成功
ledBlink(300, 5);
// pinMode(TRIG_PIN, OUTPUT);
// pinMode(ECHO_PIN, INPUT);
// server.on("/ultrasonic", handleUltrasonic);
// // 设置 Wi-Fi 为热点模式
// WiFi.softAP(ssid, password);
// // 输出热点信息
// Serial.println("Hotspot created!");
// Serial.print("IP address: ");
// Serial.println(WiFi.softAPIP()); // 输出热点的 IP 地址
// Serial.println("Setup completed!");
// // 设置蓝牙
// Serial.println("Bluetooth Device is Ready to Pair");
// // 设置温度传感器
// sensors.begin();
// Serial.println("DS18B20 is started");
// // 设置路由
// server.on("/", handleRoot); // 处理根路径请求
// server.on("/temperature", []()
// {
// sensors.requestTemperatures();
// float temperatureC = sensors.getTempCByIndex(0);
// server.send(200, "text/plain", "Temperature (°C): " + String(temperatureC)); });
// server.on("/gps", handleGPS);
// server.on("/infrared", handleInfrared); // 删除此行
// // 启动服务器
// server.begin();
// Serial.println("HTTP server started");
}
// 主循环函数,不断运行
void loop()
{
// 读取RFID卡
if (readRFID())
{
// 点亮RGB蓝灯
turnOnLEDBlue();
// 打印RFID卡号
printRFIDData();
// 查询RFID卡的编号,编号对地图上的位置
int id = queryPositionByRFID(RFID_TABLE, RFID_NUM);
Serial.println(String(id));
// 根据位置,执行相应动作
if (id != -1)
doAction(id);
// 关闭RGB蓝灯
turnOffLEDBlue();
}
// 巡线运动
followLine();
// web server请求
// server.handleClient(); // 处理客户端请求
// // 输出超声波测距数据
// float distance = readDistance();
// Serial.print("Distance: ");
// Serial.print(distance);
// Serial.println(" cm");
// 读取 GPS 数据
// processGPSData();
// 读取温度
// readTemperature();
// 延迟
delay(100);
}
帮顶,这个真不懂
有没有具体的错误信息?
有没有具体的错误信息?
代码可以运行,怀疑是rfid的运行效率问题,温度可以输出。
//rfid.h
#ifndef RFID_H
#define RFID_H
// 读取RFID卡,返回1表示读取到卡号;返回0表示未读到卡号。
bool readRFID(void);
// 打印读到的RFID卡的卡号
void printRFIDData(void);
// 查询rfid卡对应的编号,编号对应地图上的不同位置
int queryPositionByRFID(char RFID_TABLE[7], int rfid_num);
#endif // RFID_H
//rfid.cpp
#include “Arduino.h”
// 存放RFID卡号
char RFID[14];
// 读取RFID卡。返回true表示读取到RFID卡;返回false表示未读到RFID卡。
bool readRFID(void)
{
int serial2_length; // 获取串口数据长度
if (Serial2.available() > 0)
{
char incomingByte = Serial2.read();
if (incomingByte == 0x02) // 判断起始位是否正确
{
serial2_length = Serial2.readBytes(RFID, 13); // 数据长度达到一个完整的数据包
if (serial2_length == 13 && RFID[12] == 0x03) // 判断长度和结束位是否正确
{
return true; // 成功读取到一张卡
}
else
{
return false; // 失败
}
}
}
return false; // 失败
}
// 打印读到的RFID卡卡号
void printRFIDData(void)
{
for (int i = 4; i < 10; i++)
{
Serial.print(RFID[i]);
delay(2);
}
Serial.println();
}
// 若读到RFID卡,则找到对应的RFID卡号,并根据卡号获取位置信息
int queryPositionByRFID(char RFID_TABLE[7], int rfid_num)
{
bool founded; // 判断是否找到对应卡号
for (int n = 0; n < rfid_num; n++)
{
founded = true; // 假设已找到
for (int i = 0; i < 6; i++)
{
// 若有一个字符不匹配,则表示匹配失败
if (RFID[i + 4] != RFID_TABLE[n][i])
{
founded = false;
break; // 匹配下一张卡
}
}
// 若founded为true,说明已经找到对应的RFID卡号
if (founded == true)
{
return n;
}
}
return -1; // 未找到对应卡号
}
希望大家可以帮帮我,明天就要交材料了
1没有错误信息输出
2既然你已经怀疑到rfid上了,你就不去排查链接rfid的接口有没有写错啊,不去排查端口有没有接错啊,查查是不是有什么效率冲突了啊。都一点一点排查
加点打印,屏蔽巡线逻辑单独调串口rfid模块
rfid单独可以输出,但是loop函数里的其他可以运行
那你就把rfid先放到小核的线程里跑吧
谢谢大神,帮我改改
给你个例子,调试中遇到的问题可以问gpt
#include <Arduino.h>
void rfid_read_task(void *parameter) {
int count = 0;
while (true) {
// read rfid card from Serial
vTaskDelay(1000 / portTICK_PERIOD_MS); // 延迟 1 秒
}
}
void setup() {
Serial.begin(115200);
// 创建 countTask 任务
xTaskCreate(
rfid_read_task, // 任务函数
"RFID Reader", // 任务名称(调试用)
1024, // 任务堆栈大小
NULL, // 传递给任务的参数
1, // 任务优先级
NULL // 任务句柄
);
}
void loop() {
// loop 中无需任何代码
}