第一次拿到这个6mm软管接口的小家伙时,我也被它简单的三根线迷惑了。红黑线供电,黄线输出脉冲,看起来平平无奇,但里面的设计相当巧妙。拆开塑料阀体会发现,核心是那个带磁铁的水流转子——水流推动转子旋转时,旁边的霍尔传感器就像地铁闸机计数器,每检测到一次磁极变化就输出一个脉冲信号。
实测过程中有个有趣现象:当我用500mL矿泉水瓶接水时,发现脉冲数总在2400左右波动。这个数据很关键,因为它直接验证了厂家没提供的参数——每升水对应4800个脉冲。不过要注意,不同安装角度会导致这个数值变化,水平安装时转子受重力影响最小,测量最准。有次我偷懒斜着装了15度,结果流量误差直接飙到8%,这个坑你们千万别踩。
在CubeMX里配置PA11为外部中断引脚时,有三个细节决定成败:
c复制// 关键配置代码示例
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 2, 0);
当水流量大于5L/min时,外部中断可能丢失脉冲。这时TIM2的ETR功能就是救星,它直接把脉冲信号当作时钟源。配置时要注意:
c复制// TIM2配置关键参数
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ETRMODE2;
sClockSourceConfig.ClockPolarity = TIM_CLOCKPOLARITY_NONINVERTED;
sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
sClockSourceConfig.ClockFilter = 5;
原始公式看起来简单:流量=脉冲数/系数K。但实际测试发现,这个K值会随流速变化!我的解决方案是分段校准:
5L/min区间:K=76
c复制// 优化后的计算代码
float getDynamicK(uint32_t pulse) {
if(pulse < 160) return 80.0f;
else if(pulse < 400) return 78.5f;
else return 76.0f;
}
连续工作时,累计流量变量可能溢出。我的工程里做了三重保护:
c复制// 安全累计算法示例
if(golbal_flow.acculat >= 1000000.0) {
SaveToEEPROM(golbal_flow.acculat);
golbal_flow.acculat = 0;
}
用同一台水泵做测试时,发现了意料之外的结果:
| 流量范围 | 中断方式误差 | 时钟方式误差 |
|---|---|---|
| 0.5-1L/min | ±2.1% | ±3.5% |
| 1-3L/min | ±1.8% | ±1.2% |
| >3L/min | ±5.7% | ±0.8% |
原来在低流量时,外部中断的精准度反而更高!这是因为定时器的时钟分频会导致小流量脉冲丢失。后来我改进的方案是:流量<1L/min用中断模式,>1L/min自动切换到时钟模式。