我们将探索将数据记录与数据可视化相结合。 我们将使用HTML服务器等技术。 我们还将看到如何使用模拟传感器-一种产生模拟数据的传感器,然后我们必须对其进行解释。 实际上,我们将依靠电路板的模数转换(ADC)功能将读取的电压更改为我们可以使用的值。
介绍
我们将实施植物土壤湿度监测解决方案(为简洁起见,我们将使用植物监测器)。 这将涉及使用一个或多个连接到我们的MicroPython开发板的土壤湿度传感器。 我们将设置一个计时器警报(中断),使其定期运行以从传感器读取数据并将其存储在逗号分隔值(CSV)文件中。
下图描绘了该项目的概念图。 MicroPython板将从土壤湿度传感器读取数据,然后根据要求通过HTML网页显示数据。
该项目的用户界面是一个网页,其中包含一个表,该表包含从日志文件读取的所有数据。 这是我们可以克服循环运行HTML服务器的潜在问题的方法。 也就是说,我们不必中断循环来读取传感器-只需通过计时器警报回调即可完成。 可悲的是,该技术仅适用于WiPy和类似的电路板。 我们将不得不对Pyboard使用其他技术。
通过将传感器读数与显示屏分开,我们可以重复使用或修改它们,而不会在我们深入研究代码时感到困惑。 例如,只要可视化组件从文件中读取传感器数据,传感器读取代码的使用方式就无关紧要。 这两个部分之间唯一的接口或连接是文件的格式,并且由于我们使用的是CSV文件,因此在我们的代码中非常容易阅读和使用。
为了使事情变得更有趣并使编码更容易,我们将所有传感器代码放在单独的代码模块中。
零件需求
所需的跳线数量将因您使用的传感器数量以及是否使用需要网络模块的MicroPython板而异。 每个传感器需要三个跳线,如果使用的是CC3000 SPI转接板,则需要八根额外的线。 如果您打算使用Pyboard,则还需要添加一个实时时钟以在断电时保持时间
Pyboard固件不支持网络时间协议(NTP)服务器。 因此,您必须在每次打开板上电源时初始化板载RTC,将备用电池连接到板上(请参阅板的下面–您将看到需要焊接的引脚),或添加实时功能的时钟模块。
土壤水分传感器有多种形式,但大多数都有两个插脚插入土壤中,并使用少量电荷测量插脚之间的电阻。 读数越高,土壤中的水分就越多。 但是,需要一些配置才能获得可靠或现实的阈值。 尽管制造商会提供阈值建议,但可能需要进行一些实验才能找到正确的值。
这些传感器还可能受到环境因素的影响,这些环境因素包括植物所处的花盆类型,土壤成分以及其他因素。 因此,尝试使用已知的水淹过的土壤,干燥的土壤和适当照料的土壤将有助于您缩小环境的门槛。
特别值得注意的是这些土壤湿度传感器是如何工作的。 如果要让传感器保持开机状态,它们会随着时间推移而退化。 尖头上的金属可能会由于电解而降解,从而大大缩短其使用寿命。 您可以使用GPIO引脚的技术通过在想要读取值时将其打开来为传感器供电。 请记住,传感器稳定时会有一个小的延迟,但是我们可以使用一个简单的延迟来等待,然后读取该值并关闭传感器。 这样,我们可以大大延长传感器的使用寿命。
设置
下图仅显示两个传感器,但您可以根据需要添加更多传感器。 但是,建议您从一个传感器开始,直到使项目工作,然后再添加其他传感器。 如果更简单,则可以使用试验板将传感器连接到MicroPython板上,但是根据您计划将板放置的位置,可能不需要它。
接线
当然,您必须将土壤水分传感器插入植物的土壤中。 如果您的植物距离电源较远,则可能需要使用更长的电线来连接传感器。 您应该从一个单一的小型植物和一个传感器(或者为了测试,在一个植物中安装两个传感器)开始,然后将其放置在靠近PC(或电源)的位置。
请务必在打开开发板电源之前仔细检查您的连接。 现在,让我们谈谈我们需要编写的代码。
编程
我们将分两个阶段编写代码,并将在测试项目之前将所有内容放在一起。我们将有两个主要部分:主代码和封装土壤传感器的代码模块。 我们将HTML服务器代码和支持功能放在主代码模块中。 但是,在开始执行该项目的代码之前,应先校准传感器。
校对
传感器的校准非常重要。 对于土壤湿度传感器而言尤其如此,因为有许多不同的版本可用。 这些传感器对土壤成分,温度甚至植物所居住的盆栽类型也非常敏感。 因此,我们应该对已知的土壤水分进行试验,以便知道在代码中使用的范围。
更具体地说,我们想对来自传感器的观察结果进行分类,以便可以确定植物是否需要浇水。 我们将使用“ dry”,“ Ok”和“ wet”值对从传感器读取的值进行分类。 看到这些标签对于我们来说一目了然,很容易确定植物是否需要浇水。 在这种情况下,原始数据(例如1756的值)可能意义不大,但是如果看到“dry”,我们知道它需要水。
由于传感器是模拟传感器,因此我们将在板上使用模数转换。 当我们从引脚读取数据时,我们将获得0-4096范围内的值。 该值与传感器在土壤中读取的电阻有关。 低值表示干土,高值表示湿土。
我们必须确定这三种分类的阈值。 同样,有几个因素会影响从传感器读取的值。 因此,您应该选择几盆土壤,其中一盆您觉得干燥,另一盆已正确浇水,而第三盆过水。 最好的选择是选择一种干燥的,进行测量,然后浇水直到土壤湿度正确,再进行测量,然后再次浇水直到水分过多。
代码
传感代码模块
该项目的第一部分将是创建一个代码模块,以包含一个名为PlantMonitor的新类,该类包含从传感器读取数据并将数据保存到文件的所有功能。 打开一个新文件,并将其命名为plant_monitor.py。
正如我们先前所了解的,为我们要使用的每个代码模块(类)创建一个设计是一个好主意。 我们将使用主代码中的代码模块。 因此,我们需要一些函数来告知类读取传感器,以及一种获取类用于数据的文件名的方法。
通常,人们会设计一个代码模块以完全隐藏文件及其上的所有操作,但是本文,类仅涉及读取传感器和写入数据。 另外,由于主代码需要读取数据并使用HTML标签对其进行格式化,因此将读取功能放置在主代码中更为合适。 也就是说,您应该努力将类似的代码功能保持在一起,这有助于维护代码。 例如,将所有HTML代码保存在一个文件中,可以更轻松地修改HTML代码(或重新使用它)。
我们将使用计时器中断来读取传感器。 这使我们可以设置一个定期调用的函数,而无需监视或轮询时间并直接调用该函数。 为了方便起见,我们提供了清晰的日志功能。 因此,我们只需要两个公共函数:一个清除日志,另一个则获取文件名。 除了初始化类之外,我们仅在想要刷新数据(将其发送给客户端)时才需要获取文件名。
设置和初始化
我们讨论了设置和初始化代码模块所需的代码。 首先,我们需要导入一些内容,包括模数转换器,引脚,安全磁盘(SD),计时器和操作系统库的内容。
我们还需要为该类定义一些常量。我们用枚举对读取的土壤水分进行分类。 为此,我们将需要使用为分类确定的阈值。 我们可以在文件顶部使用常量,以便以后需要更改代码以与其他传感器配合使用或我们的植物条件发生变化(不同的花盆,土壤,环境等)时,可以更轻松地更改它们。 我们可以使用相同的原理来设置文件名以包含数据。
我们还使用常数来定义读取传感器的频率。 由于我们将使用循环读取传感器,每次读取等待5秒,因此最少需要50-55秒才能读取10个值。 因此,我们不能将更新频率设置为少于一分钟。 频率以秒为单位。 虽然您可能希望将此值设置为较低的值进行测试,但您当然不希望每分钟检查一次植物的土壤湿度。
最后,我们需要一个将时间结构转换为字符串的函数。我们将为该功能使用模块级私有函数。
下方是显示设置和初始化部分的代码,将其放置在文件的顶部。
构造函数
该类的构造函数是所有主要工作发生的地方。 我们需要做几件事,包括以下内容。
- 归一化数据文件的位置(路径)
- 在列表中存储的字典中设置传感器
- 设置计时器中断以定期读取传感器
我们通过尝试使用SD卡来规范化数据文件的路径。 如果找不到SD卡,则默认使用闪存驱动器。 但是,您应该避免将数据写入闪存驱动器,因为该驱动器较小,并且可能会填满,而且写入闪存驱动器会增加损坏驱动器或在执行过程中引起问题的风险。
我们为每个传感器使用一个字典,因此我们可以定义传感器的引脚,为传感器供电的引脚,传感器编号(任意标识)以及传感器的位置。 然后,我们将字典放在一个列表中,以方便使用循环,同时读取所有传感器。
最后,我们通过计时器警报类设置了一个中断,以定期读取传感器。
代码
完整代码
主代码
HTML代码
我们将在文件中存储所需的HTML代码以节省内存。 通过一次读取一行来回想一下-我们不必在代码中占用字符串空间。 随着您的项目变得越来越复杂,这可能会成为一个问题。 因此,该项目演示了一种节省内存的方法。
详情参阅 - 亚图跨际