Arduino爱好者

 找回密码
 立即注册

QQ登录

只需一步,快速开始

楼主: eagler8

[经验] 【Arduino】108种传感器模块系列实验(91)--水流量传感器模块

[复制链接]
 楼主| 发表于 2021-7-9 09:44 | 显示全部楼层
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验九十一: 1号霍尔水流量传感器 直饮机流量监控模块
  项目九:水流量传感器输出处理为以升/小时为单位读取
  实验接线:Uno D2接流量传感器OUT
  实验开源代码

  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  3.   实验九十一: 1号霍尔水流量传感器 直饮机流量监控模块
  4.   项目九:水流量传感器输出处理为以升/小时为单位读取
  5.   实验接线:Uno D2接流量传感器OUT
  6. */

  7. volatile int flow_frequency; // 测量无符号流量传感器脉冲

  8. int l_hour; // 计算升/小时
  9. unsigned char flowsensor = 2; // 传感器输入
  10. unsigned long currentTime;
  11. unsigned long cloopTime;

  12. void flow () // 中断功能
  13. {
  14.   flow_frequency++;
  15. }

  16. void setup() {
  17.   pinMode(flowsensor, INPUT);
  18.   digitalWrite(flowsensor, HIGH); // 可选的内部上拉
  19.   Serial.begin(9600);
  20.   attachInterrupt(0, flow, RISING); // 设置中断
  21.   sei(); // 启用中断
  22.   currentTime = millis();
  23.   cloopTime = currentTime;
  24. }

  25. void loop () {
  26.   currentTime = millis();
  27.   // 每秒,计算并打印升/小时
  28.   if (currentTime >= (cloopTime + 1000))
  29.   {
  30.     cloopTime = currentTime; // 更新循环时间
  31.     //脉冲频率 (Hz) = 7.5Q,Q 是以 L/min 为单位的流速。
  32.     l_hour = (flow_frequency * 60 / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour
  33.     flow_frequency = 0; // 重置计数器
  34.     Serial.print(l_hour, DEC); // 打印升/小时
  35.     Serial.println(" L/hour");
  36.   }
  37. }
复制代码


 楼主| 发表于 2021-7-9 09:46 | 显示全部楼层
实验串口返回情况

32.jpg
 楼主| 发表于 2021-7-9 09:53 | 显示全部楼层
本帖最后由 eagler8 于 2021-7-9 15:03 编辑

水流量传感器的计算公式(仅供参考,实际使用还需专业校准)

在代码部分,我们使用了下面的公式,那么这个公式是怎么来的呢?

  1. l_hour = (flow_frequency * 60 / 7.5)
复制代码

前面我们提到过,轮子每转一圈,流过的流体体积是一定的。同时,车轮每转一圈产生的脉冲数也是一定的。因此,我们可以建立脉冲数与水流量之间的方程。

事实上,YF系列使用了一个六极交替的环形磁铁,因此每转一圈,就会产生三个低电平和三个高电平,即三个脉冲。

对于 YF-S402,每流一升水,霍尔传感器输出 450 个脉冲。让我们在这里做一点数学。
450 脉冲表示 1 升,因此每个脉冲表示流过 1/450 升水。
我们取某一时刻流经水流传感器的液体总量 t(单位s)为 V_total(单位L),检测到的脉冲总数为 N。然后我们得到:


  1. V_total(L) = N* 1/450(L)
复制代码


此外,流经水流量传感器的流体总体积等于 water flow rate(Q - unit L/s) 乘以时间 t(单位 s)。

  1. V_total(L) = Q(L/s)*t(s)
复制代码

所以,我们得到:

  1. N* 1/450 = Q(L/s)*t(s)
  2. N/t = 450 * Q(L/s)
复制代码

N/t 恰好是 frequency  f,所以:

  1. f = 450*Q(L/s);
  2. Q(L/s) = f/450;
  3. Q(L/min) = f*60/450 = f/7.5
  4. Q(L/hour) = f*60*60/450 = f*60 /7.5
复制代码

对于 YF – S402,每流一升水,霍尔传感器输出 4380 个脉冲。所以,公式应该是:

  1. f = 4380*Q(L/s);
  2. Q(L/s) = f/4380;
  3. Q(L/min) = f*60/4380 = f/73
  4. Q(L/hour) = f*60*60/4380 = f*60 /73
复制代码

 楼主| 发表于 2021-7-9 13:38 | 显示全部楼层
   【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验九十一: 1号霍尔水流量传感器 直饮机流量监控模块
  项目十:用LCD1602A屏显示水流量传感器输出
  实验开源代码
  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  3.   实验九十一: 1号霍尔水流量传感器 直饮机流量监控模块
  4.   项目十:用LCD1602A屏显示水流量传感器输出
  5.   实验接线:Uno D2接流量传感器OUT
  6.   Arduino------LCD1602
  7.   5V-------------VCC
  8.   GND-----------GND
  9.   A4-----------SDA IIC 数据线
  10.   A5-----------SCL  IIC 时钟线
  11. */

  12. #include <Wire.h>
  13. #include <LiquidCrystal_I2C.h>
  14. LiquidCrystal_I2C lcd(0x27, 16, 2);

  15. unsigned char flow_sensor_pin = 2;
  16. unsigned int flow_per_min;
  17. unsigned long current_time;
  18. unsigned long cloop_time;
  19. volatile int sensor_pulses;

  20. void setup() {
  21.   Serial.begin(9600);
  22.   lcd.init(); //初始化LCD
  23.   lcd.backlight(); //打开背光
  24.   sei();
  25.   lcd.begin(16, 2);
  26.   lcd.clear();
  27.   lcd.setCursor(0, 0);
  28.   lcd.print(" Flow Meter ");

  29.   pinMode(flow_sensor_pin, INPUT);
  30.   digitalWrite(flow_sensor_pin, HIGH);
  31.   attachInterrupt(0, pulses_measure, RISING);

  32.   current_time = millis();
  33.   cloop_time = current_time;
  34. }

  35. void loop ()
  36. {
  37.   current_time = millis();
  38.   if (current_time >= (cloop_time + 1000))
  39.   {
  40.     cloop_time = current_time;
  41.     flow_per_min = (sensor_pulses / 7.5);
  42.     sensor_pulses = 0;

  43.     Serial.print(flow_per_min, DEC);
  44.     Serial.println(" L/MIN");

  45.     lcd.setCursor(0, 1);
  46.     lcd.print(" ");
  47.     lcd.setCursor(0, 1);
  48.     lcd.print(" Flow:");
  49.     lcd.print(flow_per_min, DEC);
  50.     lcd.print(" L/MIN");
  51.     delay(100);
  52.   }
  53. }

  54. void pulses_measure () {
  55.   sensor_pulses++;
  56. }
复制代码





 楼主| 发表于 2021-7-9 13:56 | 显示全部楼层
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验九十一: 1号霍尔水流量传感器 直饮机流量监控模块
  项目十:用LCD1602A屏显示水流量传感器输出

实验场景图

33.jpg

 楼主| 发表于 2021-7-9 14:56 | 显示全部楼层
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)  实验八十八: LCD1602A液晶屏5V显示模块(IIC/I2C接口)
  项目二十一:水流量传感器、5V继电器模块和LCD1602 I2C模块
  实验接线:Uno D2接流量传感器OUT,继电器接D4
  Arduino------LCD1602
  5V-------------VCC
  GND-----------GND
  A4-----------SDA IIC 数据线
  A5-----------SCL  IIC 时钟线

实验开源代码
  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  3.   实验八十八: LCD1602A液晶屏5V显示模块(IIC/I2C接口)
  4.   项目二十一:水流量传感器、5V继电器模块和LCD1602 I2C模块
  5.   实验接线:Uno D2接流量传感器OUT,继电器接D4
  6.   Arduino------LCD1602
  7.   5V-------------VCC
  8.   GND-----------GND
  9.   A4-----------SDA IIC 数据线
  10.   A5-----------SCL  IIC 时钟线
  11. */

  12. #include <LiquidCrystal_I2C.h> //include LiquidCrystal Library

  13. LiquidCrystal_I2C lcd(0x27, 16, 2);
  14. #define FLOWSENSORPIN 2 //连接到 Arduino 数字引脚 2 的水流传感器
  15. #define relayPin 4    // 连接到 Arduino 数字引脚 4 的 5v 继电器模块
  16. volatile uint16_t pulses = 0; // count how many pulses
  17. volatile uint8_t lastflowpinstate; // track the state of the pulse pin
  18. volatile uint32_t lastflowratetimer = 0; // you can try to keep time of how long it is between pulses
  19. volatile float flowrate; // and use that to calculate a flow rate
  20. // Interrupt is called once a millisecond, looks for any pulses from the sensor!

  21. SIGNAL(TIMER0_COMPA_vect) {
  22.   uint8_t x = digitalRead(FLOWSENSORPIN);

  23.   if (x == lastflowpinstate) {
  24.     lastflowratetimer++;
  25.     return; // nothing changed!
  26.   }

  27.   if (x == HIGH) {
  28.     //low to high transition!
  29.     pulses++;
  30.   }
  31.   lastflowpinstate = x;
  32.   flowrate = 1000.0;
  33.   flowrate /= lastflowratetimer;  // in hertz
  34.   lastflowratetimer = 0;
  35. }

  36. void useInterrupt(boolean v) {
  37.   if (v) {
  38.     // Timer0 is already used for millis() - we'll just interrupt somewhere
  39.     // in the middle and call the "Compare A" function above
  40.     OCR0A = 0xAF;
  41.     TIMSK0 |= _BV(OCIE0A);
  42.   } else {
  43.     // do not call the interrupt function COMPA anymore
  44.     TIMSK0 &= ~_BV(OCIE0A);
  45.   }
  46. }

  47. void setup() {
  48.   Serial.begin(9600);
  49.   Serial.print("---Water flow sensor---");
  50.   lcd.init();                      // 初始化液晶显示器
  51.   lcd.backlight();
  52.   lcd.begin(16, 2);                            //16X2 lcd display
  53.   lcd.setBacklight(HIGH);
  54.   lcd.setCursor(0, 0);                       //setting display position
  55.   lcd.print("Aqua counter");
  56.   pinMode(FLOWSENSORPIN, INPUT); //sets the FLOWSENSORPIN as an INPUT
  57.   pinMode(relayPin, OUTPUT);//sets the relayPin as OUTPUT
  58.   digitalWrite(relayPin, LOW);
  59.   digitalWrite(FLOWSENSORPIN, HIGH);//optional Internal Pull-Up
  60.   lastflowpinstate = digitalRead(FLOWSENSORPIN);
  61.   useInterrupt(true);
  62.   delay(2000);
  63.   lcd.clear();
  64. }

  65. void loop()
  66. {
  67.   lcd.setCursor(0, 0);
  68.   lcd.print("Pulses:"); lcd.print(pulses, DEC);
  69.   lcd.print(" Hz:");
  70.   lcd.print(flowrate);
  71.   //lcd.print(flowrate);
  72.   Serial.print("Freq: "); Serial.println(flowrate);
  73.   Serial.print("Pulses: "); Serial.println(pulses, DEC);

  74.   // if a plastic sensor use the following calculation
  75.   // Sensor Frequency (Hz) = 7.5 * Q (Liters/min)
  76.   // Liters = Q * time elapsed (seconds) / 60 (seconds/minute)
  77.   // Liters = (Frequency (Pulses/second) / 7.5) * time elapsed (seconds) / 60
  78.   // Liters = Pulses / (7.5 * 60)
  79.   float liters = pulses;
  80.   liters /= 7.5;
  81.   liters /= 60.0;

  82.   /*
  83.     // if a brass sensor use the following calculation
  84.     float liters = pulses;
  85.     liters /= 8.1;
  86.     liters -= 6;
  87.     liters /= 60.0;
  88.   */
  89.   Serial.print(liters); Serial.println(" Liters");
  90.   lcd.setCursor(0, 1);
  91.   lcd.print(liters); lcd.print(" Litres        ");
  92.   if (liters >= 0.15) //water limit set
  93.   {
  94.     digitalWrite(relayPin, HIGH);
  95.   }
  96.   else {
  97.     digitalWrite(relayPin, LOW);
  98.   }
  99.   delay(2000);
  100.   lcd.clear();
  101. }
复制代码


 楼主| 发表于 2021-7-9 15:02 | 显示全部楼层
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验八十八: LCD1602A液晶屏5V显示模块(IIC/I2C接口)
  项目二十一:水流量传感器、5V继电器模块和LCD1602 I2C模块
  实验接线:Uno D2接流量传感器OUT,继电器接D4

  实验串口返回情况

29.jpg

 楼主| 发表于 2021-7-9 15:06 | 显示全部楼层
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验八十八: LCD1602A液晶屏5V显示模块(IIC/I2C接口)
  项目二十一:水流量传感器、5V继电器模块和LCD1602 I2C模块
  实验接线:Uno D2接流量传感器OUT,继电器接D4

实验场景图 30.jpg

发表于 2021-7-10 08:41 来自手机 | 显示全部楼层
你快把我想做的做完了
发表于 2021-7-10 09:12 来自手机 | 显示全部楼层
下一步你是不是要接上wifi模块了,我付费你帮我做个集成吧
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|好玩手机游戏盒子|196体育|Arduino爱好者

GMT+8, 2023-6-1 13:17 , Processed in 0.136422 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表