基于树莓派的自动灌溉系统
相比大家都有这样的经验,每逢佳节回家或是旅游,如果家里没有动植物还好,有了动植物就会头疼喂食和浇水等一系列问题,以下就是我设计的项目,可以做到自动灌溉的功能,完美解决我的痛点。
零件清单:
Arduino
电容式土壤湿度传感器
DHT22
液晶屏
3x 5V 泵
螺丝端子
USB电源
12V泵
12V电源
4x MOSFET
管道
Raspberry Pi Zero W. 控制灯和雾生成器
树莓派零 W
3x 光耦
3x 小 LED
生长灯
造雾机
树莓派 3B+
树莓派 3B+
3x 低分辨率相机
1x 高分辨率相机
其他有用的工具和组件
母接头排
电线
面包板
卷边工具
剥线工具
连接器外壳
公/母连接器触点
USB充电器
第 1 步:考虑的替代方案
全自动系统可以工作。例如,如果我有一个基于计时器的系统,它会每天或每周打开浇水两次,那么,如果托盘中的水蒸发得不够快,它就会越过边缘并落在镶木地板上。当我在家时,我们有阳光明媚的日子,水蒸发得很快,但是当我旅行时-天气寒冷多雨。水蒸发得慢得多。因此,我基于计时器的方法可能会使我的公寓变得一团糟。
另一种方法是基于测量土壤湿度. 当土壤不够潮湿时 - 只需触发浇水。几年前,我使用基于电阻的土壤湿度传感器。事实证明,如果你不断让这样的传感器通电,就会发生电解,传感器的一个金属“腿”会溶解在土壤中,这不仅对食肉植物有毒,而且对其他植物也有毒好。这就是我决定使用电容式土壤湿度传感器的原因。天真的用法是提出阈值,之后应该触发浇水。事实证明,传感器的测量结果不仅取决于土壤的湿度,还取决于空气的温度和湿度。提出估计土壤水分实际水平的公式可能是一个涉及一些数学和统计的有趣项目。
另一个问题是测量的分辨率。虽然昂贵的传感器给出的值介于 460(湿土)和 520(干土)之间,但更便宜的传感器能够给出 236(湿土)和 253(干土)之间的值。如上所述,温度波动增加了更多的不确定性:
7:00 时,温度 = 23C,土壤湿度 = 238
11:00 时,温度 = 29C,土壤湿度 = 246
19:00 时,温度 = 25C,土壤湿度 = 241
这就是为什么基于土壤湿度传感器测量的全自动系统并不是这么好用
第 2 步:最终方案
我想获得半自动化系统,在那里我可以从传感器获取所有读数,但只有在我绝对确定它是安全且需要时才打开浇水。与Arduino类似,有一些更便宜的板子能够为简单的 http 服务器提供服务或发出 http 请求。但我想要更灵活的东西。ssh 是我所知道的最好的界面。据我所知,能够提供 ssh 访问权限的最简单的板是Raspberry Pi Zero W。因此,该板应负责收集测量值和控制泵。还有一个造雾器和越来越多的灯。
另一方面,我想看看发生了什么。为了确保控制电路不会阻塞我的观看系统,我决定使用另一个RaspberryPi(功能稍强)来捕捉正在发生的事情的视频。这应该是一个独立的控制器,能够报告实际发生的事情。
在紧急情况下,我希望能够切断泵的电源。有一个简单且可靠的解决方案——WiFi电源插座。我已将它添加到系统中,以确保我可以通过一个独立的界面停止一切。有了其他树莓派系统,我可以把它放在单独的电源线上,这样我就可以在断电后继续观察周围的情况。
这些是系统的三个主要部分:
控制系统,能够收集传感器信息并控制泵
手表系统,能够对周围环境进行可视化报告。
紧急情况,第三方切断控制系统。
第 3 步:浇水功能
我从我最了解的部分开始 - 使用泵。可以通过将泵直接连接到Raspberry Pi或Arduino 的数字输出引脚来驱动泵。但它们提供的功率并不大,而且通常在所有引脚之间共享。因此,如果我尝试使用多个传感器或执行器(泵或屏幕),那么每个传感器的功率都会降低。这就是为什么我决定使用 Arduino 入门项目中描述的技巧 - 使用 MOSFET 让来自Raspberry的逻辑引脚控制泵的更高功率连接。正如我从这个实验中了解到的- MOSFET不能从Raspberry Pi 板上轻松控制,因为 MOSFET 仅在其栅极引脚施加 ~5V 时触发,而 Raspberry Pi 的逻辑引脚上只有 3.3V。所以我不得不使用 Arduino 来控制泵。使用 3 个 MOSFET、一堆电线和连接器,我能够为三个更便宜的泵构建第一个驱动器。它使用外部 5V USB 充电器作为泵的电源。
经过一些实验,结果证明,更便宜的泵能够将水提升到 60 厘米以上。我希望植物能得到尽可能多的阳光,所以我想把它们放在窗台的水平上。我还想要 3 桶蒸馏水,每桶 5 升,作为供应。我无法将它们安装在离植物足够近的地方,所以我必须在主供应上方和植物下方安装一个中间容器,以便能够使用更便宜的泵。
这就是为什么我必须再构建一个带有 12V 电源的驱动器和一个 MOSFET。
Arduino 能够从串行端口接收命令,打开和关闭泵,并通过串行端口报告其状态。命令示例:“pump 2 5”,其中pump是打开泵的命令,采用两个参数:第一个(在本例中为 2)是 id 1..4,指示应该触发的泵;第二个参数是以秒为单位的持续时间,在此期间应该打开泵。此持续时间限制为值 1 到 15,因此在超过 15 秒的时间段内没有打开任何泵。为了完全填满托盘,我通常不得不在 15 秒内触发两次相应的泵。
第 4 步:传感器
我想监测植物周围的状况,为此我使用了简单的 DHT-22 传感器来收集温度和湿度测量值。我还使用电容式土壤湿度传感器来检查猪笼草是否有足够的水。对于托盘,我不想使用任何类型的侵入式传感器来避免在蒸馏水中添加任何数量的金属。
Arduino能够从这些传感器收集测量值,并使用串行端口响应命令“stats”报告它们的值。示例输出:
潮湿:240
噪声:58
温度:26.5
第 5 步:烟雾制造器
光和雾制造器由简单的硬件按钮控制。根据 Arduino starters book 的另一课,可以使用光耦合器以编程方式“单击”这些按钮。现在,当我为我的自动沼泽花园特意购买了灯和喷雾器时,我终于有机会破解硬件按钮了。与MOSFET不同,光耦合器可以使用 3.3V 信号,因此可以直接从 Raspberry Pi 控制它们。
使用四个光耦合器、四个小 LED 以及一堆电线和连接器,我能够构建一个 4 软件按钮驱动程序,它可以从 Raspberry Pi 进行操作。LED 是可选的,我用它们来确保来自 Raspberry Pi 的信号确实到达驱动板。
要“单击”来自 Raspberry Pi Zero W 的按钮,我们可以使用这样的代码:
from gpiozero import LED button = LED(17) button.on() |
第 6 步:监视系统
Raspberry Pi 3B+ 有4个大USB连接器。这些可用于插入网络摄像头。我购买了3台小型廉价摄像机,结果非常糟糕。但是他们可以检查主水箱或造雾器杯中的水位等小事。我还购买了一台能够制作高清视频的更好的网络摄像头。它的图像质量并不是非常优秀,但比制造的廉价摄像机要好得多,而且足以了解植物的整体状况。
要实际处理视频,可以使用ffmpeg-server工具,或单独的RED5 rtmp服务器。我两个都试过了,但似乎 Raspberry Pi 无法即时转码高清视频,所以我最多只能获得 5 fps 的视频。此外,我无法达到“实时”流的延迟少于 15 秒。这两个事实都促使我走向另一个解决方案。
我决定一个简单的 HTTPS 服务器,能够枚举 Raspberry Pi 上的视频设备,并从选定的视频设备传送单帧,就足够了。例如,向植物托盘加水的简单程序如下所示:
拍一张托盘和主水箱的照片。目视确保托盘中没有足够的水,并且主水箱中有足够的水。
要求托盘泵工作 15 秒。
再拍一张照片,以确保水已成功添加到托盘中。
如果主水箱中没有足够的水 - 在重新填充托盘之前,将水从供水系统添加到水箱中。
为了将相机放置在合适的位置,我使用了当地建筑市场上的木棍,安装在作为底座的矩形木块上。我使用自攻螺钉将棒和木底座连接在一起。学习使用自攻螺钉的一个很好的教训是,在拧紧螺钉之前应该先打一个孔。否则,棍子会破裂。
后来我发现可以使用 ESP32-CAM 设备,它提供了很好的实时视频流。我还没有尝试将它用于实际项目,但它似乎是一个有希望的方向。
要从连接的 USB 相机拍照,我使用了这个 ffmpeg 命令:
ffmpeg -i /dev/video0 -vframes 1 photo.jpg |
所有摄像机都可以在偶数 ID 下使用,如 /dev/video{0 2 4 6}。
第七步:使用 UART 连接 Raspberry Pi 和 Arduino
在我旅行期间,我可以通过 ssh 或使用 https 访问 Raspberry Pi。有关周围条件和泵控制的数据基于 Arduino。为了能够从 Raspberry Pi 与 Arduino 通信,我决定使用串行端口。
Arduino 和 Raspberry Pi 都能够使用其他协议进行通信 - SPI 和 I2C。但它们在不同的电压下运行 - 5V 和 3.3V。事实证明,我用于 UART 协议的简单电平转换器不适用于 I2C。
确保将两块板上的TX连接到标识为 RXI 或 TXI(可能尾随的“I”代表输入)的引脚,并将RX 连接至 RXO 或 TXO(相同,可能尾随的“O”代表输出)。
Arduino
从 Arduino 方面来看,一切都很简单:
void setup() { Serial.begin(9600); // To initialize communication } void loop() { if(Serial.available()) { String command = Serial.readStringUntil("\n"); // To read an incoming command Serial.println("OK"); // Respond with "OK\n" as soon as possible to notify // sender that the command is received. Serial.print("your command was: "); Serial.println(command); // Echo command back. Serial.println("DONE\n"); // Respond with "DONE\n" on a separate line to notify // sender that the command execution is complete and // Arduino is ready to receive new commands. } delay(100); } |
这里我们使用了Serial库提供的三个非常不错的函数:
Serial.readStringUntil("\n") 允许我们有一个协议,它通过行尾符号将字节流拆分为命令。这样的协议可以通过 Arduino Monitor 工具(Arduino IDE 中的 Ctrl+M)轻松测试。
Serial.print(string) 将字符串发送到另一端,但不会以“\n”符号结束它。这允许我们在准备好后立即发送多个响应。
Serial.println(string) 完成单行数据的发送。
在将 Arduino 连接到 Raspberry Pi 之前,请确保您没有通过 USB 连接其他串行协议客户端。例如,避免通过 USB 端口直接从您的计算机为 Arduino 供电。另一方面,您可以通过 5V USB 充电器为其供电。就我而言,我直接从 Raspberry Pi 为 Arduino 供电,而 Raspberry Pi 又连接到简单的 USB 充电器。
树莓派
默认情况下,Raspberry Pi 上禁用串行接口。使用 raspi-config 工具在“ Interfaces > Serial Port ”下启用它。
如果应通过串行端口启用登录 -否
如果应该启用串行端口 -是
现在,将 Arduino 连接到 Raspberry Pi 后,可以向 Arduino 发送命令并接收响应:
import serial ser = serial.Serial("/dev/serial0" 9600 timeout = 2.0) # Initialize connection response = ser.read_until("\n".encode()) # Arduino should respond with OK as soon |
协议详情
所有传入的命令都是以“\n”结尾的一行。命令名及其参数用空格分隔。示例:“pump 2 15\n” 命令名称为“pump”,参数为“2”和“15”。
Arduino 总是在收到新命令后尽快回复“OK\r\n”。然后它可以输出命令调用的结果。Arduino 可以通过向 Raspberry Pi 发送“DONE\r\n”来通知命令已完成调用。
第 8 步:定制电线
在原型设计时,我曾经让所有传感器和微控制器彼此靠近。在这种情况下,20 厘米的原型线工作得很好。但是在真正的园艺项目中,我发现执行器和传感器的位置要远得多。一开始我只是连接这些较短的电线链以获得更长的电线。但通常我会失去颜色编码优势,因为我没有那么多用于电源的红色/黑色电线和用于不同信号的绿色/白色/蓝色/黄色电线。
后来我购买了一大堆彩虹线,并在需要时开始切割所需长度和颜色的线。另一个有用的东西是压接工具,它允许我制作自己的原型线。这让我可以随时组装和重新组装我的系统,或者在桌子周围移动不同的部件。这不需要我焊接或重新焊接连接。
第 9 步:测试系统
在通过ssh和https与我的花园远程工作一段时间后,我认为与它交谈会很棒。使用诸如 discord 之类的聊天应用程序可以让我连续获取照片和文本消息,而不仅仅是图片或状态页面的单一视图。它还可以让我记录特定时间系统中发生的事情。
第 10 步:数据分析
我每 10 分钟测量一次湿度、温度和猪笼草土壤水分含量。我已将此数据以 SQL 插入格式写入日志文件:
INSERT INTO humidity VALUES ('2021-08-02T22:13:33' 58); INSERT INTO temperature VALUES ('2021-08-02T22:13:33' 27.5); INSERT INTO moisture VALUES ('2021-08-02T22:13:33' 245); |
这些数据稍后可以导入到某个数据库中。为了绘制数据,我使用了 Grafana。应该可以在共享图表上显示具有不同测量单位的两个数据集,但是这个功能对我来说有问题,所以我不得不创建三个不同的图表。
无论如何,从这张图表中我了解到土壤湿度读数与公寓温度之间的相关性。如果我决定实施警报系统,这可能很重要。阈值不仅取决于土壤湿度传感器的值,还取决于当时的温度。
第 11 步:组装
拥有具有ssh访问权限的计算机被证明是一个非常灵活的工具。在这种情况下,Arduino 似乎是一个可分离的、低成本的工人。将任何沉重的逻辑放入其中似乎不太灵活。它应该能够为任何工作采用足够的参数,而Raspberry实际上可以决定应该做什么以及如何做。它也可以是一个不错的传感器信息收集器。
以上就是我项目的全部内容,希望您能喜欢。
- END -