GreenPiThumb: A Raspberry Pi Gardening Bot

Michael Lynch

GreenPiThumb:基于树莓派的智能浇花机器人

原文由 Michael Lynch 发布,订阅该博客

引言

这是 GreenPiThumb 的故事:一款能自动给室内植物浇水的园艺机器人,只不过有时候也会把植物浇死。

GreenPiThumb 完整系统

故事始于大约一年前,我突然很想养一盆室内植物。养盆植物看起来不错,能给我提供急需的氧气,还能让来做客的人觉得我是个靠得住的成年人,有能力照顾一个生命。

但我是个程序员,不是园丁。养了植物,就得每周浇几次水、检查几次长势。我想,与其这样,不如花上几百个小时做个机器人来替我干这些活。如果这盆植物能活到 80 岁,那我还算略有赚头。

为什么要做 GreenPiThumb?

和我做过的大多数软件项目一样,做 GreenPiThumb 的主要动机是学习新技术。我之前写过一个应用 ProsperBot,借此自学了 Go、Ansible 和 Redis。我把 GreenPiThumb 当作学习前端开发的机会,尤其是 JavaScript 和 AngularJS。

我的朋友 Jeet 刚开始学编程,于是我问他有没有兴趣一起合作做 GreenPiThumb。对他来说,这似乎是个学习健康软件工程实践的好机会,比如代码审查、单元测试和持续集成。Jeet 欣然同意,于是我们踏上了这段原本以为两三个月就能完成的工作。

树莓派加持

树莓派是一款面向爱好者的小型廉价电脑。人们用树莓派打造过充满未来感的智能镜子运行怀旧游戏,还驱动过电动滑板

树莓派

过去几年我一直在玩树莓派,但我毕竟是做软件的,所以除了把它当成廉价的玩具服务器之外,从来没干过别的。对于大多数爱好者来说,树莓派最大的吸引力在于它能很好地与各种电子元件集成。

树莓派拥有丰富的传感器和集成教程,自然成了 GreenPiThumb 的理想选择。我想,用树莓派也能逼自己去学习它的硬件能力,终于搞明白那些“GPIO 引脚”到底是干什么的。

MOSFET 熔化面包板

树莓派和它神秘的 GPIO 引脚

为什么还要再做一个树莓派园艺机器人?

我们当然不是第一批想到要做树莓派园艺机器人的人。在我们之前就有两个很酷的项目——PiPlanterPlant Friends,此外还有不少类似的尝试。

我们决定自己再做一个,原因有二:自己动手很有趣,而且我们想把软件质量当作头等大事来对待。

大多数树莓派项目都是由精通电子但缺乏专业软件经验的爱好者做的。我们想反其道而行之——软件要做得漂亮,至于硬件,能勉强工作就行,哪怕有时候热到把面包板都熔化了。

GPIO 引脚

一个早期原型,很可能有“着火”的风险

GreenPiThumb 的代码已开源,具备以下特性:

硬件架构

GreenPiThumb 接线图

GreenPiThumb 接线图(可下载文件

树莓派只能读取数字信号,因此无法直接读取模拟传感器。我们使用 MCP3008 模数转换器,将模拟的土壤湿度传感器和光线传感器的数据转换为数字读数。

DHT11 传感器用于检测空气的温度和湿度。它输出的是数字信号,所以可以直接接到树莓派上。

最后是12V 水泵,但树莓派只能输出 5V,所以我们把一个 12V 电源适配器与一个 MOSFET 串联后接到水泵上。树莓派把 MOSFET 当作数字开关,需要开泵或关泵时就通过它来接通或断开电路。

软件架构

GreenPiThumb 软件架构

GreenPiThumb 软件架构

GreenPiThumb 后端

后端承担了 GreenPiThumb 的核心工作。这是一个 Python 应用,负责:

  • 管理各个物理传感器(土壤湿度、温度等)
  • 控制水泵的开关
  • 在数据库中记录事件和传感器读数

GreenPiThumb Web API

Web API 是一个 HTTP 接口,用于提供 GreenPiThumb 当前状态和历史记录的信息。它是 GreenPiThumb 数据库之上的一层薄封装,把所有数据都转换成 JSON,便于 Web 应用理解和处理。

GreenPiThumb 网页仪表盘

网页仪表盘会展示 GreenPiThumb 的当前状态,并将传感器读数随时间变化绘制成图表。

GPIO 引脚

我们的树莓派还难以胜任面向公网的 Web 服务器,不过这里有一个与本地仪表盘完全一致的静态镜像:

部署

要把 GreenPiThumb 部署到树莓派设备上,我们使用 Ansible——一款开源的 IT 自动化工具。

我们为 GreenPiThumb 创建了一个定制的 GreenPiThumb Ansible 配置(按 Ansible 的说法叫“role”),用于部署 GreenPiThumb 所需的全部软件。这个 Ansible role 会下载并安装 GreenPiThumb 的后端和前端代码,以及它所依赖的第三方软件组件。

只需几条命令,你就能在一台全新的树莓派上使用这个工具,几分钟内让 GreenPiThumb 的所有软件跑起来。

一路上的坑

GreenPiThumb 花了一年多才完成,远超预期,原因是一路上遇到的各种阻碍常常让进度停滞数周。下面我来讲讲其中几个比较有意思的坑。

浇水分布

其他树莓派园艺项目都没怎么讲过怎么把水均匀地浇到土里,这很遗憾,因为我们到现在也没完全搞定这个问题。

第一次往花盆里抽水时,水管把细细的水流集中冲到一个点上,那一块土被彻底浸透,其余地方却还是干的。我们考虑过把橡胶水管沿着花盆内壁盘一圈再在管子上扎孔,但不确定这样能不能让中间的土也喝到水。我们也试过用花洒,但怎么也想不出办法既让它和水管防水连接,又能控制水流方向。

最后我们采取了“胡乱喷洒”方案。这完全是环顾公寓、随手抓来可能有用的东西拼凑出来的办法。我们从一只小厨房手套上剪下一根手指,用紧紧缠了两圈的橡皮筋把它固定在水管上,再用缝衣针和指甲剪在手套指头上扎出许多小孔。

我们打开水泵,手套的断指立刻从水管上飞了出去,把水喷得满墙都是。我们重新把它装好,这次在橡皮筋前面插了一枚别针,防止它们再向前滑脱。

分水器(正面)分水器(侧面)

用厨房手套改装的分水器

这不是最优雅的方案,但基本管用。

本以为园艺不难

GreenPiThumb 最大的挑战本该是电子部分,园艺看起来并不难。尤其是四季豆,常常被形容为一种皮实的植物,只需要基本的园艺技巧就能种好。

结果我们连基本的园艺技巧都没有。GreenPiThumb 的初衷是把照料室内花园中需要人做的部分自动化,但要自动化任何事,人首先得知道什么是“正确”的样子。我们自己都不知道该浇多少水,所以很难判断 GreenPiThumb 是浇多了还是浇少了。就这样,我们一不小心拍出了一部园艺版的“杀戮纪录片”:

测个湿度能有多难?

最让我们头疼的问题是土。

刚开始做 GreenPiThumb 时,我们以为土壤湿度会在浇水的那天上升,不浇水的日子下降。GreenPiThumb 的任务就很简单:只要读数低于某个阈值就补水,保持湿度在合适水平。

下面,我们用昂贵而复杂的建模软件来可视化一下我们当初预期的土壤湿度变化:

土壤湿度变化模式

想象中的土壤湿度变化

异常读数

土壤却完全不配合我们。在最初的版本里,土壤湿度读数在 95% 到 100% 之间来回跳动,然后慢慢收敛到约 99.5%。我们把土壤传感器拿出来,分别在不同介质上测试:空气、水、湿纸巾、手、完全干燥的土。这些情况下读数似乎都还合理,可只要是带点湿气的土壤,读数就会飙到接近 100%。

土壤湿度

原始传感器的土壤湿度读数

我们最初用的是 Dickson Chow 的 Plant Friends 土壤探针,后来换成了 SparkFun 土壤传感器。新传感器在潮湿土壤中读数为 82%,刚浇完水会跳到 85%。但几个小时后,它又会回落到 82%,并在那里保持好几天。传感器似乎无法区分三小时前刚浇过水的土壤和已经五天没浇水的土壤。

土壤湿度

SparkFun 土壤传感器的读数

我觉得我的土坏了

美乐棵营养土

也许是土的问题。我们用的盆栽土是美乐棵(Miracle-Gro)的预包装混合土,号称采用了“易浇水配方”。有点可疑,对吧?显然,这是经过邪恶基因改造、永远不会干的土。难怪我们可怜的土壤传感器会如此困惑。

我们需要不会跟我们捉迷藏的土,于是买了这种有机盆栽混合土。为了测试,我们在一个塑料杯里装满有机土,浇上水,在底部扎孔让它排水,然后静置三天,以模拟 GreenPiThumb 花盆里的土壤状态。三天后,我们在两种土里分别测试了传感器。

结果读数完全一样:都是 82%。所以,土没法背这个锅……

放弃

想不出别的办法后,我们又回头研究那些启发 GreenPiThumb 的项目。它们是怎么解决这个问题的?

Plant Friends 根本不抽水。PiPlanter 虽然会测量土壤湿度,但浇水是按固定时间表进行的,和湿度无关。我们在网上搜到几个声称完全根据土壤湿度来浇水的树莓派园艺项目,但它们既不公开源代码,也不分享结果数据。因此,我们觉得完全可以合理地认为,基于湿度来浇水是不可能的,而 GreenPiThumb 在物理世界某些不可逾越的限制下,已经做到了最好

最终我们改用了一套混合方案:只有当土壤过干或者距离上次浇水已过去七天时,GreenPiThumb 才会浇水。

最终成品

以下是我们完成的 GreenPiThumb 的一些照片:

GreenPiThumb 完整系统GreenPiThumb 完整系统
GreenPiThumb 电子部分GreenPiThumb 水泵GreenPiThumb 储水容器

延时摄影是整个过程中最有趣的部分。这段来自我们的第一批四季豆(R.I.P.)。我们没料到植物会这么快就长出俯视近景的取景范围。后来我们换成了更长、更灵活的支架,能更好地拍到植物完整生命周期的画面,不过最初的设置还是捕捉到了最初几天生长的精彩延时:

第二批我们让相机在整个生长过程中保持完全相同的位置。这是第二批到目前为止的生长情况:

经验教训

事情从来没有看起来那么简单

我本以为这会是一个两三个月就能搞定的简单项目,结果却花了一年多才完成,因为事情从来没有看起来那么简单。

这个道理我很久以前就从卓越的软件随笔作家 Joel Spolsky 那里学到过,而且我预计在今后许多软件项目中还会一次又一次地体会到它。

电子学:从基础开始

Arduino 入门套件

做 GreenPiThumb 之初,我对电子学的了解仅限于高中物理的模糊记忆。我买了 Arduino 入门套件,跟着教程一步步打下了电子学基础。

这些教程出乎意料地有趣且实用。它们从易到难,循序渐进地深入更高级的主题。我向所有对电子学感兴趣的初学者推荐这套套件。

硬件要隔离测试

和我一起做过软件项目的人曾形容我在写代码方面“吹毛求疵”或“过于刻板”。我更愿意把自己的编码风格称为“严谨”。我们先严谨地实现了 GreenPiThumb 的软件部分,对每个软件组件都逐一进行了严格的代码审查和测试。

轮到硬件时,我们就一点也不严谨了。可以说我们有些轻率,天真得可笑。我们最初测试硬件组件的流程是:先写一个 GreenPiThumb 软件的简易版本,把所有传感器都接到一块测试板上,跑起来看看会出什么结果。

结果是什么都没有。因为这种测试硬件的策略糟糕透顶。系统中的每一个电子元件都可能出故障,要么是元件本身有缺陷,要么是安装不正确。把所有东西一次性全接上,我们根本无法判断到底是哪一块或哪几块出了问题。

后来,我们学会了隔离测试每个传感器。我们为每个硬件组件编写了独立的诊断脚本。现在每次调整硬件,第一件事就是跑一遍诊断脚本,确认读数是否合理。当某个新硬件不工作时,我们会用万用表系统地排查根本原因。我们本该更早买万用表的。它只花了 13 美元,却能为我们省去无数小时的沮丧和挠头。

源代码

零件清单

下表列出了我们搭建 GreenPiThumb 所用的器材。我们分享具体的型号,是为了方便你照着复刻,不过其中很多都是通用元件,你完全可以用功能相同的替代品。

GreenPiThumb 必备零件

通用电子元件

以下物品是可用于许多项目的通用电子工具和元件。因为我们原本没有任何电子设备,所以也一并列出以作完整记录:

园艺用品

可选组件

致谢

衷心感谢以下为本项目提供帮助的人:

本文章由 muse-spark-1.2-contributor 进行翻译

评论