|
本帖最后由 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,你们用计算器算一下就知道了。
最后是代码:
- #define BLINKER_WIFI
- #include <Ticker.h>
- #include <Blinker.h>
- #include<stdio.h>
- char auth[] = "4ec1296200ff";
- char ssid[] = "XTX";
- char pswd[] = "13510531949lc";
- Ticker tickerSetHigh;
- // 新建组件对象
- BlinkerNumber Number1("num-a");
- BlinkerNumber Number2("num-cm");
- BlinkerButton Button1("btn-if");
- BlinkerButton Button2("btn-beep");
- BlinkerSlider Slider1("ran-sw");
- const int trigPin = D1; //D4
- const int echoPin = D2; //D3
- // defines variables
- unsigned int duration;
- unsigned int distance;
- unsigned int ion;
- unsigned int sw_max=100;
- void button1_callback(const String & state)
- {
- BLINKER_LOG("get button state: ", state);
- cs_start();
- duration = pulseIn(echoPin, HIGH);
- distance = duration * 0.034 / 2;
- ion = distance;
- if (distance > sw_max)
- {
- Number1.print(0);
- Number2.print(0);
- }
- else
- {
- switch (sw_max)
- {
- case (100): Number1.print((sw_max - distance)/1); break;
- case (200): Number1.print((sw_max - distance)/2); break;
- case (300): Number1.print((sw_max - distance)/3); break;
- case (400): Number1.print((sw_max - distance)/4); break;
- case (500): Number1.print((sw_max - distance)/5); break;
- case (600): Number1.print((sw_max - distance)/6); break;
- case (700): Number1.print((sw_max - distance)/7); break;
- }
- //Number1.print(distance);
- Number2.print(ion);
- }
- }
- void button2_beep(const String & state)
- {
- BLINKER_LOG("get button state: ", state);
- if (state == "on")
- {
- digitalWrite(D5, 0);
- Button2.print("on");
- }
- else if (state == "off")
- {
- digitalWrite(D5, 1);
- Button2.print("off");
- }
- }
- void slider1_if(int32_t value)
- {
- BLINKER_LOG("get slider state: ", value);
- //sw_max=sw_max*100;
- switch (value)
- {
- case (1): sw_max = 100; break;
- case (2): sw_max = 200; break;
- case (3): sw_max = 300; break;
- case (4): sw_max = 400; break;
- case (5): sw_max = 500; break;
- case (6): sw_max = 600; break;
- case (7): sw_max = 700; break;
- }
- //sw_max=value;
- }
- void setup() {
- pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
- pinMode(echoPin, INPUT); // Sets the echoPin as an Input
- pinMode(D5, OUTPUT);
- digitalWrite(trigPin, LOW);
- digitalWrite(D5, 1);
- Serial.begin(115200);
- BLINKER_DEBUG.stream(Serial);
- BLINKER_DEBUG.debugAll();
- Blinker.begin(auth, ssid, pswd);
- Button1.attach(button1_callback);
- Button2.attach(button2_beep);
- Slider1.attach(slider1_if);
- tickerSetHigh.attach_ms(1, setpin);//给看门狗喂狗,这个一定要,不然会复位!
- }
- void loop() {
- Blinker.run();
- //delay(10000);
- //delay(10000);
- //delay(10000);
- //delay(10000);
- }
- void cs_start()
- {
- digitalWrite(trigPin, HIGH);
- delayMicroseconds(10);
- digitalWrite(trigPin, LOW);
- }
- void setpin()
- {
- ESP.wdtFeed();
- }
复制代码 这里我懒得注释了,有啥问题直接回复!
效果图:
|
-
|