97fe13da26
2. 修复了LVGL渲染类当中的一些小bug 3. 增加了一些CPU资源占用的日志打印函数,运行在主线程当中 4. 完善了底层通信类的封装,基于websocket,尚未测试
309 lines
8.0 KiB
Markdown
309 lines
8.0 KiB
Markdown
### 如你所见,这只是一个临时文件
|
|
|
|
|
|
|
|
```c++
|
|
// 描述了每个驱动的启动顺序
|
|
#include "ST77916.h"
|
|
#include "PCF85063.h"
|
|
#include "QMI8658.h"
|
|
#include "SD_MMC.h"
|
|
#include "Wireless.h"
|
|
#include "TCA9554PWR.h"
|
|
#include "LVGL_Example.h"
|
|
#include "BAT_Driver.h"
|
|
#include "PWR_Key.h"
|
|
#include "PCM5101.h"
|
|
#include "MIC_Speech.h"
|
|
|
|
void Driver_Loop(void *parameter)
|
|
{
|
|
Wireless_Init();
|
|
while(1)
|
|
{
|
|
QMI8658_Loop();
|
|
PCF85063_Loop();
|
|
BAT_Get_Volts();
|
|
PWR_Loop();
|
|
vTaskDelay(pdMS_TO_TICKS(100));
|
|
}
|
|
vTaskDelete(NULL);
|
|
}
|
|
void Driver_Init(void)
|
|
{
|
|
PWR_Init();
|
|
BAT_Init();
|
|
I2C_Init();
|
|
EXIO_Init(); // Example Initialize EXIO
|
|
Flash_Searching();
|
|
PCF85063_Init();
|
|
QMI8658_Init();
|
|
xTaskCreatePinnedToCore(
|
|
Driver_Loop,
|
|
"Other Driver task",
|
|
4096,
|
|
NULL,
|
|
3,
|
|
NULL,
|
|
0);
|
|
}
|
|
void app_main(void)
|
|
{
|
|
Driver_Init();
|
|
|
|
SD_Init();
|
|
LCD_Init();
|
|
Audio_Init();
|
|
MIC_Speech_init();
|
|
// Play_Music("/sdcard","AAA.mp3");
|
|
LVGL_Init(); // returns the screen object
|
|
|
|
// /********************* Demo *********************/
|
|
// Lvgl_Example1();
|
|
// lv_demo_widgets();
|
|
lv_demo_keypad_encoder();
|
|
// lv_demo_benchmark();
|
|
// lv_demo_stress();
|
|
// lv_demo_music();
|
|
|
|
while (1) {
|
|
// raise the task priority of LVGL and/or reduce the handler period can improve the performance
|
|
vTaskDelay(pdMS_TO_TICKS(10));
|
|
// The task running lv_timer_handler should have lower priority than that running `lv_tick_inc`
|
|
lv_timer_handler();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
```c++
|
|
// esp idf提供的pthread库的使用,主要服务于C++
|
|
|
|
/* pthread/std::thread example
|
|
|
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
|
|
|
Unless required by applicable law or agreed to in writing, this
|
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
CONDITIONS OF ANY KIND, either express or implied.
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <thread>
|
|
#include <chrono>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <esp_pthread.h>
|
|
#include <freertos/FreeRTOS.h>
|
|
#include <freertos/task.h>
|
|
#include <esp_log.h>
|
|
|
|
using namespace std::chrono;
|
|
|
|
const auto sleep_time = seconds {
|
|
5
|
|
};
|
|
|
|
void print_thread_info(const char *extra = nullptr)
|
|
{
|
|
std::stringstream ss;
|
|
if (extra) {
|
|
ss << extra;
|
|
}
|
|
ss << "Core id: " << xPortGetCoreID()
|
|
<< ", prio: " << uxTaskPriorityGet(nullptr)
|
|
<< ", minimum free stack: " << uxTaskGetStackHighWaterMark(nullptr) << " bytes.";
|
|
ESP_LOGI(pcTaskGetName(nullptr), "%s", ss.str().c_str());
|
|
}
|
|
|
|
void thread_func_inherited()
|
|
{
|
|
while (true) {
|
|
print_thread_info("This is the INHERITING thread with the same parameters as our parent, including name. ");
|
|
std::this_thread::sleep_for(sleep_time);
|
|
}
|
|
}
|
|
|
|
void spawn_another_thread()
|
|
{
|
|
// Create a new thread, it will inherit our configuration
|
|
std::thread inherits(thread_func_inherited);
|
|
|
|
while (true) {
|
|
print_thread_info();
|
|
std::this_thread::sleep_for(sleep_time);
|
|
}
|
|
}
|
|
|
|
void thread_func_any_core()
|
|
{
|
|
while (true) {
|
|
print_thread_info("This thread (with the default name) may run on any core.");
|
|
std::this_thread::sleep_for(sleep_time);
|
|
}
|
|
}
|
|
|
|
void thread_func()
|
|
{
|
|
while (true) {
|
|
print_thread_info();
|
|
std::this_thread::sleep_for(sleep_time);
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
extern "C" void app_main(void)
|
|
{
|
|
// Create a thread using default values that can run on any core
|
|
auto cfg = esp_pthread_get_default_config();
|
|
esp_pthread_set_cfg(&cfg);
|
|
std::thread any_core(thread_func_any_core);
|
|
|
|
// Create a thread on core 0 that spawns another thread, they will both have the same name etc.
|
|
cfg = create_config("Thread 1", 0, 3 * 1024, 5);
|
|
cfg.inherit_cfg = true;
|
|
esp_pthread_set_cfg(&cfg);
|
|
std::thread thread_1(spawn_another_thread);
|
|
|
|
// Create a thread on core 1.
|
|
cfg = create_config("Thread 2", 1, 3 * 1024, 5);
|
|
esp_pthread_set_cfg(&cfg);
|
|
std::thread thread_2(thread_func);
|
|
|
|
// Let the main task do something too
|
|
while (true) {
|
|
std::stringstream ss;
|
|
ss << "core id: " << xPortGetCoreID()
|
|
<< ", prio: " << uxTaskPriorityGet(nullptr)
|
|
<< ", minimum free stack: " << uxTaskGetStackHighWaterMark(nullptr) << " bytes.";
|
|
ESP_LOGI(pcTaskGetName(nullptr), "%s", ss.str().c_str());
|
|
std::this_thread::sleep_for(sleep_time);
|
|
}
|
|
}
|
|
```
|
|
|
|
|
|
|
|
```c++
|
|
#include "WebSocketManager.h"
|
|
#include "cJSON.h"
|
|
|
|
// JSON数据回调示例
|
|
void onJsonData(cJSON* json) {
|
|
// 处理接收到的JSON数据
|
|
cJSON* type = cJSON_GetObjectItem(json, "type");
|
|
if (type && cJSON_IsString(type)) {
|
|
ESP_LOGI("App", "Received message type: %s", type->valuestring);
|
|
|
|
if (strcmp(type->valuestring, "sensor_data") == 0) {
|
|
cJSON* value = cJSON_GetObjectItem(json, "value");
|
|
if (value && cJSON_IsNumber(value)) {
|
|
ESP_LOGI("App", "Sensor value: %.2f", value->valuedouble);
|
|
}
|
|
}
|
|
}
|
|
|
|
cJSON_Delete(json);
|
|
}
|
|
|
|
// 事件回调示例
|
|
void onWebSocketEvent(WebSocketEvent event, const std::string& message) {
|
|
switch (event) {
|
|
case WebSocketEvent::CONNECTED:
|
|
ESP_LOGI("App", "WebSocket connected: %s", message.c_str());
|
|
break;
|
|
case WebSocketEvent::DISCONNECTED:
|
|
ESP_LOGI("App", "WebSocket disconnected: %s", message.c_str());
|
|
break;
|
|
case WebSocketEvent::DATA_RECEIVED:
|
|
ESP_LOGI("App", "Received raw data: %s", message.c_str());
|
|
break;
|
|
case WebSocketEvent::ERROR:
|
|
ESP_LOGE("App", "WebSocket error: %s", message.c_str());
|
|
break;
|
|
}
|
|
}
|
|
|
|
extern "C" void app_main() {
|
|
// 初始化WiFi
|
|
WifiConnectors* wifi = WifiConnectors::getInstance();
|
|
|
|
// 连接WiFi(在实际应用中应该在单独线程中进行)
|
|
ThreadConfig wifi_config;
|
|
wifi_config.name = "WiFi_Connector";
|
|
|
|
auto wifi_thread = ThreadManager::createSingletonThread<WifiConnectors>(
|
|
wifi_config, &WifiConnectors::connectWifi, "Your_SSID", "Your_Password");
|
|
|
|
wifi_thread.join();
|
|
|
|
// 获取WebSocket管理器实例
|
|
WebSocketManager* ws = WebSocketManager::getInstance();
|
|
|
|
// 配置WebSocket
|
|
WebSocketConfig config;
|
|
config.uri = "ws://your-websocket-server.com/ws";
|
|
config.auto_reconnect = true;
|
|
config.reconnect_interval = 5000;
|
|
config.heartbeat_interval = 30000;
|
|
config.max_reconnect_attempts = 10;
|
|
|
|
// 初始化WebSocket管理器
|
|
if (!ws->initialize(config)) {
|
|
ESP_LOGE("App", "Failed to initialize WebSocket manager");
|
|
return;
|
|
}
|
|
|
|
// 设置回调
|
|
ws->setJsonCallback(onJsonData);
|
|
ws->setEventCallback(onWebSocketEvent);
|
|
|
|
// 连接WebSocket
|
|
if (!ws->connect()) {
|
|
ESP_LOGE("App", "Failed to connect WebSocket");
|
|
return;
|
|
}
|
|
|
|
// 等待连接建立
|
|
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
|
|
|
// 发送JSON数据
|
|
cJSON* json = cJSON_CreateObject();
|
|
cJSON_AddStringToObject(json, "type", "greeting");
|
|
cJSON_AddStringToObject(json, "message", "Hello from ESP32!");
|
|
cJSON_AddNumberToObject(json, "timestamp", esp_log_timestamp());
|
|
|
|
ws->sendJson(json);
|
|
|
|
// 保持运行
|
|
while (true) {
|
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
|
|
|
// 可以在这里发送其他数据或处理业务逻辑
|
|
if (ws->isConnected()) {
|
|
cJSON* status = cJSON_CreateObject();
|
|
cJSON_AddStringToObject(status, "type", "status");
|
|
cJSON_AddNumberToObject(status, "free_heap", esp_get_free_heap_size());
|
|
|
|
ws->sendJson(status);
|
|
}
|
|
}
|
|
}
|
|
``` |