| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- /*
- * Lamp Protection Module - v3.2 (Optimized for fast short detection)
- *
- * 改进:
- * - 高电流持续时间阈值降低至1200ms
- * - 增加快速短路条件(峰值≥3500且下降≥2500且当前≤1500)
- * - 稳定期内保持起始电流不变,避免高电流覆盖
- */
- /*********************↓ include ↓************************/
- #define DBG_TAG "LAMP_PROT"
- #define DBG_LVL DBG_INFO
- #include <rtdbg.h>
- #include <rtthread.h>
- #include <rtdevice.h>
- #include <board.h>
- #include <string.h>
- #include "ecode.h"
- #include "ym310_protecl.h"
- /*********************↑ include ↑************************/
- /*********************↓ define ↓************************/
- #define DETECT_MS 500 /* 检测周期,与ADC一致 */
- #define STABLE_MS 500 /* 开启后稳定等待时间(1个周期) */
- #define OPEN_TRIGGER_MS 10000 /* 开路触发时间(10秒) */
- #define RECOVER_STABLE_MS 30000 /* 恢复所需稳定时间(30秒) */
- /* 短路特征阈值 */
- #define RISE_THRESH 1000 /* 上升≥1000(情景A) */
- #define FALL_THRESH_A 2000 /* 情景A下降阈值 */
- #define HIGH_CURRENT 3300 /* 高电流阈值(情景B) */
- #define HIGH_DUR_MS 1000 /* 高电流持续时间(1秒) */
- #define FALL_THRESH_B 2500 /* 情景B下降阈值(略降提高灵敏度) */
- /* 快速短路条件(独立于持续时间) */
- #define FAST_PEAK_THRESH 3500 /* 快速短路峰值阈值 */
- #define FAST_FALL_THRESH 2500 /* 快速短路下降阈值 */
- #define FAST_CURRENT_MAX 1500 /* 快速短路时当前电流最大值 */
- #define OPEN_MAX 100 /* 开路电流最大值 */
- #define NORMAL_MIN 1000 /* 正常电流最小值 */
- #define LAMP_FAULT_NONE 0
- #define LAMP_FAULT_OPEN 0x7A
- #define LAMP_FAULT_SHORT 0x9D
- #define LAMP_PIN GET_PIN(B, 5)
- #define LAMP_ON PIN_HIGH
- #define LAMP_OFF PIN_LOW
- /*********************↑ define ↑************************/
- /*********************↓ 外部变量/函数声明 ↓***********************/
- extern SYS_STATUS sys_sta;
- extern DEV_INFO dev_info;
- extern void save_dev_info(void);
- extern void report_now(void);
- extern void gpio_lamp_ctrl(uint8_t state);
- extern void gpio_hv_ctrl(uint8_t state);
- /*********************↑ 外部变量/函数声明 ↑***********************/
- /*********************↓ 静态变量 ↓***********************/
- static rt_thread_t s_thread = RT_NULL;
- /* 开路检测 */
- static uint32_t s_open_start_ms = 0;
- /* 短路检测 */
- static uint32_t s_start_current = 0; /* 稳定期开始时的起始电流(固定值) */
- static uint32_t s_peak_current = 0; /* 检测到的峰值(稳定期内也记录) */
- static uint32_t s_high_start_ms = 0; /* 高电流开始时间(稳定期内也记录) */
- static uint8_t s_short_triggered = 0; /* 本次开启周期是否已触发短路保护 */
- /* 恢复检测 */
- static uint32_t s_recover_start_ms = 0; /* 稳定正常开始时间 */
- static uint8_t s_last_fault = 0; /* 记录当前保护类型 */
- /* 灯管开启后的稳定延迟 */
- static uint32_t s_stable_until_ms = 0; /* 稳定期结束的时间点 */
- /*********************↑ 静态变量 ↑************************/
- /*********************↓ 内部辅助函数 ↓************************/
- static void reset_all_state(void)
- {
- s_open_start_ms = 0;
- s_start_current = 0;
- s_peak_current = 0;
- s_high_start_ms = 0;
- s_short_triggered = 0;
- s_recover_start_ms = 0;
- s_stable_until_ms = 0;
- }
- /* 触发短路保护(关灯、关机、上报) */
- static void trigger_short(uint32_t current)
- {
- if (s_short_triggered)
- return;
- s_short_triggered = 1;
- sys_sta.lamp_fault = LAMP_FAULT_SHORT;
- s_last_fault = LAMP_FAULT_SHORT;
- LOG_W("[SHORT] Triggered! peak=%d, curr=%d", s_peak_current, current);
- gpio_lamp_ctrl(0);
- gpio_hv_ctrl(0);
- dev_info.power_state = 0;
- save_dev_info();
- Recode_e_code(e_protect, current, "灯管短路保护触发");
- report_now();
- }
- /* 触发开路保护(只上报,不关灯) */
- static void trigger_open(uint32_t current)
- {
- if (sys_sta.lamp_fault == LAMP_FAULT_OPEN)
- return;
- sys_sta.lamp_fault = LAMP_FAULT_OPEN;
- s_last_fault = LAMP_FAULT_OPEN;
- LOG_W("[OPEN] Triggered! current=%d", current);
- Recode_e_code(e_protect, current, "灯管开路故障");
- report_now();
- }
- /* 清除保护(恢复) */
- static void clear_protection(void)
- {
- if (sys_sta.lamp_fault == LAMP_FAULT_OPEN)
- {
- sys_sta.lamp_fault = LAMP_FAULT_NONE;
- LOG_I("[OPEN] Cleared");
- Recode_e_code(e_protect, 0, "灯管开路故障恢复");
- report_now();
- }
- else if (sys_sta.lamp_fault == LAMP_FAULT_SHORT)
- {
- sys_sta.lamp_fault = LAMP_FAULT_NONE;
- LOG_I("[SHORT] Cleared");
- Recode_e_code(e_protect, 0, "灯管短路保护解除");
- report_now();
- }
- s_recover_start_ms = 0;
- s_last_fault = LAMP_FAULT_NONE;
- }
- /*********************↑ 内部辅助函数 ↑***********************/
- /*********************↓ 主线程(极简流程) ↓***********************/
- static void lamp_protect_entry(void *param)
- {
- uint32_t now, current;
- uint8_t lamp_on;
- uint32_t rise, fall;
- rt_thread_mdelay(6*1000);
- char off_lamp_proc = 0;
- ef_get_env_blob("off_lamp_proc", &off_lamp_proc, sizeof(off_lamp_proc), NULL);
-
- if(off_lamp_proc == VALID)
- {
- LOG_W("JUMP lamp_protect_entry");
- }
- while (1)
- {
- while (rt_pin_read(LAMP_PIN) != LAMP_ON)
- {
- rt_thread_mdelay(DETECT_MS);
- }
- reset_all_state();
- s_stable_until_ms = rt_tick_get_millisecond() + STABLE_MS;
- s_start_current = sys_sta.lamp_current;
- s_peak_current = s_start_current;
- LOG_I(" Lamp ON, stable until %lu, start_current=%d",
- s_stable_until_ms, s_start_current);
- while (rt_pin_read(LAMP_PIN) == LAMP_ON)
- {
- now = rt_tick_get_millisecond();
- current = sys_sta.lamp_current;
- if (now < s_stable_until_ms)
- {
- if (current > s_peak_current)
- s_peak_current = current;
- if (current >= HIGH_CURRENT)
- {
- if (s_high_start_ms == 0)
- s_high_start_ms = now;
- }
- else
- {
- s_high_start_ms = 0;
- }
- rt_thread_mdelay(DETECT_MS);
- continue;
- }
- if (sys_sta.lamp_fault != LAMP_FAULT_OPEN)
- {
- if (current <= OPEN_MAX)
- {
- if (s_open_start_ms == 0)
- s_open_start_ms = now;
- if (now - s_open_start_ms >= OPEN_TRIGGER_MS)
- {
- trigger_open(current);
- s_open_start_ms = 0;
- }
- }
- else
- {
- s_open_start_ms = 0;
- }
- }
- if (sys_sta.lamp_fault != LAMP_FAULT_SHORT && !s_short_triggered)
- {
- if (current > s_peak_current)
- s_peak_current = current;
- rise = (s_peak_current > s_start_current) ? (s_peak_current - s_start_current) : 0;
- fall = (s_peak_current > current) ? (s_peak_current - current) : 0;
- if (current >= HIGH_CURRENT)
- {
- if (s_high_start_ms == 0)
- s_high_start_ms = now;
- }
- else
- {
- s_high_start_ms = 0;
- }
- uint8_t short_cond = 0;
- if (s_peak_current >= FAST_PEAK_THRESH && fall >= FAST_FALL_THRESH && current <= FAST_CURRENT_MAX)
- {
- short_cond = 1;
- LOG_D("[SHORT] Fast short: peak=%d, curr=%d, fall=%d", s_peak_current, current, fall);
- }
- else if (rise >= RISE_THRESH && fall >= FALL_THRESH_A)
- {
- short_cond = 1;
- LOG_D("[SHORT] Cond A: rise=%d, fall=%d", rise, fall);
- }
- else if (s_high_start_ms && (now - s_high_start_ms >= HIGH_DUR_MS) && fall >= FALL_THRESH_B)
- {
- short_cond = 1;
- LOG_D("[SHORT] Cond B: highDur=%d, fall=%d", now - s_high_start_ms, fall);
- }
- if (short_cond)
- {
- trigger_short(current);
- break;
- }
- }
- if (sys_sta.lamp_fault != LAMP_FAULT_NONE)
- {
- if (current >= NORMAL_MIN)
- {
- if (s_recover_start_ms == 0)
- {
- s_recover_start_ms = now;
- LOG_D("[RECOV] Start counting, current=%d", current);
- }
- if (now - s_recover_start_ms >= RECOVER_STABLE_MS)
- {
- clear_protection();
- s_recover_start_ms = 0;
- }
- }
- else
- {
- s_recover_start_ms = 0;
- }
- }
- else
- {
- s_recover_start_ms = 0;
- }
- static uint32_t last_log = 0;
- if (now - last_log >= 10000)
- {
- last_log = now;
- LOG_D(" Cur=%d, Fault=%s, Peak=%d, Rise=%d, Fall=%d, HighDur=%d",
- current,
- (sys_sta.lamp_fault == LAMP_FAULT_OPEN) ? "OPEN" : (sys_sta.lamp_fault == LAMP_FAULT_SHORT) ? "SHORT"
- : "NONE",
- s_peak_current, rise, fall,
- s_high_start_ms ? (now - s_high_start_ms) : 0);
- }
- rt_thread_mdelay(DETECT_MS);
- } /* end while(lamp_on) */
- LOG_I(" Lamp OFF, reset all");
- reset_all_state();
- }
- }
- static void lamp_protect_start(void)
- {
- if (s_thread)
- return;
- s_thread = rt_thread_create("lamp_prot", lamp_protect_entry, NULL,
- 1024, 15, 10);
- if (s_thread)
- {
- rt_thread_startup(s_thread);
- LOG_I(" Thread created");
- }
- else
- {
- LOG_E(" Failed to create thread");
- }
- }
- static int auto_init(void)
- {
- lamp_protect_start();
- return 0;
- }
- INIT_APP_EXPORT(auto_init);
- /*********************↓ MSH命令(独立命名) ↓***********************/
- static void cmd_lamp_status(int argc, char **argv)
- {
- (void)argc;
- (void)argv;
- uint32_t now = rt_tick_get_millisecond();
- rt_kprintf("\n========== LAMP PROTECTION STATUS ==========\n");
- rt_kprintf("Lamp switch: %s\n", rt_pin_read(LAMP_PIN) ? "ON" : "OFF");
- rt_kprintf("Current: %d\n", sys_sta.lamp_current);
- rt_kprintf("Fault: %s\n",
- sys_sta.lamp_fault == LAMP_FAULT_OPEN ? "OPEN" : sys_sta.lamp_fault == LAMP_FAULT_SHORT ? "SHORT"
- : "NONE");
- rt_kprintf("Short triggered this session: %s\n", s_short_triggered ? "YES" : "NO");
- rt_kprintf("Peak current: %d\n", s_peak_current);
- if (s_high_start_ms)
- {
- rt_kprintf("High current duration: %d/%d ms\n", now - s_high_start_ms, HIGH_DUR_MS);
- }
- rt_kprintf("Recover stable: %s\n", s_recover_start_ms ? "COUNTING" : "IDLE");
- if (s_recover_start_ms)
- {
- rt_kprintf(" elapsed: %d/%d ms\n", now - s_recover_start_ms, RECOVER_STABLE_MS);
- }
- rt_kprintf("============================================\n");
- }
- MSH_CMD_EXPORT(cmd_lamp_status, Show lamp protection status);
- static void cmd_lamp_clear(int argc, char **argv)
- {
- if (argc < 2)
- {
- rt_kprintf("Usage: lamp_clear [open|short|all]\n");
- return;
- }
- if (strcmp(argv[1], "open") == 0 || strcmp(argv[1], "all") == 0)
- {
- if (sys_sta.lamp_fault == LAMP_FAULT_OPEN)
- {
- sys_sta.lamp_fault = LAMP_FAULT_NONE;
- LOG_I("[CMD] Open protection cleared");
- }
- }
- if (strcmp(argv[1], "short") == 0 || strcmp(argv[1], "all") == 0)
- {
- if (sys_sta.lamp_fault == LAMP_FAULT_SHORT)
- {
- sys_sta.lamp_fault = LAMP_FAULT_NONE;
- s_short_triggered = 0;
- LOG_I("[CMD] Short protection cleared");
- }
- }
- s_recover_start_ms = 0;
- s_last_fault = LAMP_FAULT_NONE;
- rt_kprintf("Lamp protection cleared.\n");
- cmd_lamp_status(0, NULL);
- }
- MSH_CMD_EXPORT(cmd_lamp_clear, Clear lamp protection : lamp_clear[open | short | all]);
- /*********************↑ MSH命令 ↑***********************/
|