HJ212 CRC校验错误让数据传不上去怎么排查

「数采仪屏幕上写着已连接,平台那边一条数据都没收到,抓包一看全是校验不过。」这是华东一家做运维服务的客户在电话里说的原话。先把结论放在前面:十次 HJ212 CRC校验错误,八九次不是网络断,而是报文内容在某一环被改过、CRC 却没跟着重算。常见的改动点有三类——中间转发网关重新拼了包、串口透传设备吃掉了首尾字节、或者数采仪在浓度小数位、因子数量变化后没有重算校验值。先别急着换设备、也别急着找运营商,先把报文原文捞出来,离线重算一遍,比什么都快。

先讲清 HJ212 的校验是怎么算的

HJ212 报文的结构是 ## + 数据段 + && + 4 位十六进制校验值 + \r\n。数据段由若干「参数名=参数值」用分号连接,前面是 QN(时间戳,YYMMDDhhmmss)、ST、CN、PW、MN、Flag、PN 这些公共字段,后面才是 CP 里的具体污染物数据。

校验算法是 CRC16,多项式多项式取反为 0xA001,初值 0xFFFF,结果转成 4 位大写十六进制。关键中的关键是覆盖范围:从 ## 中的第一个 # 开始,一直到 && 前面的最后一个字符为止,包括 ## 本身,不包括 && 和后面的 4 位校验值,也不包括行尾的 \r\n。范围多算一个字符、少算一个字符,算出来的值都是错的。这一点决定了后面所有排查动作的顺序。

  • 覆盖起点:数据包第一个 # 字符。
  • 覆盖终点:&& 前面的最后一个字符(含 & 之前的全部内容)。
  • 不参与计算:&&、4 位校验值、\r\n。
  • 常见命令码:2051 实时数据、2061 分钟数据补发、3020 分钟数据、1014 报警,排查时看 CN 字段就能判断是哪类业务的报文出了问题。

按四层拆:错误到底出在哪一层

协议层:算法与范围

  • 覆盖范围算错,把 ## 漏掉或把 && 算进去,是最常见的一种。
  • 十六进制大小写混用、报文里混入空格或全角字符,校验值位数不对。
  • QN 时间戳位数不对(少一位或多一位),导致整个数据段长度变了。
  • 浓度值小数位从两位变三位,数据段变长,CRC 却没重算。
  • 部分设备在 && 后面还跟了 4 位长度字段,接收侧按国标理解就必然对不上。

网络层:拼包与透传

  • TCP 粘包、半包,接收侧没按 ## 到 \r\n 的边界切分,把两条报文拼成一条,CRC 自然错。
  • 串口转 TCP 的透传模块加了额外换行或去掉了首字节。
  • 心跳报文和数据报文交错发送,平台按顺序解析时错位。

设备层:组包逻辑

  • 数采仪固件在因子数量变化(比如新增一个因子)后,数据段重组但 CRC 沿用旧值。
  • PN、CP 字段为空时多留了一个分号,多出的分隔符进了计算范围。
  • 补发历史数据(CN=3020)时,时间字段格式与实时数据不一致。

平台层:接收侧规则

  • 部分平台对 \r\n 的处理和国标略有出入,要求严格不带行尾。
  • 平台对 4 位校验值的大小写做了强制判断。
  • 平台侧按固定长度截取报文,遇到变长数据段就误判。

排查顺序:为什么必须先算、再查、最后改

顺序本身就是知识。第一步永远是把报文原文拿出来离线重算 CRC,因为这一步成本最低、结论最硬:重算对得上,问题在平台或链路;重算对不上,问题在设备或中间转发。反过来先查网络,可能折腾半天,结果报文本身就有问题。

  • 第一步,抓包取原文。在数采仪出口或平台入口抓一段完整报文,确认首尾 ## 与 \r\n 齐全。判断标准:报文完整、无截断、无拼接。动作:把原文存成文本,去掉 && 之后的部分。
  • 第二步,离线重算。用同一套 CRC16 参数(0xA001、初值 0xFFFF)重算,与报文携带的 4 位值比对。判断标准:一致说明设备组包正确。动作:不一致则回到设备侧看数据段是否被改。
  • 第三步,看数据段长度。比对报文中字段个数、小数点位数与配置是否一致。判断标准:字段数、长度与配置对得上。动作:对不上就检查固件版本与因子配置。
  • 第四步,查中间环节。是否经过转发网关、透传模块、协议转换器。判断标准:旁路中间设备直连后报文恢复正确。动作:确认后调整透传参数或改用直连。
  • 第五步,核对平台侧规则。判断标准:同一报文在其他平台校验通过。动作:与平台方确认覆盖范围与大小写要求。

每一步的判断标准与处置动作

  • 现象:数采仪显示已连接,平台无数据。判断:TCP 建连成功只代表链路通,与协议校验无关。动作:抓包看报文是否完整。
  • 现象:报文完整但校验值不符。判断:数据段被改动或覆盖范围算错。动作:逐字段比对,重算 CRC。
  • 现象:单条正确、连续发送后开始出错。判断:粘包或拼包错位。动作:检查接收侧切分逻辑与发送间隔。
  • 现象:新增因子后集中报错。判断:数据段变长但 CRC 未重算。动作:升级或核对固件组包逻辑。
  • 现象:同一报文换个平台就通过。判断:平台侧接收规则差异。动作:与平台确认行尾与大小写处理。

三个最容易踩的坑

第一个坑:把「连接成功」当成「数据通了」。TCP 三次握手和 CRC 校验是两件事,屏幕上那个绿色图标只说明端口开着,不代表任何一个字节符合规范。看到连接正常就排网络,方向就偏了。

第二个坑:用在线工具算 CRC 时把 && 和行尾一起粘进去了。复制报文时顺手全选,把 \r\n 也带进去,算出来的值当然对不上,于是误判成设备故障,白白换件。

第三个坑:改了浓度小数位或因子数量,以为只是显示问题。数据段长度变了,CRC 必须跟着重算。有些设备在修改配置后不会自动重算,表现为「配置改完,数据立刻传不上去」,很多人第一反应是网络断了,实际上是报文本身校验就错了。

FAQ

我这台数采仪以前一直好好的,什么都没动,怎么突然就报 CRC 错了?

先看是不是上游环节动了:平台侧升级了接收规则、中间加了一台转发设备、或者运营商链路换了出口,都会让原本能过的报文过不去。设备侧什么都没动,不代表链路上什么都没动。

平台说 CRC 错误,是不是平台的问题?

不能一概而论。把报文原文拿出来离线重算,对得上就是平台侧的问题,对不上就是发送侧的问题。这一步不做,跟平台扯不清。

我抓包看报文内容和平台要求的一模一样,为什么还是报错?

「看起来一样」和「字节一样」是两回事。重点看三处:## 是否被计入、&& 后面有没有多余字符、行尾有没有隐藏的 \r\n。这三处肉眼很难看出来,建议用十六进制视图看。

新增了一个监测因子,数据就传不上去了,跟这个有关系吗?

有。因子增加意味着数据段变长,如果设备在组包时没有按新长度重算校验值,整条报文都会校验失败。可以把新增因子临时去掉再发一次,如果恢复了,方向就确认了。