基于Arduino UNO Q制作一个智能灌溉控制器
农业用水量巨大,仅农业领域就占全球总用水量的70%。根据联合国粮食及农业组织的数据,该行业导致了约60%的水资源浪费。更糟糕的是,农民正面临日益不稳定的天气模式,使得作物生长季节变得更加炎热和干旱。
实时水表应用,如智能灌溉系统或作物水分管理系统,有助于农民减少浪费,同时保持土壤健康,提高水资源利用效率并增加农作物产量。这正是我所应用的 EcoFlow AI 的作用所在。
EcoFlow AI 是一款基于 Arduino UNO Q 的智能去中心化灌溉控制器。该系统通过设备端的机器学习(ML)技术,分析本地环境遥测数据——特别是大气温度、土壤湿度和湿度,从而做出实时的灌溉决策。与传统的基于定时器的系统不同,本项目通过仅在训练好的模型确认真正需要灌溉时才启动水泵,从而避免了过度灌溉,不受传感器“噪声”或天气变化的影响。
该项目的目标是在一段时间内(时间序列)收集遥测数据(温度、湿度、土壤湿度),并利用Edge Impulse平台训练一个分类模型。训练完成后,该模型可应用于实际传感器数据,实时进行分类,以评估土壤湿度状态。
有人可能会认为,与其训练分类模型,不如使用if-then-else算法。这确实可行,但效率较低。该算法基于启发式规则系统,较为僵化。例如,不能简单地根据“若湿度 < 30%”这样的基本规则来触发水泵,而机器学习模型会分析所有传感器在特定时间段内的行为趋势,以预测土壤的真实生态状态。此外,该算法通常包含大量if-then-else语句,导致其使用和维护变得困难。相反,分类模型并不关注某个数值是否被超过,而是分析数据曲线的几何形状。它能够识别复杂的动态天气模式。通过这种方式,我们的系统变得智能且具备上下文感知能力,从而减少错误并节约用水,这是传统代码无法实现的。
1. 硬件
本项目采用Arduino UNO Q,因为它需要在设备上实现机器学习(ML)功能,以分析本地环境遥测数据——特别是大气温度、湿度和土壤湿度,从而做出实时的浇水决策。与传统的定时系统不同,该项目通过训练模型确认真正需要浇水时才启动水泵,无论传感器是否存在“噪声”或天气变化,都能有效避免过度灌溉。
用于测量大气温度和湿度的传感器是DHT11,这是该任务中非常常用的选择。为了测量土壤湿度,使用了电容式土壤湿度传感器,它通过电容效应而非市场上其他传感器所使用的电阻效应来检测土壤湿度,因此测量结果更可靠,且不会像电阻式传感器那样被土壤化学物质腐蚀。为给植物供水,使用了一台电机泵,由12伏电池供电。由于该泵包含电机,需要比Arduino UNO Q所能安全提供的更高电压和电流,因此并未直接连接到电路板上。相反,使用一个5伏继电器模块来电气隔离Arduino与水泵,并控制水泵的运行。电路图如下所示。
1.1 电路图
2. 设置 Arduino Uno Q
Arduino Uno Q 以无头模式运行。有关初始设置和配置 SSH 访问的说明,请参阅官方 Arduino 文档。
3. 数据收集
分类模型在 Edge Impulse 平台上训练,用于区分土壤的三种不同状态:干燥、最佳、饱和。系统会针对每个土壤状态,在一段时间内收集相应的数据,以学习温度、湿度和土壤湿度传感器读数之间的规律。这一过程涉及数据采集,但为获得最佳结果,还需注意一些关键因素。
3.1 文件格式
Edge Impulse 要求时间序列数据具有统一的结构。由于多个传感器读数需在完全相同的时间戳下采集,因此必须使用多轴 CSV 文件。该文件必须具备特定格式,并包含清晰的标题行,如下所示:
因此,对于每种土壤状态,都需要创建一个独立的 CSV 文件。生成这些文件的过程如下:
首先,让土壤完全干燥,并在此期间持续采集温度、湿度和土壤湿度的传感器读数,并记录时间戳。在此过程中,会生成表示土壤干燥状态的 CSV 文件。
之后,对土壤进行适量浇水,使其既不干涸也不积水,即达到我们所期望的最佳状态。我们开始在一段时间内记录传感器读数,并附上时间戳。在此期间,会生成一个CSV文件,用于记录土壤的最佳状态。
随后,土壤被过度浇水,我们再次开始记录传感器读数并附上时间戳。在此期间,也会生成一个CSV文件,用于记录土壤的饱和状态。
3.2 记录时间
为确保分类模型的准确性和可靠性,记录时间和文件组织方式至关重要。对于本项目中这类变化缓慢的环境数据,Edge Impulse 需要几分钟的时间来“识别”微小波动和传感器噪声。因此,每个土壤状态下的所有传感器读数将每10秒记录一次,持续30分钟或更长时间。这样产生的历史数据足够神经网络回溯分析,以识别出明确的趋势(例如:“温度急剧上升,而湿度骤降”)。最终,将生成一个包含该30分钟记录期间所有读数的单一CSV文件。
然而,为了更好地训练分类模型,Edge Impulse 提供了一项功能,可将上传的文件划分为 80% 的训练数据和 20% 的测试数据。这需要上传多个小型独立文件,以便自动清晰地管理 80/20 的训练/测试划分。因此,30 分钟的文件会被拆分成多个 5 分钟的小文件。这意味着对于每种土壤状态,都会生成多个较小的 CSV 文件。例如,在土壤干燥状态下,会生成多个 CSV 文件,每个文件包含传感器数据,总时长为 5 分钟。
3.3 软件程序
数据采集过程必须顺畅运行。一旦传感器连接到 Arduino UNO Q,就需要一个定制程序自动采集其数值,无需人工干预。为此,程序在 Arduino App Lab 中编写,利用了 Arduino UNO Q 的微控制器(MCU)和微处理器(MPU)单元。
微控制器单元负责硬件关键任务,例如读取模拟土壤传感器,而程序本身实际上是一个类似原始 Arduino Uno 的代码草图。另一方面,微处理器搭载了运行Linux系统的高通处理器,程序通常使用Python编写。因此,MCU端的代码会从传感器收集时间序列数据,并通过桥接层(由Arduino UNO Q提供)将数据发送至MPU端运行的Python程序,后者再生成CSV文件。Linux与Arduino之间的通信通过桥接层实现。
数据采集程序的代码可从GitHub仓库的数据采集(data-collection)目录中获取。
如图所示,Arduino程序每10秒采集一次所有传感器的数据并添加时间戳,通过桥接层发送给Python程序。Python程序则每隔5分钟创建一个包含这些数据的新CSV文件。例如,在土壤干燥状态时,程序在前5分钟后开始工作,此时生成名为dry_1.csv的文件;接下来的5分钟内生成dry_2.csv,依此类推。最后,所有生成的CSV文件会被移动到名为“dry”的文件夹中。同样地,程序还会为其他两种土壤状态——最佳状态和饱和状态——生成对应的CSV文件,并将其存入相应的文件夹中。收集到的数据可在 GitHub 仓库的 data 目录下找到。
4. 脉冲设计
在模型开发过程中,需要在 Edge Impulse Studio 中创建一个脉冲。首先注册一个新账户,并创建一个新的项目。然后将传感器数据上传至 Edge Impulse。
4.1 数据上传
在左侧菜单中进入“数据采集”页面,在“数据集”选项卡中点击“添加数据”按钮以上传数据。选择“从文件夹上传”作为上传模式。在“上传到类别”下,选择“自动划分训练与测试数据”(这可确保后续验证时具有标准的80/20数据分布,避免偏差)。在“标签”选项中,选择“输入标签”,为属于同一土壤状态的CSV文件集指定相应的标签。最后点击“选择文件”,选取位于“dry”文件夹中的CSV文件进行上传。同样地,对“optimal”和“saturated”文件夹中的CSV文件重复此操作。
上传带有正确标签的CSV文件如下所示:
4.2 训练
现在是设置神经网络训练所需参数的时候了。该过程分为三个步骤完成。
第一步
转到“脉冲设计 > 创建脉冲”页面,左侧会显示一个时间序列数据面板。输入轴包括三个:温度、湿度和水分。
将窗口大小设置为10000毫秒(10秒),以适应缓慢变化的环境条件。这用于表示AI需要回溯多长时间才能识别出趋势。
将窗口增加量设置为1000毫秒。这将创建一个滚动滑动窗口,从您的时间线中生成高度重叠的训练数据。
在同一页面上,选择“添加处理块”,并选择“对所有三个输入轴进行展开”。展开模块会将时间窗口提取出统计特征(平均值、最小值、最大值、标准差),针对每个传感器轴,从而将杂乱的时间线转化为清晰的数学指标。
在同一页面上,选择“添加学习块”,并选择“分类”,用于从数据中学习模式,并可将这些模式应用于新数据。再次选择“添加学习块”,并选择“异常检测(K-means)”,用于在新数据中识别异常值。该方法有助于识别未知状态,并可作为分类器的有效补充。
在同一页面的最右侧,输出特征应包含四个值:干燥、最佳、饱和、异常分数。
最后点击“保存脉冲”按钮。
第二步
转到“冲动设计 > 折叠页面”,该页面将显示训练所需的所有必要参数。
点击“保存参数”按钮,将出现一个新页面,其中包含有关训练集的信息。
点击“生成特征”按钮,以了解数据的统计特征。如右侧特征探索器所示,每个土壤状态在三维空间中所占的空间各不相同,这意味着训练集的质量非常好。
第三步
导航至“Impulse Design > 分类器”页面,在训练前配置神经网络的参数。
如图所示,训练周期数设置为较高的100次。周期数越高,训练结果越好,但所需时间也越长。学习率设置为非常低的0.0005。该参数决定了神经网络的学习速度。如果网络过快拟合,则应选择较低的学习率。关于神经网络结构,保留默认参数。
最后点击“保存并训练”按钮,这将开始神经网络的训练。等待一段时间后,结果会显示在屏幕右侧。
混淆矩阵展示了模型的表现情况。如图所示,结果非常出色。三种固态的得分均为100%,这意味着分类模型能够根据实时数据准确区分三种土壤状态。
4.3 模型部署
转到 Impulse Design > 部署页面,选择目标为 Arduino UNO Q,然后点击“构建”按钮,以编译并下载库文件包。这将生成一个扩展名为 .eim 的文件,该文件是原生的 Linux 二进制应用程序,其中包含了在 Edge Impulse Studio 中创建的完整脉冲,并已针对我们的特定系统架构进行编译。
5. 运行应用程序
将.eim文件下载到个人电脑后,我们需要将其导入到Arduino UNO Q中。
5.1 模型导入
首先将其重命名为time-series-sensor.eim,以便于引用。我们使用WinSCP等软件将模型文件复制到UNO Q的以下文件夹中:
/app/assets/
这是Python程序用于访问分类模型并实时运行推理的路径。
5.2 软件程序
应用程序代码位于github仓库data-inference目录下。
这与第3.3节中使用的程序不同,后者会收集所有传感器的数据,并为每种土壤状态生成CSV文件。但某些功能是相似的。
Arduino程序每5秒采集一次所有传感器的数据,并通过桥接层(Bridge layer)发送给Python程序。Python程序接收这些数据并输入到分类模型中。模型根据温度、湿度和土壤湿度的实时值进行推理,并生成预测结果。这些参数用于判断土壤是干燥、最佳还是饱和状态。最终结果是土壤状态,其置信度最高,以百分比表示该预测的概率。
最后,在Python程序中使用一系列“如果-那么-否则”语句,根据模型的预测在Arduino端决定相应的操作。例如,如果预测的土壤状态为干燥且置信度超过80%,则向MCU发送指令以激活串行端口,启动水泵并为植物供水。随着水分逐渐增加,土壤湿度将逐步上升,直至达到饱和状态。Arduino程序检测到这一变化,并将更新后的传感器读数发送回Python程序。这些数值随后被输入分类模型,模型生成高置信度的饱和土壤预测。在此情况下,系统会向MCU发送指令,关闭串行端口并停止水泵运行,防止进一步给植物浇水。执行此分析的代码如下:
5.3 网络用户界面
该功能可通过网络用户界面进行演示。WebUI Brick 用于在网页浏览器中显示系统数据。Python 程序初始化 WebUI 并创建一个 REST 接口,提供以下值:
•温度
•湿度
•土壤湿度
•通过分类模型预测的土壤状态
•水泵状态,表示是否开启或关闭
应用程序的网页部分实现于 index.html 文件中。该文件显示一个仪表盘,用户可在其中查看上述数值。文件包含一个函数,每5秒向REST端点发送一次请求,并相应更新显示的数值,使用户能够近乎实时地监控系统运行情况。
仪表盘运行在默认端口7000的WebUI模块上,显示所有必要的数值。如图所示,当预测的土壤状态为干燥且置信度超过80%时,水泵将启动以向植物供水。
在植物被灌溉期间,土壤状态会逐渐变为饱和;当置信度超过88%时,水泵将自动关闭。
5.4 演示
为了使演示更加顺畅和可靠,我们做了以下两个妥协:
1. 在激活串口时,不会直接启动泵,而是使用Arduino内置的LED灯。这样,当需要显示泵已开启或关闭时,就可以通过点亮内置LED来实现。
2. 由于难以精确复现测试所需的特定环境条件,因此采用模拟传感器数据代替。如前所述,Arduino程序每5秒采集一次所有传感器的读数,从而可以将温度、湿度和土壤湿度值替换为预先设定的数值,以最符合我们想要验证的测试场景。
然而,若仅一次性更改这些数值,则无法模拟环境条件随时间的变化。为此,我们统计自程序启动以来经过的5秒间隔数量,并利用该信息定义模拟环境条件的不同阶段。这样便能够重现一系列变化的环境状态,并观察分类模型随时间的响应情况。因此,在Arduino程序中,我们可以输入以下示例代码,通过增加湿度值来模拟土壤持续浇水的过程。
如图所示,我们从模拟土壤最佳状态的传感器读数开始。通过统计经过的5秒间隔数量,我们重置传感器数值,以模拟15秒后土壤干燥的状态。这是在经过三个5秒间隔(共15秒)之后。接着,在接下来的5秒内或经过四个5秒间隔(共20秒)后,我们更改湿度值。这一过程可通过以下演示视频说明。
在应用启动时,首先模拟最佳状态,并以高置信度显示在仪表盘上。此时泵的状态为关闭,如视频所示,Arduino UNO Q内置LED灯也处于熄灭状态。当传感器数值被修改以模拟干燥状态后,应用进行推理,仪表盘随即以高置信度显示干燥状态。此时,应用将泵的状态切换为开启,视频中也可见内置LED灯亮起。最后,当传感器数值被修改以模拟饱和状态时,应用的推理结果变为饱和,仪表盘相应更新。但只有当置信度超过88%时,泵的状态才会切换为关闭。在视频中,当内置LED关闭时显示的内容。
6. 需要改进的事项
可实施三项关键改进措施,以提升项目的专业性、效率和整体表现。
6.1 全年数据收集
该项目的传感器数据主要在夏季采集。若能在其他季节也收集传感器数据,将有助于分类模型全年更广泛地捕捉各种环境条件,从而提升模型在不同气候条件下(包括春季降雨、夏季干旱和冬季霜冻)的预测准确性和用水效率。
6.2 带电池的太阳能板
通过将微型光伏(PV)太阳能板与可充电锂离子电池组及集成电源管理电路结合,项目可显著升级为完全独立于电网、自给自足的系统。由于Edge Impulse机器学习推理和传感器数据均在低功耗的Arduino UNO Q上本地运行,系统可利用微控制器的睡眠模式,周期性唤醒以采集数据并执行推理,之后再返回低功耗待机状态。
太阳能板在白天为电池充电,而节能电路则确保系统在夜间也能全天候不间断运行。这种自给自足的设计无需电网基础设施或人工更换电池,使其成为适用于偏远农业田地、大型商业农场及离网环境的真正自主部署解决方案。
6.3 额外传感器
通过增加更多传感器,为分类模型提供更多的输入参数,可进一步优化本项目。这将提高模型的准确性,并实现对作物用水需求的更精确估算。部分传感器如下:
土壤温度传感器
土壤温度传感器用于监测土壤温度,该温度会影响根系吸水、植物生长以及蒸发速率。将土壤温度数据纳入模型,可提升对作物需水量的估算精度,并根据土壤条件变化实现更精准的灌溉调度。
土壤NPK与pH传感器
NPK传感器用于测量土壤中氮、磷、钾的含量,而pH传感器则用于检测土壤的酸碱度。将这些参数集成到分类模型中,可使系统优化施肥灌溉(即肥料与灌溉的结合使用),同时提高水资源利用效率。这使得系统不仅能确定适宜的水量,还能判断作物所需的最优养分需求。
太阳辐射/光强计
太阳辐射传感器,或称光强计,用于测量照射到作物区域的太阳光强度。该信息可整合进模型中,以估算蒸散发(ET)速率,帮助系统判断通过蒸发和植物蒸腾损失了多少水分。通过纳入太阳辐射数据,模型能够改进灌溉时间安排,并根据当前环境条件提供更精确的用水需求。
风速与风向
风速仪用于测量风速和风向,为喷灌系统的管理提供重要信息。在风力较强时,系统可暂时暂停或调整灌溉,以防止水分分布不均、喷洒过量以及水资源浪费。因此,将风力数据集成到模型中可以提高灌溉效率,并确保更精确的用水管理。
水位/超声波传感器
水位或超声波传感器用于监测水库、水箱或水井中的水量。通过提供实时的水位信息,系统可在供水不足时防止水泵运行,从而降低泵体损坏的风险。这些数据还可帮助模型根据可用水资源优化灌溉计划,提升整体水资源管理效率。
本文编译自hackster.io





