核心上限

This commit is contained in:
2025-09-20 16:57:16 +08:00
parent 71e8bd7532
commit 991c673630
7 changed files with 1456 additions and 47 deletions

281
core.h Normal file
View File

@@ -0,0 +1,281 @@
#ifndef CORE_H
#define CORE_H
#include <Arduino.h>
#include <Preferences.h>
// 包含所有必要的模块头文件
#include "DHT11control.h"
#include "RTC_Module.h"
#include "LunarCalendarAndHolidayJudge.h"
#include "audio_model_esp32.h"
#include "microphone.h"
// 核心判断结果枚举
typedef enum {
JUDGE_NO_ACTION = 0, // 无需操作
JUDGE_TURN_ON_COOLING = 1, // 开启制冷
JUDGE_TURN_ON_HEATING = 2, // 开启制暖
JUDGE_TURN_OFF_AC = 3, // 关闭空调
JUDGE_ADJUST_TEMP = 4, // 除湿
JUDGE_ERROR = -1 // 错误状态
} JudgeResult;
// 环境数据结构
typedef struct {
float temperature; // 当前温度
float humidity; // 当前湿度
int year; // 当前年份
int month; // 当前月份
int day; // 当前日期
int hour; // 当前小时
int minute; // 当前分钟
int second; // 当前秒数
bool is_holiday; // 是否为节假日
AudioClassType audio_class; // AI音频识别结果
float audio_confidence; // 音频识别置信度
bool data_valid; // 数据是否有效
} EnvironmentData;
// 全局麦克风对象
static INMP441Microphone microphone(14, 15, 32, 16000, 1024);
// 初始化核心模块
bool initializeCore() {
Serial.println("正在初始化核心模块...");
// 初始化音频模型
if (audio_model_init() != 0) {
Serial.println("音频模型初始化失败!");
return false;
}
// 初始化麦克风
if (!microphone.begin()) {
Serial.println("麦克风初始化失败!");
return false;
}
Serial.println("核心模块初始化完成");
return true;
}
// 获取环境数据
bool getEnvironmentData(EnvironmentData* env_data) {
if (env_data == NULL) {
return false;
}
// 初始化数据结构
memset(env_data, 0, sizeof(EnvironmentData));
env_data->data_valid = false;
// 获取温湿度数据
float* temp_humidity = getTempAndHumidity();
if (temp_humidity[0] == -999 || temp_humidity[1] == -999) {
Serial.println("温湿度传感器读取失败!");
return false;
}
env_data->temperature = temp_humidity[0];
env_data->humidity = temp_humidity[1];
// 获取RTC时间
RtcDateTime current_time = getRTCTime();
if (!current_time.IsValid()) {
Serial.println("RTC时间读取失败!");
return false;
}
env_data->year = current_time.Year();
env_data->month = current_time.Month();
env_data->day = current_time.Day();
env_data->hour = current_time.Hour();
env_data->minute = current_time.Minute();
env_data->second = current_time.Second();
// 判断是否为节假日
env_data->is_holiday = LunarCalendar::isHoliday(env_data->year, env_data->month, env_data->day);
env_data->data_valid = true;
return true;
}
// 执行AI音频识别
bool performAudioRecognition(EnvironmentData* env_data) {
if (env_data == NULL) {
return false;
}
Serial.println("开始音频识别...");
// 分配音频缓冲区 (2秒 * 16000Hz = 32000 samples)
const size_t audio_buffer_size = 32000;
int16_t* audio_buffer = (int16_t*)malloc(audio_buffer_size * sizeof(int16_t));
if (audio_buffer == NULL) {
Serial.println("音频缓冲区分配失败!");
return false;
}
// 采集2秒音频数据
size_t samples_read = 0;
unsigned long start_time = millis();
while (samples_read < audio_buffer_size && (millis() - start_time) < 2100) {
size_t chunk_size = microphone.readAudioData(
audio_buffer + samples_read,
min(1024, (int)(audio_buffer_size - samples_read))
);
samples_read += chunk_size;
delay(1); // 短暂延时避免过度占用CPU
}
Serial.printf("采集到 %d 个音频样本\n", samples_read);
// 执行AI预测
AudioPredictionResult prediction_result;
int predict_status = audio_model_predict(audio_buffer, samples_read, &prediction_result);
// 释放音频缓冲区
free(audio_buffer);
if (predict_status != 0 || !prediction_result.is_valid) {
Serial.println("音频预测失败!");
env_data->audio_class = AUDIO_CLASS_PERSON_ABSENT;
env_data->audio_confidence = 0.0f;
return false;
}
env_data->audio_class = prediction_result.predicted_class;
env_data->audio_confidence = prediction_result.confidence;
Serial.printf("音频识别结果: %s (置信度: %.2f)\n",
get_class_name_cn(env_data->audio_class),
env_data->audio_confidence);
return true;
}
// 核心判断函数
int judge() {
Serial.println("=== 开始核心判断流程 ===");
// 获取环境数据
EnvironmentData env_data;
if (!getEnvironmentData(&env_data)) {
Serial.println("环境数据获取失败!");
return JUDGE_ERROR;
}
// 执行音频识别
if (!performAudioRecognition(&env_data)) {
Serial.println("音频识别失败,使用默认值");
// 继续执行,但音频数据可能不准确
}
// 打印当前环境状态
Serial.println("=== 当前环境状态 ===");
Serial.printf("时间: %04d-%02d-%02d %02d:%02d:%02d\n",
env_data.year, env_data.month, env_data.day,
env_data.hour, env_data.minute, env_data.second);
Serial.printf("温度: %.1f°C, 湿度: %.1f%%\n", env_data.temperature, env_data.humidity);
Serial.printf("节假日: %s\n", env_data.is_holiday ? "" : "");
Serial.printf("音频识别: %s (置信度: %.2f)\n",
get_class_name_cn(env_data.audio_class), env_data.audio_confidence);
// 核心判断逻辑
JudgeResult result = JUDGE_NO_ACTION;
// 获取用户设置的温度范围 (从Preferences读取)
Preferences prefs;
prefs.begin("DACSC", true); // 只读模式
float min_temp = prefs.getFloat("min_temp", 5.0); // 默认最低温度22°C
float max_temp = prefs.getFloat("max_temp", 28.0); // 默认最高温度26°C
prefs.end();
// 判断逻辑:基于节假日、音频识别、时间、温度和湿度的智能控制
// 规则1节假日规则优先级最高
if (env_data.is_holiday) {
result = JUDGE_NO_ACTION;
Serial.println("判断结果: 节假日,系统不进行任何操作");
}
// 规则2-9非节假日规则
else {
// 检查是否有人在室内(包括"室内有人"和"有人进门"
bool person_present = (env_data.audio_class == AUDIO_CLASS_PERSON_PRESENT ||
env_data.audio_class == AUDIO_CLASS_KEY_JINGLING) &&
env_data.audio_confidence > 0.6;
// 检查是否无人在室内(包括"室内无人"和"有人出门"
bool person_absent = (env_data.audio_class == AUDIO_CLASS_PERSON_ABSENT ||
env_data.audio_class == AUDIO_CLASS_DOOR_CLOSING) &&
env_data.audio_confidence > 0.6;
// 检查是否为白天时间8:00-22:00
bool is_daytime = (env_data.hour >= 8 && env_data.hour <= 22);
if (person_absent) {
// 规则10无人时关闭空调优先级高
result = JUDGE_TURN_OFF_AC;
Serial.println("判断结果: 检测到无人或有人出门,关闭空调以节能");
}
else if (person_present) {
if (is_daytime) {
// 白天有人的规则规则2-5
if (env_data.temperature < min_temp) {
result = JUDGE_TURN_ON_HEATING;
Serial.println("判断结果: 白天有人且温度过低,开启制热");
}
else if (env_data.temperature > max_temp) {
result = JUDGE_TURN_ON_COOLING;
Serial.println("判断结果: 白天有人且温度过高,开启制冷");
}
else if (env_data.humidity > 70.0) {
result = JUDGE_ADJUST_TEMP;
Serial.println("判断结果: 白天有人、温度舒适但湿度过高,开启除湿");
}
else {
result = JUDGE_NO_ACTION;
Serial.println("判断结果: 白天有人、温度舒适且湿度正常,无需操作");
}
}
else {
// 晚上有人的规则规则6-9
if (env_data.temperature < min_temp) {
result = JUDGE_TURN_ON_HEATING;
Serial.println("判断结果: 晚上有人但温度过低,开启制热");
}
else if (env_data.temperature > max_temp) {
result = JUDGE_TURN_ON_COOLING;
Serial.println("判断结果: 晚上有人但温度过高,开启制冷");
}
else if (env_data.humidity > 70.0) {
result = JUDGE_ADJUST_TEMP;
Serial.println("判断结果: 晚上有人、温度舒适但湿度过高,开启除湿");
}
else {
result = JUDGE_NO_ACTION;
Serial.println("判断结果: 晚上有人、温度舒适且湿度正常,无需操作以节能");
}
}
}
else {
// 音频识别不确定或置信度不够时的默认处理
result = JUDGE_NO_ACTION;
Serial.println("判断结果: 音频识别不确定,保持当前状态");
}
}
Serial.printf("=== 判断完成,返回值: %d ===\n", result);
return result;
}
// 清理核心模块资源
void cleanupCore() {
Serial.println("清理核心模块资源...");
microphone.end();
audio_model_cleanup();
Serial.println("核心模块资源清理完成");
}
#endif // CORE_H