当前位置: 首页 > news >正文

《储能系统中的故障定位》

从“故障现象”到“可验证证据”的工程化闭环(含故障录波),线上/现场的故障排查,最怕两件事:只看现象、却没有证据链;只采集日志、却无法对齐“故障发生时刻”的关键波形。结合你们工程代码里已有的“故障信息采集 + 故障/日志/录波触发 + 波形原始帧落盘(USB)+ Web 导出”,下面给出一套可直接落地的故障定位思路:让排查从“猜”变成“证”。

1. 先定义:这次故障你要定位的“对象”是什么?

建议在处理告警/故障时,先把对象分清楚,后续采集与排查才能对齐:

通信类:CAN/BMS/电表/主从 MQTT 通道是否异常(会导致录波数据拿不到)
功能类:充电/放电控制逻辑是否进入保护/停止(策略触发)
设备类:BMS 单体或系统级故障码是否成立(故障信息)
证据类:能不能拿到“故障发生时刻”的故障录波/原始帧(可复盘波形)

在代码里,“对象”的证据分别来自不同模块:例如 BMS 侧故障信息与录波触发/写盘;Web 侧对部分故障日志(如 meterfaultlog)导出。

2. 故障信息怎么拿:先拿“可复用的故障码/状态快照”

在 BMS 侧采集到的原始数据最终会映射为“可上送的故障信息”。例如 `can_infy_batt.c` 中,把运行侧聚合的故障码字段映射到上层 blob:


pBlobIfyBMS->unioBattFault = s_infy_BattRunData[n].unioBattFaultCode;
...
pBlobIfyBMS->emBattSysState = s_infy_BattRunData[n].emBattSysState ;
pBlobIfyBMS->emBattChgState = s_infy_BattRunData[n].emBattChgState ;
```

这一步的意义是:不管录波最终是否成功,至少先有“故障是什么”的快照。故障定位时你要做的第一件事,通常是把“故障码/系统状态/充电状态”与“控制策略触发点”对齐。

3. 故障录波怎么拿:代码里已经实现了“录波触发 + 逐条收取 + 原始帧写盘 + 确认”

工程中,BMS 录波属于“受控的采集流程”,核心链路在 `can_infy_batt.c` 里非常清晰。

3.1 先拿到“总记录数”:决定是否触发故障/日志/波形采集

`Parse_S2C_RecNum()` 会读取总记录数,包括故障记录、日志记录、波形记录:


if(pFrmReply->byData[1] == 0x00) {
s_infy_BattRunData[nBMSGrpMapIdx].nFaultRecNum = CAN_StringToUShort(pFrmReply->byData + 2);
s_infy_BattRunData[nBMSGrpMapIdx].nLogRecNum = CAN_StringToUShort(pFrmReply->byData + 4);
s_infy_BattRunData[nBMSGrpMapIdx].nWaveRecNum = CAN_StringToUShort(pFrmReply->byData + 6);
}
...
TRACEX("Idx=[%d] Total nFaultRecNum=[%d] nLogRecNum=[%d] nWaveRecNum=[%d] nDODRecNum=[%d]\n", ...);
```

工程化排查关键点:
如果你现场想要录波,但发现系统没有触发录波,先检查 `nWaveRecNum` 是否满足触发条件。

3.2 状态机决定“触发哪类录波”:故障 > 日志 > 波形优先级

`YFY_StateMachine4BMSMsg()` 在 `STAT_ON_START` 里选择触发类型(优先故障记录,其次日志记录,最后波形记录),并且用 `MAX_RECSAVE_NUM` 做阈值判断:


case STAT_ON_START:
if(s_infy_BattRunData[nBMSIdx].nFaultRecNum > MAX_RECSAVE_NUM) {
pSTBatt_Rough->stuCanSave.emTrigMsgTp[nBMSIdx] = TP_TRIG_FAULT;
} else if(s_infy_BattRunData[nBMSIdx].nLogRecNum > MAX_RECSAVE_NUM) {
pSTBatt_Rough->stuCanSave.emTrigMsgTp[nBMSIdx] = TP_TRIG_LOG;
} else if(s_infy_BattRunData[nBMSIdx].nWaveRecNum > MAX_RECSAVE_NUM) {
pSTBatt_Rough->stuCanSave.emTrigMsgTp[nBMSIdx] = TP_TRIG_WAVE;
}
break;
```

这直接给出一个非常实用的排查判断法:
“录波没抓到”**通常不是“波形不存在”,而是状态机没有进入 `TP_TRIG_WAVE`(阈值/计数/通讯导致读不到记录数)。

3.3 逐条收取 wave,并写入 USB 原始帧,再发送确认

当触发类型为 `TP_TRIG_WAVE`,状态机会不断发送 `CAN_RD_CMD_C2S_WAVE_REC`,直到 `nWaveRecNum` 归零/进入挂起状态。

收包后,`Tigger_IfyBmsFrameWrite2USB()` 对 `_CAN_R_CMD_S2C_WAVEREC` 做了非常明确的动作:**把原始帧写到 USB,并发确认**:


case TP_TRIG_WAVE:
if(pFrmReply->emMsgType == _CAN_R_CMD_S2C_WAVEREC) {
Pending_WriteMsg2USB(pSTBatt_Rough, nBMSGrpMapIdx, pFrmReply->byRawData, 1);
YFY_Send_C2S_Status(pSTBatt_Rough, nBMSGrpMapIdx, CAN_CFM_CMD_C2S_WAVE_REC);
}
break;
```

这也是“故障定位可复盘”的关键设计:
波形/故障录波并不依赖解析细节,**用原始帧保真**,后续再用离线工具解析波形内容。
如果写盘成功但无法解析,问题在离线解析/文件格式;如果写盘都没有,问题多半在录波收取链路或通讯。

3.4 发送波形读取命令(Wave Record 0x0b21yyxx)

波形读取指令打包也在同文件中:


YFY_CAN_StuffMsgID(0x0B, 0x21, frm.byBMSGrpAddr, frm.byEMSAddr, CAN_DATA_AREA_LEN, pbySendBuf);
frm.byData[0] = 0xC0;
...
memcpy(pbySendBuf + 5, frm.byData, CAN_DATA_AREA_LEN);
```

这段能帮助你做“命令是否发出去”的验证(例如抓 CAN 日志对齐 `0x0B/0x21` 对应的读取请求)。

4. 故障录波之外:日志类证据也要纳入定位(比如 AFE 异常时落盘)

代码中有对 AFE 异常状态的落盘行为(示例:`/data/AfeSrStatus.csv`)。当 `bAfeWorkModeAbnormal` 且状态变化时,会把数据写入文件:


fp = fopen("/data/AfeSrStatus.csv", "a");
...
TimeToString(_NOW_, TIME_CHN_FMT, szTime, sizeof(szTime));
...
fputs(strLine, fp);
```

故障定位建议: 波形是“事发时刻的证据”,AFE 落盘是“异常演化的证据”。
当你发现波形抓不到时,至少可以用这种“关键状态变化落盘”去补齐定位链条。

5. Web 侧怎么“导出证据包”:让故障录波可交付、可复现

工程里提供了故障/日志相关的导出接口。例如 `api_query_chgrecord.c` 里,对电表故障日志 `meterfaultlog` 做了打包导出:


if(access("/data/meterfaultlog.0", F_OK) != 0) {
Make_Web_OutPut(104, "Can NOT find MeterLog file for export!", NULL, NULL);
return FALSE;
}
system("tar cvf /var/volatile/Meter_Log.tar /data/meter*");
...
UploadBinFile_2Client(METERLOG_EXPORT_LOCALFILE, szRemoteName)
```

这对故障定位的意义是: 你不用只靠“现场口述”,而是能把“可落盘证据包”交给分析侧进一步定位根因。

6. 一条可直接照做的排查闭环

把上面代码证据链拼成“定位闭环”,建议按下面顺序执行:

1. 先抓“故障对象快照”:从 blob/状态字段确认系统状态、充放电状态、故障码是否成立(例如 `unioBattFault` / `emBattSysState` / `emBattChgState`)。
2. 再确认“录波是否被触发”:查看 `nFaultRecNum/nLogRecNum/nWaveRecNum` 是否满足 `MAX_RECSAVE_NUM` 的触发优先级。
3. 检查“波形收取是否成功”:看 `_CAN_R_CMD_S2C_WAVEREC` 分支是否执行了。 `Pending_WriteMsg2USB` 并发送了 `CAN_CFM_CMD_C2S_WAVE_REC`。
4. 如果录波写盘成功但分析失败:回到原始帧文件格式/离线解析工具,而不是直接怀疑采集链路。
5. 若录波/日志缺失:优先排查通讯链路(能否读取记录数、能否收到 waverec 回包)。
6. 最后导出证据包(Web export 或打包上送),用于跨团队复盘。

7. 典型故障场景怎么套用

现场有故障现象,但系统没有录波文件。
优先检查:`nWaveRecNum` 是否触发 `TP_TRIG_WAVE`(阈值/计数)以及 CAN 录波回包是否收到(`_CAN_R_CMD_S2C_WAVEREC` 分支是否走到写 USB + confirm)。

有故障码,但波形与故障码对不上。
先确认录波原始帧时间是否与故障发生时刻一致(在解析阶段做对齐),再考虑:录波数据是原始帧保真,定位应从“解析对齐”回到“证据解释层”。

电表相关故障反复出现,但定位总是停留在告警表
用 Web export 把 `meterfaultlog` 导出来,再用解析工具结合曲线对齐,减少“只看告警、不看过程”的盲区。

http://www.jsqmd.com/news/535201/

相关文章:

  • 精确率 vs 召回率:为什么你的模型总是顾此失彼?
  • 实战qt项目开发:基于快马平台构建工业数据监控可视化看板
  • 信管毕设本科生课题怎么做
  • 嵌入式HTTP服务器:MCU上实现轻量Web服务
  • 利用Qwen3-ASR-0.6B构建企业级语音助手:SpringBoot集成实战
  • 5G波束管理实战解析:从原理到应用场景
  • 深度解析:如何通过Python SDK高效获取百度指数与搜索数据
  • StructBERT中文相似度模型实战案例:中文在线教育题库去重与难度映射系统
  • 锅炉水温串级调节系统西门子S7-200 PLC和用组态王6.55联机和仿真程序全套包
  • 清音听真Qwen3-ASR-1.7B保姆级教程:Windows WSL2环境下GPU加速部署
  • foobox-cn:重塑foobar2000用户体验的DUI皮肤引擎解决方案
  • FPGA内部模块详解之四 算力引擎——数字信号处理单元(DSP Slice)深度解析
  • rk3588 + MCP2515 驱动修改分析:原生 2 路 + SPI 1 路方案
  • 数字后端设计:Innovus Powerplan实操指南
  • 计算机毕业设计springboot基于的医院住院管理系统 SpringBoot框架下医疗机构住院部数字化管理平台的设计与实现 基于Java的医院病房管理与患者住院服务系统开发
  • Windows 11 + Python 3.9 保姆级教程:手把手搞定奥比中光Gemini 2L深度相机SDK配置
  • H.265编码技术解析:从原理到视频监控共享平台的实战部署
  • STM32标准库开发:从寄存器到固件库封装
  • STM32CubeMX+HAL库驱动OLED全流程指南(附I2C引脚重映射技巧)
  • [Windows Defender启动故障]的[3]维解决方案:从[基础修复]到[深度重构]的实战指南
  • 什么是词元?AI的Token终于有了标准中文名!【2026年3月最新版】
  • 毕设程序java基于vue的健身食谱系统的设计与实现 基于SpringBoot与Vue框架的健康膳食管理平台的设计与开发 面向健身人群的智能营养配餐系统的设计与实现
  • SecGPT-14B开源可部署:无需申请License的国产网络安全大模型本地化方案
  • 有没有大佬能帮忙用ER图画一画
  • 避坑指南:Altium Designer 2024安装后激活失败的常见原因及解决方案
  • 基于STM32F103C8的循迹避障小车V6设计及Proteus仿真(含C语言Keil工程与仿...
  • Wan2.1-umt5构建行业搜索引擎:基于语义理解的精准信息检索
  • Anaconda+Pycharm环境下Pytorch CPU版安装避坑指南(附虚拟环境配置技巧)
  • 禅道测试用例 RAG 系统 1:从 SQL 到智能问答,手把手搭建测试专家助手
  • 2026年目前热门的棕刚玉品牌推荐,棕刚玉企业诚信金钢砂专注产品质量 - 品牌推荐师