1. 历时两天,完整且完美的设计了宠物类,使用到了多种设计模式,完成了低耦合,高内聚的完美代码,测试也完美通过。
2. 顺便完善了底层通信类的封装,基于websocket,基准测试通过,但存在一点很小的线程bug,似乎是来自于esp32 idf底层的问题,待解决
This commit is contained in:
@@ -20,17 +20,6 @@ const auto sleep_time = seconds{
|
||||
5
|
||||
};
|
||||
|
||||
esp_pthread_cfg_t create_config(const char *name, int core_id, int stack, int prio)
|
||||
{
|
||||
|
||||
auto cfg = esp_pthread_get_default_config();
|
||||
cfg.thread_name = name;
|
||||
cfg.pin_to_core = core_id;
|
||||
cfg.stack_size = stack;
|
||||
cfg.prio = prio;
|
||||
return cfg;
|
||||
}
|
||||
|
||||
#include "ThreadManager.h"
|
||||
#include "WifiConnectors.h"
|
||||
#include <string>
|
||||
@@ -38,6 +27,124 @@ esp_pthread_cfg_t create_config(const char *name, int core_id, int stack, int pr
|
||||
#include "LVGLRender.h"
|
||||
#include "SDFileManager.h"
|
||||
#include "AudioOutput.h"
|
||||
#include "CommClass.h"
|
||||
// JSON数据回调函数
|
||||
void onJsonData(cJSON* json) {
|
||||
// 打印接收到的JSON数据
|
||||
char* jsonStr = cJSON_Print(json);
|
||||
ESP_LOGI("JSON_CALLBACK", "收到JSON数据: %s", jsonStr);
|
||||
free(jsonStr);
|
||||
|
||||
// 解析消息类型并处理
|
||||
cJSON* type = cJSON_GetObjectItem(json, "type");
|
||||
if (type && cJSON_IsString(type)) {
|
||||
if (strcmp(type->valuestring, "greeting") == 0) {
|
||||
ESP_LOGI("JSON_CALLBACK", "收到服务器问候消息");
|
||||
} else if (strcmp(type->valuestring, "heartbeat") == 0) {
|
||||
ESP_LOGI("JSON_CALLBACK", "收到心跳响应");
|
||||
} else if (strcmp(type->valuestring, "response") == 0) {
|
||||
ESP_LOGI("JSON_CALLBACK", "收到服务器响应");
|
||||
} else if (strcmp(type->valuestring, "echo") == 0) {
|
||||
ESP_LOGI("JSON_CALLBACK", "收到回显消息");
|
||||
} else if (strcmp(type->valuestring, "broadcast") == 0) {
|
||||
ESP_LOGI("JSON_CALLBACK", "收到广播消息");
|
||||
}
|
||||
}
|
||||
|
||||
// 记得删除cJSON对象
|
||||
cJSON_Delete(json);
|
||||
}
|
||||
|
||||
// WebSocket事件回调函数
|
||||
void onWebSocketEvent(WebSocketEvent event, const std::string& message) {
|
||||
switch (event) {
|
||||
case WebSocketEvent::CONNECTED:
|
||||
ESP_LOGI("EVENT_CALLBACK", "WebSocket已连接: %s", message.c_str());
|
||||
break;
|
||||
case WebSocketEvent::DISCONNECTED:
|
||||
ESP_LOGI("EVENT_CALLBACK", "WebSocket已断开: %s", message.c_str());
|
||||
break;
|
||||
case WebSocketEvent::DATA_RECEIVED:
|
||||
ESP_LOGI("EVENT_CALLBACK", "收到原始数据: %s", message.c_str());
|
||||
break;
|
||||
case WebSocketEvent::ERROR:
|
||||
ESP_LOGE("EVENT_CALLBACK", "WebSocket错误: %s", message.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 发送状态信息函数
|
||||
void sendStatus() {
|
||||
cJSON* status = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(status, "type", "status");
|
||||
|
||||
cJSON* data = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(data, "free_heap", esp_get_free_heap_size());
|
||||
cJSON_AddNumberToObject(data, "uptime", xTaskGetTickCount() * portTICK_PERIOD_MS / 1000);
|
||||
|
||||
cJSON_AddItemToObject(status, "data", data);
|
||||
|
||||
if (WebSocketManager::getInstance()->sendJson(status)) {
|
||||
ESP_LOGI("SEND", "已发送状态信息");
|
||||
} else {
|
||||
ESP_LOGE("SEND", "发送状态信息失败");
|
||||
}
|
||||
}
|
||||
|
||||
// 发送问候消息函数
|
||||
void sendGreeting() {
|
||||
cJSON* greeting = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(greeting, "type", "greeting");
|
||||
cJSON_AddStringToObject(greeting, "message", "Hello from ESP32-S3");
|
||||
cJSON_AddNumberToObject(greeting, "timestamp", xTaskGetTickCount() * portTICK_PERIOD_MS / 1000);
|
||||
|
||||
if (WebSocketManager::getInstance()->sendJson(greeting)) {
|
||||
ESP_LOGI("SEND", "已发送问候消息");
|
||||
} else {
|
||||
ESP_LOGE("SEND", "发送问候消息失败");
|
||||
}
|
||||
}
|
||||
|
||||
void websocket_task() {
|
||||
TickType_t lastStatusTime = 0;
|
||||
TickType_t lastHeartbeatTime = 0;
|
||||
TickType_t lastGreetingTime = 0;
|
||||
|
||||
while (true) {
|
||||
TickType_t currentTime = xTaskGetTickCount();
|
||||
|
||||
// 检查连接状态
|
||||
if (!WebSocketManager::getInstance()->isConnected()) {
|
||||
ESP_LOGI("APP_TASK", "WebSocket未连接,尝试重新连接...");
|
||||
|
||||
// 确保WiFi已连接
|
||||
if (!WifiConnectors::getInstance()->isWifiConnect()) {
|
||||
ESP_LOGI("APP_TASK", "WiFi未连接,等待WiFi连接...");
|
||||
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (WebSocketManager::getInstance()->connect()) {
|
||||
ESP_LOGI("APP_TASK", "重新连接成功");
|
||||
} else {
|
||||
ESP_LOGI("APP_TASK", "重新连接失败");
|
||||
}
|
||||
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
||||
continue;
|
||||
}
|
||||
// 每10秒发送状态信息
|
||||
if (currentTime - lastStatusTime > (10000 / portTICK_PERIOD_MS)) {
|
||||
sendStatus();
|
||||
lastStatusTime = currentTime;
|
||||
}
|
||||
// 每60秒发送问候
|
||||
if (currentTime - lastGreetingTime > (60000 / portTICK_PERIOD_MS)) {
|
||||
sendGreeting();
|
||||
lastGreetingTime = currentTime;
|
||||
}
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
void OTAClass::Init() {
|
||||
ESP_LOGI("OTA", "Init");
|
||||
@@ -65,27 +172,67 @@ void OTAClass::Init() {
|
||||
// 同步播放
|
||||
AudioOutput::getInstance()->playSync("/sdcard/music", "Old_Memory.mp3");
|
||||
|
||||
// 等待5秒
|
||||
// vTaskDelay(pdMS_TO_TICKS(10000));
|
||||
|
||||
// 暂停
|
||||
// AudioOutput::getInstance()->pause();
|
||||
// // 配置Wifi连接线程参数
|
||||
// ThreadConfig wifi_config;
|
||||
// wifi_config.name = "WifiConnector"; // 线程名称
|
||||
// wifi_config.core_id = 1; // 绑定到核心1(避免与主线程冲突)
|
||||
// wifi_config.stack_size = 4096; // 设置稍大的栈空间(Wifi连接可能需要)
|
||||
// wifi_config.priority = 6; // 设置较高优先级(确保连接及时)
|
||||
// // 使用单例方式创建线程,调用connectWifi成员函数
|
||||
// std::thread wifi_thread = ThreadManager::createSingletonThread<WifiConnectors>(
|
||||
// wifi_config,
|
||||
// &WifiConnectors::connectWifi,
|
||||
// "Misaki-2.4G", // SSID
|
||||
// "88888888", // 密码
|
||||
// 5 // 最大重试次数
|
||||
// );
|
||||
// wifi_thread.detach();
|
||||
|
||||
WifiConnectors::getInstance()->connectWifi("Misaki-2.4G", "88888888", 5);
|
||||
|
||||
|
||||
// 配置Wifi连接线程参数
|
||||
ThreadConfig wifi_config;
|
||||
wifi_config.name = "WifiConnector"; // 线程名称
|
||||
wifi_config.core_id = 1; // 绑定到核心1(避免与主线程冲突)
|
||||
wifi_config.stack_size = 4096; // 设置稍大的栈空间(Wifi连接可能需要)
|
||||
wifi_config.priority = 6; // 设置较高优先级(确保连接及时)
|
||||
// 使用单例方式创建线程,调用connectWifi成员函数
|
||||
std::thread wifi_thread = ThreadManager::createSingletonThread<WifiConnectors>(
|
||||
wifi_config,
|
||||
&WifiConnectors::connectWifi,
|
||||
"Misaki-2.4G", // SSID
|
||||
"88888888", // 密码
|
||||
5 // 最大重试次数
|
||||
);
|
||||
// 等待WiFi连接成功后再连接WebSocket
|
||||
ESP_LOGI("APP_TASK", "等待WiFi连接...");
|
||||
while (!WifiConnectors::getInstance()->isWifiConnect()) {
|
||||
ESP_LOGI("APP_TASK", "WiFi未连接,等待中...");
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
// 配置WebSocket
|
||||
WebSocketConfig config;
|
||||
config.uri = "ws://" + std::string("192.168.1.11") + ":" + std::to_string(8080) + "/ws";
|
||||
config.auto_reconnect = true; // 自动重连
|
||||
config.reconnect_interval = 5000; // 重连间隔(毫秒)
|
||||
config.heartbeat_interval = 30000; // 心跳间隔(毫秒)
|
||||
config.max_reconnect_attempts = 10; // 最大重连尝试次数
|
||||
// TODO: 此处通信类存在线程重复创建bug,似乎是来自esp-idf的bug,待查证
|
||||
// 初始化WebSocket管理器
|
||||
// if (!WebSocketManager::getInstance()->initialize(config)) {
|
||||
// ESP_LOGE("APP_TASK", "WebSocket管理器初始化失败");
|
||||
// vTaskDelete(NULL);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// 设置回调函数
|
||||
// WebSocketManager::getInstance()->setJsonCallback(onJsonData);
|
||||
// WebSocketManager::getInstance()->setEventCallback(onWebSocketEvent);
|
||||
|
||||
// 连接WebSocket服务器
|
||||
// ESP_LOGI("APP_TASK", "正在连接WebSocket服务器: %s", config.uri.c_str());
|
||||
// if (!WebSocketManager::getInstance()->connect()) {
|
||||
// ESP_LOGE("APP_TASK", "WebSocket连接失败");
|
||||
// }
|
||||
|
||||
// 创建WebSocket任务
|
||||
// ThreadConfig websocket_config;
|
||||
// websocket_config.core_id = 0;
|
||||
// websocket_config.inherit_cfg = true;
|
||||
// websocket_config.name = "websocket_task";
|
||||
// websocket_config.priority = 5;
|
||||
// websocket_config.stack_size = 4096;
|
||||
// std::thread websocket_thread = ThreadManager::createThread(websocket_config, websocket_task);
|
||||
// websocket_thread.detach();
|
||||
|
||||
// ThreadConfig ota_config;
|
||||
// ota_config.name = "OTA";
|
||||
|
||||
Reference in New Issue
Block a user