利用WIFI模块检测水塔水位高度并将结果上传给点灯APP-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1025|回复: 2

利用WIFI模块检测水塔水位高度并将结果上传给点灯APP

[复制链接]
发表于 2022-2-6 14:51 | 显示全部楼层 |阅读模式
本帖最后由 xiongjiaxiao 于 2022-2-6 14:52 编辑

最近家里老是停水,还好房顶上备用了一个大水塔,以备不时只需,平时往里面灌水,停水时用就行了,但如果水灌得太满的话水就会溢出造成不必要的麻烦,而且每次用完水后主人需要水塔里还剩多少水,因此我就想,有没有一款可以将水塔当前水位发送给用户,使其能够一目了然的知道水塔里还剩多少水。
那么接下来,就要开始构思了。

主控用的是ESP-01M,这款模块的IO数量正好够用,并且他是直插封装的,所以就选他了!
检测距离的话用超声波就行了,但是超声波有个致命缺点,那就是一旦测量物体太近或者太远,就会导致测量结果不准(讲个笑话,之前我在调试的时候用手挡住了超声波模块,结果测量距离高达十万八千里!)。不过我们的项目要求的测量精度并不高,所以说就用它了!
现在,就可以开始编写代码了。
在这里,有一个地方要注意了,超声波检测到的距离不能直接上传给点灯APP,这是因为此时超声波检测的并不是剩余水量,因此,我们要用水位的总高度(比如我的水塔高度是两米,我就用2米减去测得的值)减去测得的值,考虑到后期还可以用在别的地方,我就用一个滑块来设定最高的水位(单位为米)因为超声波模块最大能检测7米,因此要将滑块的最小和最大值设置为1-7米,这样测出的数据才是真正的水位高度,你以为这就完了?不不不,如果直接将这样的数据上传到APP,用户看着并不直观,就好比我告诉你,这杯水还有几厘米,你觉得你看得懂吗?因此,我们可以用百分比这样的书来表示水位,(比如说:还剩50厘米的水,而忙的状态是100厘米,那么就相当于50%),但在这里就牵扯到了一个算法的问题了,楼主也是苦思冥想才想出了这么一个算法:比如说水满时高度是100厘米,那么就用100厘米减去超声波测得的值从而得到当前剩下的水,在用这个值除以1,注意,重点来了,是除以1而不是除100,那么就可以得出了当前剩下的水的百分比了。代码为:((value-cs)/(value/100))其中value为水满时的高度(单位是厘米),cs是超声波测得的值,至于最后为啥要除100,你们用计算器算一下就知道了。
最后是代码:
  1. #define BLINKER_WIFI
  2. #include <Ticker.h>
  3. #include <Blinker.h>
  4. #include<stdio.h>
  5. char auth[] = "4ec1296200ff";
  6. char ssid[] = "XTX";
  7. char pswd[] = "13510531949lc";
  8. Ticker tickerSetHigh;
  9. // 新建组件对象
  10. BlinkerNumber Number1("num-a");
  11. BlinkerNumber Number2("num-cm");
  12. BlinkerButton Button1("btn-if");
  13. BlinkerButton Button2("btn-beep");
  14. BlinkerSlider Slider1("ran-sw");
  15. const int trigPin = D1;  //D4
  16. const int echoPin = D2;  //D3

  17. // defines variables
  18. unsigned int duration;
  19. unsigned int distance;
  20. unsigned int ion;
  21. unsigned int sw_max=100;
  22. void button1_callback(const String & state)
  23. {
  24.   BLINKER_LOG("get button state: ", state);
  25.   cs_start();
  26.   duration = pulseIn(echoPin, HIGH);
  27.   distance = duration * 0.034 / 2;
  28.   ion = distance;
  29.   if (distance > sw_max)
  30.   {
  31.     Number1.print(0);
  32.     Number2.print(0);
  33.   }
  34.   else
  35.   {
  36.     switch (sw_max)
  37.     {
  38.       case (100): Number1.print((sw_max - distance)/1); break;
  39.       case (200): Number1.print((sw_max - distance)/2); break;
  40.       case (300): Number1.print((sw_max - distance)/3); break;
  41.       case (400): Number1.print((sw_max - distance)/4); break;
  42.       case (500): Number1.print((sw_max - distance)/5); break;
  43.       case (600): Number1.print((sw_max - distance)/6); break;
  44.       case (700): Number1.print((sw_max - distance)/7); break;
  45.     }
  46.     //Number1.print(distance);
  47.     Number2.print(ion);
  48.   }
  49. }
  50. void button2_beep(const String & state)
  51. {
  52.   BLINKER_LOG("get button state: ", state);
  53.   if (state == "on")
  54.   {
  55.     digitalWrite(D5, 0);
  56.     Button2.print("on");
  57.   }
  58.   else if (state == "off")
  59.   {
  60.     digitalWrite(D5, 1);
  61.     Button2.print("off");
  62.   }
  63. }
  64. void slider1_if(int32_t value)
  65. {
  66.   BLINKER_LOG("get slider state: ", value);
  67.   //sw_max=sw_max*100;
  68.   switch (value)
  69.   {
  70.     case (1): sw_max = 100; break;
  71.     case (2): sw_max = 200; break;
  72.     case (3): sw_max = 300; break;
  73.     case (4): sw_max = 400; break;
  74.     case (5): sw_max = 500; break;
  75.     case (6): sw_max = 600; break;
  76.     case (7): sw_max = 700; break;
  77.   }
  78.   //sw_max=value;
  79. }
  80. void setup() {
  81.   pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  82.   pinMode(echoPin, INPUT); // Sets the echoPin as an Input
  83.   pinMode(D5, OUTPUT);
  84.   digitalWrite(trigPin, LOW);
  85.   digitalWrite(D5, 1);
  86.   Serial.begin(115200);
  87.   BLINKER_DEBUG.stream(Serial);
  88.   BLINKER_DEBUG.debugAll();
  89.   Blinker.begin(auth, ssid, pswd);
  90.   Button1.attach(button1_callback);
  91.   Button2.attach(button2_beep);
  92.   Slider1.attach(slider1_if);
  93.   tickerSetHigh.attach_ms(1, setpin);//给看门狗喂狗,这个一定要,不然会复位!
  94. }

  95. void loop() {
  96.   Blinker.run();
  97.   //delay(10000);
  98.   //delay(10000);
  99.   //delay(10000);
  100.   //delay(10000);
  101. }
  102. void cs_start()
  103. {
  104.   digitalWrite(trigPin, HIGH);
  105.   delayMicroseconds(10);
  106.   digitalWrite(trigPin, LOW);
  107. }
  108. void setpin()
  109. {
  110.   ESP.wdtFeed();
  111. }
复制代码
这里我懒得注释了,有啥问题直接回复!
效果图:

微信图片_20220206141804_爱奇艺.jpg
发表于 2022-2-7 13:22 | 显示全部楼层
这个挺实用
发表于 2022-3-15 21:57 | 显示全部楼层
如果是让超声波一直处于检测状态,就是不通过按键更新状态,应该怎么搞呀,弄了几次还是不行,大佬求帮助
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-12-1 07:06 , Processed in 0.079574 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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