查看: 879|回复: 7

[分享] 点灯加持!3天DIY一套智能灌溉系统(补图)

[复制链接]

该用户从未签到

发表于 2021-4-1 10:28 | 显示全部楼层 |阅读模式
本帖最后由 Cp0204 于 2021-4-1 11:06 编辑

大概是大一放暑假,因为在宿舍养了一棵多肉,第一次萌生了希望有一套自动浇水的装置的想法,当时也只是想想。

在事隔若干年后,因为做菜的葱蒜总是用不完,在窗边弄了两个泡沫箱种着,又因为懒得浇水,试着就把智能灌溉系统给实现了。

整套系统基于 arduino,结合 点灯·blinker 的平台加持,实现在线控制和数据显示,好处是编程简单、模块丰富,控制电路图如下:


image1.png

目录
一、第一天
  1.1 硬件准备
  1.2 软件准备
二、第二天
  2.1 设计一个浇水按钮
  2.2 设置自动浇水开关
  2.3 显示实时湿度和历史图表
三、第三天
  3.1 实物连接
  3.2 设备外壳
  3.3 湿度传感器
后记


一、第一天

1.1 硬件准备

买材料,等快递,完。

板子我用的是 D1 mini,优点是小巧,带ESP8266芯片,可以物联网。

其它主要部件有:土壤湿度传感器、5V一路继电器、小水泵、配套水管。

零散的部件:杜邦线、micro数据线(旧安卓数据线,用于D1板子烧录和供电)、废旧塑料瓶等…

image2.png
主控板子

image3.png
土壤湿度传感器

image4.png
电磁继电器

image5.png
水泵和管子
1.2 软件准备

下载并安装 Arduino IDE,安装开发版的库(具体操作自行搜)。实际上程序我也是第一天写好的,实现自动浇水的关键代码(篇幅有限,只给出关键代码,需融会贯通,下同)
  1. // 设置湿度临界值
  2. int auto_moisture = 100;

  3. void setup() {
  4.   // D1 控制继电器
  5.   pinMode(D1, OUTPUT);
  6.   // A0 读取湿度
  7.   pinMode(A0, INPUT);
  8. }

  9. void loop() {
  10.   // 读取湿度模拟值,转化成表现值
  11.   int moisture = 1024 - analogRead(A0);
  12.   // 如果湿度小于阈值则启动水泵
  13.   if (moisture != 0 && moisture < auto_moisture) {
  14.     digitalWrite(D1, HIGH);
  15.     // 浇水持续时间
  16.     delay(5000);
  17.     digitalWrite(D1, LOW);
  18.   }
  19. }
复制代码

以上代码从A0口读取土壤湿度传感器的模拟值,根据设定阈值,自动启动水泵浇水的过程。

注意这里读取的并不是真正的湿度值,而是 0~1024 范围的模拟电信号,湿度越大值越小;我为了更易于人类理解,把它和1024相减,使湿度越大表现值越大。

二、第二天

以上代码实现了本地控制,但我们肯定不满足于此。下一步是试其联网,远程控制、在线显示数据,这也是我用带WIFI板子的目的。物联网部分,我使用 blinker 的方案。

blinker 是一套物联网设备开发部署方案,核心是制定了设备和设备间、设备和客户端间通信及交互标准。用户可自己拖拽布局设备控制界面,自由打造你的物联网设备。


官网文档:https://diandeng.tech/doc/getting-start-8266

下载安装 blinker APP,新建设备,获取秘钥。IDE 安装 blinker Arduino 库,示例代码,配置WIFI、秘钥,这些官网文档都有,不赘述。

2.1 设计一个浇水按钮

APP 中新建一个按钮,数据健名「btn-water」;新建一个数据控件,键名「num-water」。

image6.jpeg
添加浇水按钮

结合以下代码,就能在自动浇水的基础上,实现远程手动浇水的功能。按一下开关水泵启动 5 秒,如果管子较长,这个值可以稍微设大一些。浇水完成后计数器 +1 并返回浇水的次数。
  1. #define BLINKER_WIFI
  2. #include <Blinker.h>

  3. char auth[] = "你的token";
  4. char ssid[] = "热点名";
  5. char pswd[] = "热点密码";

  6. // 新建组件对象
  7. BlinkerButton BtnWater("btn-water");
  8. BlinkerNumber NumWater("num-water");

  9. // 手动浇水计数
  10. int counter = 0;
  11. // 设置湿度临界值
  12. int auto_moisture = 100;

  13. void setup() {
  14.   // D1 控制继电器
  15.   pinMode(D1, OUTPUT);
  16.   // A0 读取湿度
  17.   pinMode(A0, INPUT);
  18.   // 初始化 blinker
  19.   Blinker.begin(auth, ssid, pswd);
  20.   // 绑定按钮事件
  21.   BtnWater.attach(BtnWater_callback);
  22. }

  23. void loop() {
  24.   Blinker.run();
  25.   // 读取湿度模拟值,转化成表现值
  26.   int moisture = 1024 - analogRead(A0);
  27.   // 如果湿度小于阈值则启动水泵
  28.   if (moisture != 0 && moisture < auto_moisture) {
  29.     digitalWrite(D1, HIGH);
  30.     // 浇水持续时间
  31.     Blinker.delay(5000);
  32.     digitalWrite(D1, LOW);
  33.   }
  34. }

  35. // 按下浇水按钮
  36. void BtnWater_callback(const String & state) {
  37.   if (state == "tap" && digitalRead(D1) == 0) {
  38.     digitalWrite(D1, HIGH);
  39.     Blinker.delay(5000);
  40.     digitalWrite(D1, LOW);
  41.     counter++;
  42.     // 发送计数
  43.     NumWater.print(counter);
  44.   }
  45. }
复制代码

2.2 设置自动浇水开关

如果我不想自动浇水,怎么办?我们可以在设置一个自动浇水开关,设置为打开时,执行检测湿度自动浇水的代码。
  1. //……此处省略部分非关键代码

  2. // 新建组件对象
  3. BlinkerButton BtnAuto("btn-auto");

  4. // 自动浇水默认开关
  5. bool auto_water = false;

  6. //……此处省略部分非关键代码

  7. void loop() {
  8.   Blinker.run();
  9.   // 读取湿度模拟值,转化成表现值
  10.   int moisture = 1024 - analogRead(A0);
  11.   // 如果湿度小于阈值则启动水泵
  12.   if (auto_water && moisture != 0 && moisture < auto_moisture) {
  13.     digitalWrite(D1, HIGH);
  14.     // 浇水持续时间
  15.     Blinker.delay(5000);
  16.     digitalWrite(D1, LOW);
  17. }

  18. // 自动浇水开关
  19. void BtnAuto_callback(const String & state) {
  20.   if (state == "on") {
  21.     auto_water = true;
  22.   } else {
  23.     auto_water = false;
  24.   }
  25. }
复制代码

2.3 显示实时湿度和历史图表

怎样湿度实时显示在 APP 上呢?方法和 2.1 中显示计数是一样的,APP中新建数据控件,代码中绑定控件。
  1. //……此处省略部分非关键代码

  2. // 新建组件对象
  3. BlinkerNumber NumMoisture("num-moisture");

  4. void setup() {
  5.   //……此处省略部分非关键代码

  6.   // 历史数据图表
  7.   // Blinker.attachDataStorage(func, time, times);
  8.   // func, 对应的回调函数
  9.   // time, 对应数据采集时间-默认60 s, 最少60 s
  10.   // times, 对应采集次数后上传到云端-默认2次, 最多不超过4次
  11.   Blinker.attachDataStorage(dataStorage, 60 , 2);
  12. }

  13. // 设备需要上传数据到云端时会调用对应的回调函数
  14. void dataStorage() {
  15.   int moisture = 1024 - analogRead(MOIST);
  16.   Blinker.dataStorage("moisture", moisture);
  17. }
复制代码

但这里我们还需要加入心跳包,以便在一打开设备页面的时候就返回数据,后面每 30~60s 会定期返回一次心跳包。
  1. void setup() {
  2.   //……此处省略部分非关键代码

  3.   // 心跳绑定
  4.   Blinker.attachHeartbeat(heartbeat);
  5. }

  6. // 发送实时数据
  7. void heartbeat() {
  8.   NumMoisture.print(1024 - analogRead(MOIST));
  9.   // 以下是返回开关状态
  10.   btnSwitch(BtnAuto, STRING_format(auto_water ? "on" : "off"));
  11. }
复制代码


三、第三天

3.1 实物连接

下面是我制作实物的一些经验。把基本部件按以下线路连接,另外我们还需要储水罐、防水外壳。我用的是潜水泵,放到储水罐中,出水口连接软管到植物处。


3.2 设备外壳

整套装置我是打算放在窗台外的,所以必须考虑防水,外壳我用一个饮料瓶倒立放置。把元件全塞进去,娃哈哈某款饮料瓶口刚刚好。

image7.jpeg

瓶盖打三个孔,孔直径等于线的直径,引出三根导,分别是主板电源线、湿度传感器导线、水泵电源线。

image8.jpeg


3.3 湿度传感器

湿度传感器插针和导线焊接,用热缩管做最后的包裹。

image9.jpeg

这里我的经验之谈是做滴蜡处理,防止洒水的时候渗入到插针处,造成传感器不准。

后记

最后成品的效果,我把装置固定在窗边,用快递袋包裹遮太阳,从窗边引入一根电源线到室内接电源,储水罐用坏了的烧水壶。

image10.jpeg

手机控制端,当然后面程序上还做了一些升级优化,比如湿度数值取平均数,防止某一次取值偏差,增加浇水微信通知之类的。

image11.jpeg


整套东西做好了有一段时间,这篇文章陆陆续续写了快四个月。

再次证明了「一鼓作气,再而衰,三而竭」,以至于后面有些细节忘了,代码也是从最终版本中抠出来简化的,有 bug 别怪我 ╮( ̄▽ ̄)╭ ,如果有朋友需要可以完整开源,但我希望你有一点基础,有排错的能力。

感谢点灯提供的平台和库,让物联网开发变得简单、便捷!后面我还做了同时支持APP、天猫精灵、小爱同学(我用小米手环4)控制的氛围彩灯,支持不同闪动模式,后续希望加入读AUX音频信号,随音乐节奏跳动,但也一直拖着没动,有能力和兴趣的朋友可以一起探讨完善。

对了,还有舵机+激光逗猫的玩具,可是没有猫。

Made with love, just for fun!

未经许可禁止转载。

签到天数: 66 天

[LV.6]常住居民II

发表于 2021-4-2 08:21 | 显示全部楼层
硬件放在瓶子内,放在户外   瓶内是否有水气产生?

该用户从未签到

 楼主| 发表于 2021-4-2 08:29 | 显示全部楼层
ahua7336 发表于 2021-4-2 08:21
硬件放在瓶子内,放在户外   瓶内是否有水气产生?

没有水气,瓶子是密封的,电源线从刚刚好的圆孔通过(封蜡)。再加上是倒着放置,雨水都打不进去,没有涉水的机会。
另外我在外面又包了一层快递袋,以免阳光直晒。

签到天数: 1 天

[LV.1]初来乍到

发表于 2021-4-2 15:58 来自手机 | 显示全部楼层
你好,我是新手小白,对这个项目挺感兴趣的,想问一下为啥开发板连上WiFi但是app里面显示离线呢?

该用户从未签到

 楼主| 发表于 2021-4-6 01:30 | 显示全部楼层
taograndpa 发表于 2021-4-2 15:58
你好,我是新手小白,对这个项目挺感兴趣的,想问一下为啥开发板连上WiFi但是app里面显示离线呢? ...

库没配置好吧

该用户从未签到

发表于 2021-4-14 17:17 | 显示全部楼层
新手小白,问一下。我做的也有浇水方面的。我的连线也是按照楼主的连接。但是代码写进去以后,水泵一直在工作,我想问下是哪里的问题。是不是继电器的问题,我用的是蓝色的普通的继电器。求解答。感谢,大佬。

该用户从未签到

 楼主| 发表于 2021-4-15 08:58 | 显示全部楼层
你猜我是谁啊 发表于 2021-4-14 17:17
新手小白,问一下。我做的也有浇水方面的。我的连线也是按照楼主的连接。但是代码写进去以后,水泵一直在工 ...

仅有的信息无法判断,贴代码,看实物;

该用户从未签到

发表于 2021-4-15 14:25 | 显示全部楼层
本帖最后由 你猜我是谁啊 于 2021-4-15 14:29 编辑

老哥你好,我是在你帖子下面留言的。实物方面我的继电器用的蓝色的普通的继电器。接线方面,继电器的vcc接的板子的5v,gnd接的板子的gnd,in接的是D13口,继电器的com接的是5v。水泵方面,黑色的线接的是gnd,红色的线接的是继电器的nc。代码我就是用的你的代码。除了数据口其他都没有改变。blinker方面 组件也是用的代码的数据键名。问题是这样的,我板子接通电源以后水泵一直在工作,并且继电器的绿灯也一直在跳动,有声音。而且当我的湿度,超过湿度临界值的时候,也是会在工作,手动浇水的按钮也没有用。所以我想问下,我这是哪里的问题?还请大神指导一下。感谢。我已经上传了我的接线图,视频方面我传不上去,所以无法呈现,抱歉。C:\Users\Administrator\Desktop
QQ图片20210415142452.jpg
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

arduino程序设计基础 blinker物联网解决方案

热门推荐

【分享】esp8266/32 炫彩LED氛围灯
【分享】esp8266/32 炫彩L
[md]# esp8266/32 炫彩LED氛围灯 - 作者:pengqiangsheng - 说明:基于太极创客智能
ESP32-CAM 推流直播【分享】
ESP32-CAM 推流直播【分享
# ESP32-CAM 推流直播 > 使用esp32-cam进行实时录像,然后通过obs推流到虎牙直播。
DS18B20温度传感器,资料分享
DS18B20温度传感器,资料
DS18B20温度传感器,需要资料的可以留下联系方式。
【分享】esp8266/32 网站快速生成器脚手架和mqtt web客户端
【分享】esp8266/32 网站
一、mqtt web客户端 先来分享一下mqtt web客户端吧: 下载后就解压里面有两个文件:
教你让OLED动起来!多重字符串版!
教你让OLED动起来!多重字
大家都知道:arduino单片机是单线程的 而上次教程中的多段字符串的运行速度必须一致
Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
快速回复 返回顶部 返回列表