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