在使用灵动MCU(MindMotion MCU)监测电压波动(如电池电压、电源电压)时,如果直接依赖原始ADC值进行判断,容易因为瞬时噪声、电磁干扰或电源纹波而产生误报。为了实现更稳定、更可靠的电压判断逻辑,建议结合数字滤波策略进行处理。
误报的常见原因
原因 示例场景
ADC采样抖动 由于供电噪声、模拟输入阻抗高等问题
负载突变引起电压闪降 电机启动、无线发射瞬时拉低电压
高频干扰 尤其是开关电源、电感器件邻近ADC管脚
不恰当的阈值判断 单点判断可能触发虚假的低电压报警
推荐的数字滤波方法
1.移动平均滤波(滑动窗口法)
原理:连续采样N次,计算平均值后再判断。
优点:实现简单,抗短时干扰能力强。
缺点:响应略滞后,不适合快速突变场合。
#define WINDOW_SIZE 8
uint16_t adcBuffer[WINDOW_SIZE];
uint8_t index = 0;
uint16_t MovingAverageFilter(uint16_t newSample) {
adcBuffer[index++] = newSample;
if (index >= WINDOW_SIZE) index = 0;
uint32_t sum = 0;
for (int i = 0; i < WINDOW_SIZE; i++) {
sum += adcBuffer[i];
}
return (uint16_t)(sum / WINDOW_SIZE);
}
中值滤波(Median Filter)
原理:采集若干个数据点,取中间的那个值。
优点:能有效剔除尖峰干扰(如某一次明显偏离)。
缺点:实现稍复杂,运算量略大。
uint16_t MedianFilter(uint16_t *data, uint8_t size) {
uint16_t temp[size];
memcpy(temp, data, size * sizeof(uint16_t));
// 简单冒泡排序
for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < size; j++) {
if (temp[i] > temp[j]) {
uint16_t t = temp[i];
temp[i] = temp[j];
temp[j] = t;
}
}
}
return temp[size / 2];
}
卡尔曼滤波(Kalman Filter)
高级滤波方法,适合对电压变化趋势建模,有更强的预测性。
更适用于需要跟踪变化、但过滤突变的系统,如电池电量估算。
若需使用卡尔曼滤波,我可提供完整代码模板。
结合逻辑阈值判断的优化策略
延迟确认机制:只有电压连续低于阈值 N 次采样 才触发报警,防止瞬时闪变误报。
c
复制
编辑
#define LOW_VOLTAGE_THRESHOLD 2700 // mV
#define DETECT_COUNT_THRESHOLD 5
uint8_t lowVoltageCount = 0;
bool isLowVoltage = false;
void VoltageDecision(uint16_t filteredVoltage) {
if (filteredVoltage < LOW_VOLTAGE_THRESHOLD) {
lowVoltageCount++;
if (lowVoltageCount >= DETECT_COUNT_THRESHOLD && !isLowVoltage) {
isLowVoltage = true;
TriggerLowVoltageAlarm();
}
} else {
lowVoltageCount = 0;
isLowVoltage = false;
}
}
可选扩展功能
可设置报警阈值为 动态(软件可配置)
将滤波后电压用于电量估算、曲线绘制等应用
|