

在前几篇中,我们讨论了传输协议、边缘联动和时序存储。但有一个底层问题始终贯穿其中:传感器节点如何确信自己“采到的是对的”、“发出去的是真的”?
在智慧档案馆、医药冷库等合规场景,一个错误的温湿度值(如传感器受潮导致湿度飙升至 99% RH)可能引发误告警、误联动,甚至导致合规审计失败。因此,端侧(Edge/Device Side)数据校验是第一道质量防线。
本文聚焦以太网温湿度变送器的CRC 校验与异常值过滤逻辑,解析数据在离开 MCU 之前,如何被“清洗”和“自证清白”。
有人会问:TCP/IP 本身有校验和(Checksum),平台侧也可以做阈值判断,为什么还要在端侧做?
原因有三:
CRC(Cyclic Redundancy Check,循环冗余校验)是嵌入式领域最常用的错误检测码。它用于检测数据在内存拷贝、总线传输、网络发送过程中是否发生意外改变。
在以太网温湿度变送器中,CRC 通常应用于两个层面:
当节点通过 UDP 或私有 TCP 协议发送数据时,报文结构通常如下:
[帧头][长度][设备ID][时间戳][温度][湿度][CRC16][帧尾]节点内部 Flash 中存储着校准参数、阈值配置、设备 ID 等。
在资源受限的 MCU 中,CRC 计算需兼顾速度与性能。
示例:CRC-16-MODBUS 查表法(高效)
// CRC16 查找表(部分)
static const uint16_t crc16_table[256] = {...};
uint16_t calc_crc16(const uint8_t *data, uint16_t length) {
uint16_t crc = 0xFFFF; // MODBUS CRC 初始值
while (length--) {
crc = (crc >> 8) ^ crc16_table[(crc ^ *data++) & 0xFF];
}
return crc;
}
// 发送前打包
void build_packet(env_data_t *data, uint8_t *buf) {
// ... 填充数据 ...
uint16_t crc = calc_crc16(buf + 1, data_len); // 假设帧头不算CRC
buf[total_len - 3] = crc & 0xFF; // 低字节在前
buf[total_len - 2] = (crc >> 8) & 0xFF; // 高字节在后
}平台侧校验:
平台收到报文后,对相同字段计算 CRC,与报文尾部的 CRC 字段比对。若不一致,直接丢弃该包并记录“CRC Error”计数,不向上层业务传递。
即使 CRC 校验通过,数据在物理层面是正确的(0/1 没变),但在逻辑层面可能是荒谬的(如温度 -100℃)。异常值过滤旨在剔除物理上正确但逻辑上荒谬的数据。
这是最基础的过滤,基于传感器的物理特性。
逻辑:
if (temp < -40.0 || temp > 85.0) {
data_quality = QUALITY_OUT_OF_RANGE;
discard_data();
}
if (humi < 0.0 || humi > 100.0) {
data_quality = QUALITY_OUT_OF_RANGE;
discard_data();
}温湿度是慢变信号。如果 1 秒内温度变化 5℃,极大概率是噪声或传感器故障,而非真实环境变化。
逻辑:
float temp_change = fabs(current_temp - last_valid_temp);
float max_change_per_sec = 2.0; // 假设最大变化率 2℃/s
if (temp_change > max_change_per_sec * sample_interval_sec) {
// 变化过快,标记为可疑,但不一定丢弃,可能触发内部自检
data_quality = QUALITY_SUSPICIOUS;
// 可选:保留旧值,或触发传感器重新校准流程
} else {
last_valid_temp = current_temp;
}对于极其稳定的环境(如档案馆恒温恒湿),连续读取到完全相同的值(如连续 100 次都是 25.60℃),可能意味着 ADC 卡死或数据通路故障(尽管 CRC 可能通过)。
逻辑:
if (current_temp == last_temp) {
identical_count++;
if (identical_count > 100) { // 阈值可配置
data_quality = QUALITY_STUCK;
trigger_self_test(); // 触发自检
}
} else {
identical_count = 0;
}在 ADC 采样后、数据输出前,进行软件滤波,去除随机噪声。
new_val = 0.7 * old_val + 0.3 * current_val。平滑曲线,但会引入滞后。 推荐:工业传感器常用 中值+滑动平均组合,兼顾实时性与稳定性。
经过上述校验与过滤后,节点应输出带有数据质量戳的数据,而不仅仅是数值。
定义质量枚举:
typedef enum {
QUALITY_GOOD = 0, // 数据有效
QUALITY_CRC_ERROR, // CRC 校验失败
QUALITY_OUT_OF_RANGE, // 超出物理极限
QUALITY_RATE_LIMIT, // 变化率超限
QUALITY_STUCK, // 数值卡死
QUALITY_SENSOR_FAULT, // 传感器自检失败
QUALITY_UNCERTAIN // 不确定(如边缘值)
} data_quality_t;报文携带质量戳:
{
"device_id": "TH-20-031",
"temp": 25.6,
"humi": 53.2,
"quality": 0, // QUALITY_GOOD
"timestamp": 1700000000
}平台侧处理:
💡 关键原则:坏数据不入历史库,但坏数据要入告警库。 即数据本身不能用于趋势分析,但数据缺失或异常事件必须被记录,用于运维审计。
除了对采集的数据进行校验,变送器还应具备自检能力,定期或在异常时验证自身健康状态。
自检结果通过 SNMP Trap 或 MQTT 主动上报,或通过特定寄存器(如 Modbus 40003)供平台轮询。
端侧数据校验机制是以太网温湿度变送器的“免疫系统”。它通过 CRC 校验 确保数据在传输链路上“没坏”,通过 异常值过滤 确保数据在逻辑上“不傻”,通过 数据质量戳 为平台提供决策依据,通过 自检机制 确保自身“健康”。
设计 Checklist:
💡 核心思想:让错误死在端侧,让真相流向平台。 只有经过严格校验的数据,才配得上“智慧档案馆”的“智慧”二字。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。