feat:增加跌倒时间消抖
fix:修复误触发报警
This commit is contained in:
+70
-32
@@ -56,14 +56,18 @@ bool g_humiDismissed = false;
|
||||
uint8_t g_tempAbnCnt = 0;
|
||||
uint8_t g_humiAbnCnt = 0;
|
||||
uint8_t g_radarTimeoutCnt = 0;
|
||||
uint8_t g_heartAbnCnt = 0; // 心率异常防抖
|
||||
uint8_t g_breathAbnCnt = 0; // 呼吸异常防抖
|
||||
uint32_t g_heartAbnMs = 0; // 心率异常持续计时 (ms)
|
||||
uint32_t g_heartNormalMs = 0; // 心率正常持续计时 (ms)
|
||||
uint32_t g_breathAbnMs = 0; // 呼吸异常持续计时 (ms)
|
||||
uint32_t g_breathNormalMs = 0; // 呼吸正常持续计时 (ms)
|
||||
uint32_t g_fallDetectMs = 0; // 跌倒检测计时 (ms)
|
||||
uint32_t g_fallClearMs = 0; // 跌倒清除计时 (ms)
|
||||
bool g_fallDismissed = false; // 已手动解除, 不重复报警
|
||||
#define ALARM_HYSTERESIS 3 // 连续3次确认才触发
|
||||
#define FALL_DETECT_MS 2000 // 跌倒持续2秒才触发 (房顶安装, 过滤坐下)
|
||||
#define FALL_CLEAR_MS 5000 // 跌倒消失5秒后才清除 (防误消)
|
||||
#define FALL_DETECT_MS 10000 // 跌倒持续10秒才触发 (房顶安装, 过滤坐下)
|
||||
#define FALL_CLEAR_MS 18000 // 跌倒消失18秒后才清除 (防误消)
|
||||
#define VITAL_DETECT_MS 20000 // 心率/呼吸持续异常20秒才触发
|
||||
#define VITAL_CLEAR_MS 15000 // 心率/呼吸持续正常15秒才恢复
|
||||
|
||||
// ============================================================
|
||||
// 时间同步
|
||||
@@ -115,8 +119,10 @@ void handleAlarmCommand(const AlarmCommand& cmd) {
|
||||
g_tempAbnCnt = 0;
|
||||
g_humiAbnCnt = 0;
|
||||
g_radarTimeoutCnt = 0;
|
||||
g_heartAbnCnt = 0;
|
||||
g_breathAbnCnt = 0;
|
||||
g_heartAbnMs = 0;
|
||||
g_heartNormalMs = 0;
|
||||
g_breathAbnMs = 0;
|
||||
g_breathNormalMs = 0;
|
||||
g_fallDetectMs = 0;
|
||||
g_fallClearMs = 0;
|
||||
g_fallDismissed = false;
|
||||
@@ -335,55 +341,85 @@ void checkLocalAlarms(const RadarRawData& radar) {
|
||||
g_fallClearMs = 0; // 仍在跌倒, 重置消失计时
|
||||
}
|
||||
|
||||
// ─── ★★★★★ 人身安全: 心率异常 (仅卧室+ABD1, 防抖3次, 30s) ───
|
||||
// ─── ★★★★★ 人身安全: 心率异常 (仅卧室+ABD1, 持续异常20s触发/正常15s恢复, 30s) ───
|
||||
#if RADAR_TYPE != RADAR_TYPE_AFD1
|
||||
if (enVital && millis() > 30000 && humanPresent && radar.vitalValid && radar.heartRate > 0) {
|
||||
bool heartAbn = (radar.heartRate < HEART_RATE_MIN || radar.heartRate > HEART_RATE_MAX);
|
||||
if (heartAbn) {
|
||||
if (!g_heartDismissed && ++g_heartAbnCnt >= ALARM_HYSTERESIS && !g_localHeartAbnActive) {
|
||||
g_localHeartAbnActive = true;
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "心率异常: %d bpm", radar.heartRate);
|
||||
g_alarm.triggerLocal(AlarmManager::ALARM_HEART_ABNORMAL, buf);
|
||||
// 持续异常: 累积时长, 满 VITAL_DETECT_MS 触发
|
||||
if (!g_heartDismissed && !g_localHeartAbnActive) {
|
||||
if (g_heartAbnMs == 0) {
|
||||
g_heartAbnMs = millis();
|
||||
} else if (millis() - g_heartAbnMs >= VITAL_DETECT_MS) {
|
||||
g_localHeartAbnActive = true;
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "心率异常: %d bpm", radar.heartRate);
|
||||
g_alarm.triggerLocal(AlarmManager::ALARM_HEART_ABNORMAL, buf);
|
||||
}
|
||||
}
|
||||
g_heartNormalMs = 0; // 仍异常, 重置正常计时
|
||||
} else {
|
||||
g_heartAbnCnt = 0;
|
||||
g_heartDismissed = false;
|
||||
if (g_localHeartAbnActive) {
|
||||
g_localHeartAbnActive = false;
|
||||
g_alarm.clearLocal(AlarmManager::ALARM_HEART_ABNORMAL);
|
||||
// 持续正常: 累积时长, 满 VITAL_CLEAR_MS 清除 + 重新武装
|
||||
g_heartAbnMs = 0; // 正常了, 重置异常计时
|
||||
if (g_heartNormalMs == 0) {
|
||||
g_heartNormalMs = millis();
|
||||
}
|
||||
if (millis() - g_heartNormalMs >= VITAL_CLEAR_MS) {
|
||||
if (g_localHeartAbnActive) {
|
||||
g_localHeartAbnActive = false;
|
||||
g_alarm.clearLocal(AlarmManager::ALARM_HEART_ABNORMAL);
|
||||
}
|
||||
if (g_heartDismissed) {
|
||||
g_heartDismissed = false; // 持续正常后重新武装
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!humanPresent && g_localHeartAbnActive) {
|
||||
g_localHeartAbnActive = false;
|
||||
g_heartAbnCnt = 0;
|
||||
g_heartAbnMs = 0;
|
||||
g_heartNormalMs = 0;
|
||||
g_heartDismissed = false;
|
||||
g_alarm.clearLocal(AlarmManager::ALARM_HEART_ABNORMAL);
|
||||
}
|
||||
#endif // RADAR_TYPE != AFD1
|
||||
|
||||
// ─── ★★★★★ 人身安全: 呼吸异常 (仅卧室+ABD1, 防抖3次, 30秒后生效) ───
|
||||
// ─── ★★★★★ 人身安全: 呼吸异常 (仅卧室+ABD1, 持续异常20s触发/正常15s恢复, 30秒后生效) ───
|
||||
#if RADAR_TYPE != RADAR_TYPE_AFD1
|
||||
if (enVital && millis() > 30000 && humanPresent && radar.vitalValid && radar.breathRate > 0) {
|
||||
bool breathAbn = (radar.breathRate < BREATH_RATE_MIN || radar.breathRate > BREATH_RATE_MAX);
|
||||
if (breathAbn) {
|
||||
if (!g_breathDismissed && ++g_breathAbnCnt >= ALARM_HYSTERESIS && !g_localBreathAbnActive) {
|
||||
g_localBreathAbnActive = true;
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "呼吸异常: %d 次/分", radar.breathRate);
|
||||
g_alarm.triggerLocal(AlarmManager::ALARM_BREATH_ABNORMAL, buf);
|
||||
// 持续异常: 累积时长, 满 VITAL_DETECT_MS 触发
|
||||
if (!g_breathDismissed && !g_localBreathAbnActive) {
|
||||
if (g_breathAbnMs == 0) {
|
||||
g_breathAbnMs = millis();
|
||||
} else if (millis() - g_breathAbnMs >= VITAL_DETECT_MS) {
|
||||
g_localBreathAbnActive = true;
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "呼吸异常: %d 次/分", radar.breathRate);
|
||||
g_alarm.triggerLocal(AlarmManager::ALARM_BREATH_ABNORMAL, buf);
|
||||
}
|
||||
}
|
||||
g_breathNormalMs = 0; // 仍异常, 重置正常计时
|
||||
} else {
|
||||
g_breathAbnCnt = 0;
|
||||
g_breathDismissed = false;
|
||||
if (g_localBreathAbnActive) {
|
||||
g_localBreathAbnActive = false;
|
||||
g_alarm.clearLocal(AlarmManager::ALARM_BREATH_ABNORMAL);
|
||||
// 持续正常: 累积时长, 满 VITAL_CLEAR_MS 清除 + 重新武装
|
||||
g_breathAbnMs = 0; // 正常了, 重置异常计时
|
||||
if (g_breathNormalMs == 0) {
|
||||
g_breathNormalMs = millis();
|
||||
}
|
||||
if (millis() - g_breathNormalMs >= VITAL_CLEAR_MS) {
|
||||
if (g_localBreathAbnActive) {
|
||||
g_localBreathAbnActive = false;
|
||||
g_alarm.clearLocal(AlarmManager::ALARM_BREATH_ABNORMAL);
|
||||
}
|
||||
if (g_breathDismissed) {
|
||||
g_breathDismissed = false; // 持续正常后重新武装
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!humanPresent && g_localBreathAbnActive) {
|
||||
g_localBreathAbnActive = false;
|
||||
g_breathAbnCnt = 0;
|
||||
g_breathAbnMs = 0;
|
||||
g_breathNormalMs = 0;
|
||||
g_breathDismissed = false;
|
||||
g_alarm.clearLocal(AlarmManager::ALARM_BREATH_ABNORMAL);
|
||||
}
|
||||
@@ -551,8 +587,10 @@ void setup() {
|
||||
g_localDhtFaultActive = false;
|
||||
g_tempAbnCnt = 0;
|
||||
g_humiAbnCnt = 0;
|
||||
g_heartAbnCnt = 0;
|
||||
g_breathAbnCnt = 0;
|
||||
g_heartAbnMs = 0;
|
||||
g_heartNormalMs = 0;
|
||||
g_breathAbnMs = 0;
|
||||
g_breathNormalMs = 0;
|
||||
g_radarTimeoutCnt = 0;
|
||||
g_fallClearMs = 0;
|
||||
g_fallDismissed = true; // 抑制重复报警, 等跌倒信号消了再恢复
|
||||
|
||||
Reference in New Issue
Block a user