feat: 添加MQTT客户端任务,优化数据上报频率控制,移除冗余日志输出

This commit is contained in:
Admin
2026-04-17 17:58:51 +08:00
parent 0fa483f450
commit 5d0202afae
23 changed files with 6511 additions and 3634 deletions

View File

@@ -5,616 +5,76 @@
#include <Preferences.h>
#include "wifi_manager.h"
#include "radar_manager.h"
// ESP32 GPIO控制演示
#define BOOT_BUTTON_PIN 0 // Boot按钮引脚
#define NETWORK_LED_PIN 5 // 网络状态LED指示灯开发板48引脚雷达板5引脚
#define CONFIG_CLEAR_PIN 4 // 配置清除指示灯
#define GPIO8 8 // 自定义GPIO8
#define GPIO9 9 // 自定义GPIO9
uint8_t WiFi_Connect_First_bit = 1; // WiFi首次连接标志位
// 配置清除指示灯状态枚举
enum ConfigClearStatus {
CONFIG_NORMAL, // 正常运行 - LOW
CONFIG_PREPARING, // 准备清除 - HIGH
CONFIG_CLEARING, // 清除过程中 - 呼吸灯
CONFIG_COMPLETED // 清除完成 - 快速闪烁3次
};
NetworkStatus currentNetworkStatus = NET_INITIAL; // 当前网络状态
unsigned long lastBlinkTime = 0; // 上次LED闪烁时间
bool ledState = false; // LED状态
int breatheValue = 0; // 呼吸灯当前亮度值
bool breatheIncreasing = true; // 呼吸灯是否在增加亮度
ConfigClearStatus currentConfigClearStatus = CONFIG_NORMAL; // 当前配置清除状态
unsigned long lastConfigBlinkTime = 0; // 上次配置清除LED闪烁时间
bool configLedState = false; // 配置清除LED状态
int configBreatheValue = 0; // 配置清除呼吸灯当前亮度值
bool configBreatheIncreasing = true; // 配置清除呼吸灯是否在增加亮度
const int SLOW_BLINK_INTERVAL = 1000; // 慢闪间隔(毫秒)
const int FAST_BLINK_INTERVAL = 200; // 快闪间隔(毫秒)
const int BREATHE_INTERVAL = 40; // 呼吸灯更新间隔(毫秒)
const int BREATHE_MIN = 0; // 呼吸灯最小亮度值
const int BREATHE_MAX = 155; // 呼吸灯最大亮度值
const int BREATHE_STEP = 5; // 呼吸灯亮度步进值
const uint16_t MIN_DEVICE_ID = 1000; // 最小设备ID
const uint16_t MAX_DEVICE_ID = 1999; // 最大设备ID
const unsigned long CLEAR_CONFIG_DURATION = 3000; // 清除配置持续时间(毫秒)
#include "data_processor.h"
#include "emotion_analyzer_simple.h"
#include "tasks_manager.h"
Preferences preferences; // Flash存储对象
WiFiManager wifiManager; // WiFi管理器对象
uint16_t currentDeviceId = 0000; // 当前设备ID
bool clearConfigRequested = false; // 清除配置请求标志
bool forceLedOff = false; // 强制关闭LED标志
void configClearLedTask(void *parameter);
void bootButtonMonitorTask(void *parameter);
void checkBootButton();
void clearStoredConfig();
void ledControlTask(void *parameter);
void setNetworkStatus(NetworkStatus status);
void wifiMonitorTask(void *parameter);
void WiFiEvent(WiFiEvent_t event);
void loadDeviceId();
void saveDeviceId();
String getFieldNameByProtocolId(int protocolId);
/**
* @brief 根据协议ID获取字段名称
* 将协议ID映射到对应的字段名称用于数据序列化和反序列化
* @param protocolId 协议ID
* @return 对应的字段名称字符串
*/
String getFieldNameByProtocolId(int protocolId) {
switch(protocolId) {
case 1:
return "heartRate";
case 2:
return "breathingRate";
case 13:
return "personDetected";
case 14:
return "humanActivity";
case 15:
return "humanDistance";
case 16:
return "humanPosition";
case 17:
return "sleepState";
default:
return "unknown";
}
}
/**
* @brief 检查Boot按钮状态
* 在启动时检查Boot按钮是否被按下如果按下则进入配置清除流程
*/
void checkBootButton() {
Serial.println("🔍 检查Boot按钮状态...");
pinMode(BOOT_BUTTON_PIN, INPUT_PULLUP);
delay(10);
int buttonState = digitalRead(BOOT_BUTTON_PIN);
Serial.printf("📊 Boot按钮状态: %s\n", buttonState == LOW ? "按下" : "释放");
if (buttonState == LOW) {
Serial.println("⚠️ 检测到Boot按钮按下请释放按钮后继续启动");
Serial.println("⏰ 等待按钮释放...");
while (digitalRead(BOOT_BUTTON_PIN) == LOW) {
delay(100);
}
Serial.println("✅ Boot按钮已释放正常启动");
} else {
Serial.println("✅ Boot按钮未按下正常启动");
}
}
/**
* @brief 加载设备ID
* 从Flash中读取保存的设备ID
*/
void loadDeviceId() {
currentDeviceId = preferences.getUShort("deviceId", 1001);
Serial.printf("从Flash加载设备ID: %u\n", currentDeviceId);
}
/**
* @brief 保存设备ID
* 将设备ID保存到Flash中
*/
void saveDeviceId() {
preferences.putUShort("deviceId", currentDeviceId);
Serial.printf("设备ID已保存到Flash: %u\n", currentDeviceId);
}
/**
* @brief 清除存储的配置
* 清除Flash中保存的所有配置包括设备ID和WiFi配置
*/
void clearStoredConfig() {
Serial.println("🧹 开始清除存储的配置...");
uint16_t oldDeviceId = preferences.getUShort("deviceId", 0);
preferences.remove("deviceId");
preferences.remove("wifi_first");
wifiManager.clearAllConfigs();
Serial.println("✅ 配置已清除完成");
Serial.printf("🗑️ 被清除的设备ID: %u\n", oldDeviceId);
currentDeviceId = 1001;
WiFi_Connect_First_bit = 1;
WiFi.disconnect(true);
setNetworkStatus(NET_DISCONNECTED);
Serial.println("🔄 已清除Flash与内存中的配置请重新配置WiFi和设备ID");
if (deviceConnected) {
sendStatusToBLE();
}
}
/**
* @brief 配置清除LED控制任务
* 根据配置清除状态控制CONFIG_CLEAR_PIN引脚的LED显示
* @param parameter 任务参数(未使用)
*/
void configClearLedTask(void *parameter) {
while (1) {
switch (currentConfigClearStatus) {
case CONFIG_NORMAL:
analogWrite(CONFIG_CLEAR_PIN, 0);
break;
case CONFIG_PREPARING:
analogWrite(CONFIG_CLEAR_PIN, 255);
break;
case CONFIG_CLEARING:
if (millis() - lastConfigBlinkTime >= BREATHE_INTERVAL) {
analogWrite(CONFIG_CLEAR_PIN, configBreatheValue);
if (configBreatheIncreasing) {
configBreatheValue += 5;
if (configBreatheValue >= BREATHE_MAX) {
configBreatheValue = BREATHE_MAX;
configBreatheIncreasing = false;
}
} else {
configBreatheValue -= 5;
if (configBreatheValue <= BREATHE_MIN) {
configBreatheValue = BREATHE_MIN;
configBreatheIncreasing = true;
}
}
lastConfigBlinkTime = millis();
}
break;
case CONFIG_COMPLETED:
if (millis() - lastConfigBlinkTime >= FAST_BLINK_INTERVAL) {
configLedState = !configLedState;
digitalWrite(CONFIG_CLEAR_PIN, configLedState ? HIGH : LOW);
lastConfigBlinkTime = millis();
static int blinkCount = 0;
blinkCount++;
if (blinkCount >= 6) {
blinkCount = 0;
currentConfigClearStatus = CONFIG_NORMAL;
digitalWrite(CONFIG_CLEAR_PIN, LOW);
}
}
break;
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
/**
* @brief BOOT按钮监控任务
* 持续监控BOOT按钮状态检测长按3秒事件并触发配置清除
* @param parameter 任务参数(未使用)
*/
void bootButtonMonitorTask(void *parameter) {
Serial.println("🔍 启动BOOT按钮监控任务...");
pinMode(BOOT_BUTTON_PIN, INPUT_PULLUP);
unsigned long buttonPressStartTime = 0;
bool buttonPressed = false;
while (1) {
int buttonState = digitalRead(BOOT_BUTTON_PIN);
if (buttonState == LOW && !buttonPressed) {
buttonPressed = true;
buttonPressStartTime = millis();
Serial.println("⚠️ 检测到BOOT按钮按下长按3秒将清除配置");
currentConfigClearStatus = CONFIG_PREPARING;
}
else if (buttonState == HIGH && buttonPressed) {
if (!clearConfigRequested) {
currentConfigClearStatus = CONFIG_NORMAL;
Serial.println("❌ 按钮释放,取消清除操作");
}
buttonPressed = false;
}
if (buttonPressed && (millis() - buttonPressStartTime >= CLEAR_CONFIG_DURATION)) {
if (!clearConfigRequested) {
clearConfigRequested = true;
forceLedOff = true;
ledcWrite(0, 0);
Serial.println("✅ 长按3秒确认将清除配置");
Serial.println("💡 网络LED已强制熄灭");
clearStoredConfig();
Serial.println("🔄 配置清除完成LED将闪烁3次表示完成...");
analogWrite(CONFIG_CLEAR_PIN, 0);
Serial.println("🔄 系统即将重启...");
vTaskDelay(1000 / portTICK_PERIOD_MS);
ESP.restart();
}
}
vTaskDelay(50 / portTICK_PERIOD_MS);
esp_task_wdt_reset();
}
}
/**
* @brief LED控制任务
* 根据网络状态控制NETWORK_LED_PIN引脚的LED显示
* 支持慢闪、快闪和呼吸灯效果
* @param parameter 任务参数(未使用)
*/
void ledControlTask(void *parameter) {
while (1) {
if (forceLedOff) {
ledcWrite(0, 0);
vTaskDelay(10 / portTICK_PERIOD_MS);
continue;
}
switch (currentNetworkStatus) {
case NET_INITIAL:
case NET_DISCONNECTED:
if (millis() - lastBlinkTime >= SLOW_BLINK_INTERVAL) {
ledState = !ledState;
if(ledState) {
ledcWrite(0, 255);
} else {
ledcWrite(0, 0);
}
lastBlinkTime = millis();
}
break;
case NET_CONNECTING:
if (millis() - lastBlinkTime >= FAST_BLINK_INTERVAL) {
ledState = !ledState;
if(ledState) {
ledcWrite(0, 255);
} else {
ledcWrite(0, 0);
}
lastBlinkTime = millis();
}
break;
case NET_CONNECTED:
if (millis() - lastBlinkTime >= BREATHE_INTERVAL) {
ledcWrite(0, breatheValue);
if (breatheIncreasing) {
breatheValue += BREATHE_STEP;
if (breatheValue >= BREATHE_MAX) {
breatheValue = BREATHE_MAX;
breatheIncreasing = false;
}
} else {
breatheValue -= BREATHE_STEP;
if (breatheValue <= BREATHE_MIN) {
breatheValue = BREATHE_MIN;
breatheIncreasing = true;
}
}
lastBlinkTime = millis();
}
break;
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
/**
* @brief 设置网络状态
* 更新当前网络状态,并重置呼吸灯参数
* @param status 网络状态
*/
void setNetworkStatus(NetworkStatus status) {
currentNetworkStatus = status;
if (status == NET_CONNECTED) {
breatheValue = BREATHE_MIN;
breatheIncreasing = true;
}
}
/**
* @brief WiFi事件处理函数
* 处理WiFi连接状态变化事件更新网络状态和LED显示
* @param event WiFi事件类型
*/
void WiFiEvent(WiFiEvent_t event) {
switch (event) {
case ARDUINO_EVENT_WIFI_STA_START:
setNetworkStatus(NET_INITIAL);
break;
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
setNetworkStatus(NET_CONNECTING);
break;
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
setNetworkStatus(NET_CONNECTED);
break;
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
setNetworkStatus(NET_DISCONNECTED);
break;
case ARDUINO_EVENT_WIFI_STA_STOP:
setNetworkStatus(NET_DISCONNECTED);
break;
}
}
/**
* @brief WiFi监控任务
* 定期更新WiFi管理器状态处理WiFi重连等逻辑
* @param parameter 任务参数(未使用)
*/
void wifiMonitorTask(void *parameter) {
Serial.println("📡 WiFi监控任务启动");
while(1) {
wifiManager.update();
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
/**
* @brief 系统初始化函数
* 初始化所有硬件外设、任务和通信模块
*/
void setup() {
Serial.begin(115200);
checkBootButton();
analogWrite(CONFIG_CLEAR_PIN, 0);
Serial.println("🚀 ESP32-R60ABD1系统启动");
Serial.println("🔧 初始化系统组件...");
pinMode(BOOT_BUTTON_PIN, INPUT);
pinMode(NETWORK_LED_PIN, OUTPUT);
pinMode(CONFIG_CLEAR_PIN, OUTPUT);
pinMode(GPIO8, OUTPUT);
pinMode(GPIO9, OUTPUT);
digitalWrite(CONFIG_CLEAR_PIN, LOW);
digitalWrite(GPIO8, LOW);
digitalWrite(GPIO9, LOW);
digitalWrite(NETWORK_LED_PIN, LOW);
digitalWrite(CONFIG_CLEAR_PIN, LOW);
ledcSetup(0, 5000, 8);
ledcSetup(1, 5000, 8);
ledcAttachPin(NETWORK_LED_PIN, 0);
ledcAttachPin(CONFIG_CLEAR_PIN, 1);
WiFi.onEvent(WiFiEvent);
setNetworkStatus(NET_INITIAL);
esp_task_wdt_init(30, true);
esp_task_wdt_add(NULL);
preferences.begin("radar_data", false);
wifiManager.begin();
Serial.println("💾 加载设备配置...");
loadDeviceId();
Serial.println("🏗️ 初始化雷达管理器...");
initRadarManager();
xTaskCreate(
configClearLedTask,
"Config Clear LED Task",
2048,
NULL,
1,
NULL
);
xTaskCreate(
bootButtonMonitorTask,
"Boot Button Monitor Task",
2048,
NULL,
1,
NULL
);
xTaskCreate(
ledControlTask,
"LED Control Task",
2048,
NULL,
1,
NULL
);
xTaskCreate(
wifiMonitorTask,
"WiFi Monitor Task",
4096,
NULL,
2,
NULL
);
Serial.println("✅ FreeRTOS任务创建成功");
Serial.println("📶 初始化BLE服务...");
String deviceName = "Radar_" + String(currentDeviceId);
BLEDevice::init(deviceName.c_str());
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
BLEService *pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY
);
pCharacteristic->setCallbacks(new MyCallbacks());
pCharacteristic->addDescriptor(new BLE2902());
pService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06);
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();
Serial.println(String("BLE已启动设备名称: Radar_") + String(currentDeviceId));
Serial.println("🌐 检查WiFi配置...");
if (wifiManager.getSavedNetworkCount() > 0) {
Serial.printf("💾 检测到 %d 个已保存的WiFi配置尝试连接...\n", wifiManager.getSavedNetworkCount());
if (wifiManager.initializeWiFi()) {
Serial.println("✅ WiFi连接成功");
} else {
Serial.println("❌ WiFi连接失败请通过BLE重新配置");
}
} else {
Serial.println("⚠️ 未检测到WiFi配置请通过BLE进行网络配置");
}
size_t wifi_first_len = preferences.getBytes("wifi_first", &WiFi_Connect_First_bit, sizeof(WiFi_Connect_First_bit));
if (wifi_first_len == sizeof(WiFi_Connect_First_bit)) {
Serial.printf("从Flash读取 WiFi_Connect_First_bit: %u\n", WiFi_Connect_First_bit);
} else {
Serial.println("Flash中无 wifi_first 条目,保留内存中原始值");
}
if(WiFi_Connect_First_bit == 0)
{
unsigned long wifiWaitStart = millis();
unsigned long lastWifiWaitPrint = 0;
const unsigned long WIFI_WAIT_TIMEOUT = 15000;
while (WiFi.status() != WL_CONNECTED && (millis() - wifiWaitStart) < WIFI_WAIT_TIMEOUT) {
if (millis() - lastWifiWaitPrint >= 1000) {
Serial.println("等待WiFi连接...");
lastWifiWaitPrint = millis();
}
yield();
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
Serial.println("WiFi连接成功");
initR60ABD1();
Serial.println("🎉 系统初始化完成,等待雷达数据...");
if (WiFi.status() == WL_CONNECTED) {
Serial.println("🌅 启动时发送睡眠数据到数据库");
Serial.begin(115200); // 初始化串口通信
checkBootButton(); // 检查Boot按钮状态
analogWrite(CONFIG_CLEAR_PIN, 0); // 关闭配置清除指示灯
WiFi.onEvent(WiFiEvent); // 注册WiFi事件处理函数
setNetworkStatus(NET_INITIAL); // 初始化网络状态
esp_task_wdt_init(30, true); // 初始化看门狗定时器
esp_task_wdt_add(NULL); // 将主任务添加到看门狗
preferences.begin("radar_data", false); // 初始化Flash存储
loadDeviceId(); // 加载设备ID
initRadarManager(); // 初始化雷达管理器
initAllTasks(); // 创建所有FreeRTOS任务
if (WiFi.status() == WL_CONNECTED) // 启动时发送睡眠数据
sendSleepDataToInfluxDB();
}
Serial.println("✅ 系统初始化完成");
}
/**
* @brief 主循环函数
* 处理BLE连接状态和定期发送雷达命令
* 主循环只负责看门狗重置,保持空闲
*/
void loop() {
esp_task_wdt_reset();
if (!deviceConnected && oldDeviceConnected) {
vTaskDelay(500 / portTICK_PERIOD_MS);
pServer->startAdvertising();
Serial.println("开始BLE广播");
oldDeviceConnected = deviceConnected;
}
if (deviceConnected && !oldDeviceConnected) {
oldDeviceConnected = deviceConnected;
}
{
static const uint8_t radar_cmds[][3] = {
{0x84, 0x81, 0x0F},
{0x84, 0x8D, 0x0F},
{0x84, 0x8F, 0x0F},
{0x84, 0x8E, 0x0F},
{0x84, 0x91, 0x0F},
{0x84, 0x92, 0x0F},
{0x84, 0x83, 0x0F},
{0x84, 0x84, 0x0F},
{0x84, 0x85, 0x0F},
{0x84, 0x86, 0x0F},
{0x84, 0x90, 0x0F}
};
const size_t cmdCount = sizeof(radar_cmds) / sizeof(radar_cmds[0]);
static size_t cmdIndex = 0;
static unsigned long lastCmdMillis = 0;
const unsigned long CMD_INTERVAL = 2000UL;
unsigned long now = millis();
if (now - lastCmdMillis >= CMD_INTERVAL) {
sendRadarCommand(radar_cmds[cmdIndex][0], radar_cmds[cmdIndex][1], radar_cmds[cmdIndex][2]);
lastCmdMillis = now;
cmdIndex++;
if (cmdIndex >= cmdCount) cmdIndex = 0;
}
}
processBLEConfig();
esp_task_wdt_reset();
esp_task_wdt_reset();
esp_task_wdt_reset();
vTaskDelay(100 / portTICK_PERIOD_MS);
}
/**
* @brief 检查Boot按钮状态
* 在启动时检查Boot按钮是否松开等待松开后再启动避免频繁重启
*/
void checkBootButton() {
pinMode(BOOT_BUTTON_PIN, INPUT_PULLUP);
delay(10);
if (digitalRead(BOOT_BUTTON_PIN) == LOW) {
Serial.println("⚠️ 检测到Boot按钮按下请释放按钮后继续启动");
while (digitalRead(BOOT_BUTTON_PIN) == LOW) {
delay(50);
}
Serial.println("✅ Boot按钮已释放正常启动");
}
}
/**
* @brief 加载设备ID
* 从Flash中读取保存的设备ID如果Flash中没有则使用默认值1001并保存
*/
void loadDeviceId() {
if (preferences.isKey("deviceId")) {
currentDeviceId = preferences.getUShort("deviceId", 1001);
} else {
currentDeviceId = 1001;
preferences.putUShort("deviceId", currentDeviceId);
Serial.printf("Flash中无设备ID使用默认值1001并保存\n");
}
Serial.printf("从Flash加载设备ID: %u\n", currentDeviceId);
}