你有没有想过一个每天上报几万条传感器数据的网关其中有多少条是真正有用的有些项目里网关往云端推的数据量中超过一半是废话——前后两秒温度没变也塞一条上去。带宽烧了存储撑了云端那边还得跑一套去重逻辑何苦呢。与其等上位机来擦屁股不如在网关这一层就把脏活干了。过滤是为了什么网关的处境其实挺尴尬。它不像传感器那样只管采集也不像云平台那样有无限的算力和存储。它夹在中间要做的不是把所有东西传上去而是只把有价值的东西传上去。三个核心目标减流量——NB-IoT按流量计费LoraWAN有占空比限制WiFi虽然不差钱但也没必要白烧降延迟——聚合之后再上传云端一次处理完省掉来回握手的时间去冗余——重复数据到了云端还得查重能在边缘干掉的就别往上送三个常用策略死区过滤最简单也最容易被忽略。传感器数据在稳定状态下波动极小。比如一个温度传感器精度是±0.1°C那它在25°C上下跳个0.05°C属于正常噪声。如果每次变化都上报云端的数据库里会塞满25.01、24.99、25.02这种毫无意义的记录。做法是设一个阈值delta只有当新值和上一次上报值之差超过delta时才真的往上送。#define TEMP_DEADBAND 0.5f static float last_reported_temp 0.0f; static int first_report 1; int should_report_temperature(float current_temp) { if (first_report) { last_reported_temp current_temp; first_report 0; return 1; } if (fabsf(current_temp - last_reported_temp) TEMP_DEADBAND) { last_reported_temp current_temp; return 1; } return 0; }关键在delta怎么设。设太小等于没过滤设太大又可能错过真实变化。一个经验是取传感器精度数值的3到5倍——精度0.1°Cdelta用0.3到0.5°C比较合理。变化率过滤死区过滤有个盲区温度从20°C缓升到30°C中间每一度都跨过了死区阈值该上传的一条不少。但如果变化速率本身很慢比如五分钟才升一度那每次上传的必要性其实值得商榷。变化率过滤的思路是不仅要看变化幅度还要看变化的速度。#define RATE_LIMIT 0.1f // 每秒不超过0.1°C #define MIN_INTERVAL 30 // 至少30秒上报一次 static float last_rate_report 0.0f; static uint32_t last_rate_ts 0; int should_report_by_rate(float current_temp, uint32_t now_sec) { float rate; uint32_t elapsed now_sec - last_rate_ts; if (elapsed MIN_INTERVAL) return 0; rate fabsf(current_temp - last_rate_report) / elapsed; if (rate RATE_LIMIT || elapsed 300) { last_rate_report current_temp; last_rate_ts now_sec; return 1; } return 0; }这里加了一个保底逻辑——超过300秒五分钟不管变化率多少强制上报一次。防止网关静默太久云端以为设备离线了。滑动窗口聚合有些场景不需要原始采样值需要的是一个时间段内的统计特征。比如工业振动监测三轴加速度传感器每秒采4000个点全量上传根本不可能。网关要做的是开一个时间窗口窗口结束时算一下最大值、最小值、平均值只上报这三个值。#define WINDOW_SEC 1 typedef struct { float sum; float max; float min; uint32_t count; } agg_window_t; void agg_reset(agg_window_t *w) { w-sum 0.0f; w-max -1e6f; w-min 1e6f; w-count 0; } void agg_feed(agg_window_t *w, float sample) { w-sum sample; if (sample w-max) w-max sample; if (sample w-min) w-min sample; w-count; } // 窗口结束时调用返回一个聚合结果 // 4000个点压成3个float压缩比超过1000:1这里的压缩比是可以量化的。4000个原始float是16KB三个float才12字节。代价是丢掉了个体的时序细节——但如果应用只需要知道这一秒最大振动到了多少这个代价完全可以接受。三种策略怎么选这不是一个非此即彼的问题。实际项目中往往是三层叠加死区过滤放在最前面挡掉传感器噪声。变化率过滤跟在后面过滤掉缓慢漂移。滑动窗口用于高频数据流把原始信号压成统计特征。一个常见误区是觉得过滤越多越好。过滤逻辑本身也是计算开销。在资源受限的MCU上一次fabsf调用可能就要几十个周期。如果每路传感器都跑三个滤波算法CPU占用率可能比实际传输数据还高。所以还是要看具体的业务场景——电池供电的温湿度传感器死区过滤就够用了高频振动监测不得不用窗口聚合。有意思的是很多做云端开发的同事第一次接触网关过滤时第一反应是这些数据丢了怎么办。但换个角度看一个每秒上报4000个点的振动传感器如果真的全量送到了云端云端的时序数据库按点计费一个月下来开销可能比硬件本身还贵。网关在这里的角色恰恰是帮两边都省点力气。这就是今天想分享的内容。你们在实际项目里是怎么做边缘数据降噪的用哪种过滤组合比较多