脉冲流量计怎么换算成升?YF-S201实测450脉冲/升偏差11%,附ESP32与S7-1200读数步骤
上个月帮楼下老张的鱼缸做自动补水,随手买了个YF-S201水流量传感器。规格书写得很清楚:450脉冲/升,频率F(Hz) = 7.5 × 流量(L/min)。我就照这个写了代码,脉冲数除以450就是升数。跑了三天,老张说水加多了,地板湿了一片。我拿10升量杯重测,18升那一档实际只倒进去15.9升,20升那一档更离谱,最多差11%。
后来连着三个晚上做了几组标定,才明白问题不在我的代码,而在「450脉冲/升」这五个字本身。它是个平均值,前提是稳定层流、水温20℃左右、管路无气泡、水压恒定,现实里这四条一条都不占。所以这篇不吹传感器,只讲我踩过的东西,以及一套你自己能把脉冲流量换算准的笨办法。
一、脉冲流量到底是什么,为什么不能直接乘系数
水流量传感器里最常见的是霍尔式叶轮。水流推着叶轮转,叶轮上嵌了一小块磁钢,旁边一个霍尔元件。磁钢每扫过一次霍尔,输出电平就翻转一次,出来一串方波。你数方波个数除以脉冲当量,得到累计流量;你测方波频率乘个系数,得到瞬时流量。YF-S201的公式是F = 7.5 × Q,Q单位L/min,反过来Q = F / 7.5,看着特别干净,干净得像假的。
问题出在叶轮不是理想速度计。低流量时(1~2 L/min),水流推不动叶轮,它有爬行、有停顿,甚至转半圈又倒回去一点,脉冲数会偏少;高流量时(25 L/min以上)叶轮转速上去了,但轴摩擦、水流湍流、管径突变带来的涡流,又会让当量往上抬或者往下压。厂家给的450是在某个中间流量、某个水压下标出来的,你换个水泵、换个管径、加个弯头,它就变了。
我拿三个量杯、一个秒表、一个12V隔膜泵做标定。方法是先跑固定体积,用秒表算平均流量,同时用ESP32数脉冲,算出这一档的脉冲当量,分五档。下面这张表是我这只YF-S201的实测值(4分口径,进水25℃左右),不是普适规律:
| 平均流量 (L/min) | 累计脉冲数 | 折算脉冲当量 (脉冲/升) | 相对450的偏差 |
|---|---|---|---|
| 1.2 | 2190(跑5L) | 438 | -2.7% |
| 5.0 | 2262(跑5L) | 452 | +0.4% |
| 10.1 | 11260(跑25L) | 450 | 0 |
| 18.5 | 8904(跑20L) | 445 | -1.1% |
| 25.6 | 11520(跑25L) | 461 | +2.4% |
单档看没多大,可你要是长时间小流量滴灌,200升累计下来就是4到5升的差额,养鱼、配药、做滴定实验都受不了。
二、三种脉冲输出,买之前先分清楚
市面上叫得出名字的脉冲流量传感器就三大类,参数差得挺远,我整理了一下:
| 类型 | 代表型号 | 脉冲当量 | 流量范围 | 供电 | 输出形式 | 参考单价 |
|---|---|---|---|---|---|---|
| 霍尔叶轮(大方量) | YF-S201 | 约450 脉冲/升 | 1~30 L/min | DC 5~24V | 方波,占空比约50% | 15~25元 |
| 霍尔叶轮(小方量) | YF-S401 | 约5880 脉冲/升 | 0.3~6 L/min | DC 5~24V | 方波,F=98×Q | 25~40元 |
| 干簧管式 | 老式水表加装 | 1脉冲/转,需实测 | 视表体而定 | 无源触点 | 机械通断 | 10~30元 |
| 涡轮+光电编码器 | 工业型 | 可到20000 脉冲/升 | 0.1~10 L/min | DC 12~24V | 推挽/集电极开路 | 300元起 |
霍尔式的优点是便宜、输出干净、直接进MCU;缺点是叶轮有启动流量,低于1 L/min基本不转。干簧管的优点是不要供电、抗干扰好,缺点是触点会抖,我见过用示波器看一次闭合能抖出七八个窄脉冲,不做消抖计数直接翻倍。光电编码器精度最高,但那个价格你也看到了,一般人不值得。
选型号时还有个容易忽略的点:口径。4分(1/2英寸)和6分(3/4英寸)同样是S201系列,脉冲当量能差出一倍。买的时候别只看型号前缀,要看完整料号和螺纹规格。
三、自己标定的四个步骤
第一步,准备一个能读到50mL刻度的量杯,至少5升容量,和一个能计时的手机秒表。别用桶,桶的刻度误差比传感器还大。
第二步,把传感器装在你实际使用的位置,别拆下来单独测。管子长度、弯头数量、水泵位置都会影响叶轮,拆下来测出来的数搬回去就不准了。
第三步,至少跑三档:你日常的最小流量、最常见流量、最大流量。每档跑够20升以上再停,跑太少随机误差压不住。记下累计脉冲数N和实际体积V,当量 = N / V。
第四步,把三个当量做成一张分段表写进代码。比如我这只:低于2 L/min用438,2到15 L/min用450,高于15 L/min用458。听起来糙,但比你全程用一个450准得多,我实测累计200升的误差从5.2升降到了1.1升。
如果想更严谨一点,就画N-V曲线做线性回归,斜率就是当量。不过对家用项目来说,三档分段已经够了。
四、ESP32读数:中断能跑,但有两个细节会坑你
写代码这块,最容易被忽略的是触发边沿。YF-S201输出的是占空比接近50%的方波,一高一低算一个完整周期,也就是一个脉冲。很多人图省事写CHANGE,结果一个周期触发两次,读数直接翻倍,还以为传感器不准。正确做法是只用FALLING或者只用RISING,二选一。
第二个细节是中断里千万别干重活。我一开始在ISR里做浮点运算、算流量、往串口打日志,结果15 L/min时频率才112.5 Hz就丢脉冲了,因为串口打印阻塞了几毫秒。改成ISR里只做count++,主循环里每1秒读一次差值,就稳了。
如果你的流量会超过25 L/min,建议上PCNT硬件计数器,ESP32有8个PCNT单元,每个16位,可以设上下限报警,还能开毛刺滤波。毛刺滤波的门限按APB时钟80MHz算,设1000就是滤掉大约12.5微秒以下的窄脉冲,正好能压住泵启停时的那点尖峰。
// 中断版,ISR里只加一
volatile uint32_t pulseCount = 0;
void IRAM_ATTR onPulse() { pulseCount++; }
void setup() {
pinMode(27, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(27), onPulse, FALLING);
}
// 主循环每1000ms读一次
uint32_t now = pulseCount;
uint32_t delta = now - lastCount;
lastCount = now;
float liter = delta / 450.0f;
float lpm = liter * 60.0f;
还有一点,YF-S201是集电极开路输出,必须加上拉电阻。我见过有人直接接GPIO不加pull-up,读到的数一会儿多一会儿少,查了半天以为是干扰,其实就是引脚悬空。
五、S7-1200读数:采样窗比计数器更关键
PLC这边我用的是CPU 1214C,板载HSC单相最高100 kHz,YF-S201满量程才225 Hz,随便跑。配置上选HSC1,计数模式,单相计数,输入滤波设成最低档。
真正的坑在采样周期。我一开始用OB30设100ms中断读一次计数值,结果1 L/min时100ms只有7.5个脉冲,加上取整误差,算出来的瞬时流量在0.8到1.3之间来回跳。后来把中断周期改成1秒,低流量下就平滑多了。所以采样窗要看你关心的流量下限:低于3 L/min,老老实实用1秒;只看大流量,100ms也行。
另一个细节是计数寄存器是DInt,加减法别用Int,不然跑到32767就溢出了。25 L/min跑一天是1620万个脉冲,早爆了。复位用CTRL_HSC指令,别直接写寄存器,写不进去。
六、我踩过的七个坑
- 用CHANGE触发,脉冲翻倍,查了两天。
- 传感器装反了。壳体上有箭头,进水方向错了叶轮不转或者转得极慢,表现为脉冲极少。
- 管里有气泡。水泵吸入口漏气,叶轮在气液混合里空转,脉冲数虚高,比实际流量多算20%以上。
- 泵启停的水锤产生虚脉冲。硬件上加10kΩ上拉加4.7~10nF对地,软件上开PCNT毛刺滤波。
- 5V输出直连3.3V的ESP32 GPIO。短期能用,长期不保险,加个电阻分压或者电平转换模块。
- 用半年后水垢。叶轮变重,同样的流量转得慢,脉冲当量整体往上飘。我拆开用白醋泡了半小时,当量从468回到451。
- 长时间低流量跑,累计误差累加。这个是最隐性的,短时间内看不出来。
七、最后
如果你的项目只是做个大致的水量统计,450这个数用着也行,误差5%到10%能接受。但你要是配药、做实验、给鱼缸精准补水,花一个晚上标定一下,比换一个贵十倍的传感器管用。
顺便说一句,我现在给老张的鱼缸用的是标定后的分段当量,跑了半个月,补水误差在200毫升以内。老张还挺满意,就是他至今不知道我把他家地板搞湿过。