621 lines
18 KiB
C++
621 lines
18 KiB
C++
|
|
#include <Arduino.h>
|
|||
|
|
#include <WiFi.h>
|
|||
|
|
#include <esp_task_wdt.h>
|
|||
|
|
#include <ArduinoJson.h>
|
|||
|
|
#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; // 清除配置持续时间(毫秒)
|
|||
|
|
|
|||
|
|
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("🌅 启动时发送睡眠数据到数据库");
|
|||
|
|
sendSleepDataToInfluxDB();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @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();
|
|||
|
|
}
|
|||
|
|
|