注意:本教程可能已过时,请到此处获取最新版本。
你们中有些人可能知道在许多欧洲城市作为纪念品出售的变色小雕像。这些白色雕像涂有一种特定的化学物质,这种物质会与空气湿度发生反应,使颜色从浅蓝色变为粉红色,并在不断变化中经历其他色调。他们应该预测当地的短期天气。它们实际上显示了当前情况,但预测能力非常有限且不准确。
从那开始,我们决定基于新的 Arduino Nano Every 和 BME280 传感器制作一个天气预报小矮人。起初看似容易的任务,结果却是相当具有挑战性。普通气压计可以进行短期预报,因为它可以告诉您气压是升高还是降低,并且根据海平面压力与当地海拔高度相抵消的相对压力,它还可以为您提供一些“高”值和“低”阅读。
为了获得更准确的预报,还考虑了相对湿度和风力,并且经典的气压计被更复杂的预报设备“Zambretti Forecaster”所取代。
作者 Zambra end Negretti 早在 1920 年就记录了该预报器,它已成为许多基于微控制器的项目中本地天气预报的解决方案。您可以在此处 ( http://drkfs.net/zambretti.htm)找到有关预报器的完整详细信息,我们还发现Fandonov ( https://github.com/fandonov/weatherstation)的工作对他实施Zambretti 预报员在他的电子墨水显示屏天气预报器中。
我们正在我们的Arduino Nano Every plus 上运行这个项目,我们在其中添加了博世的BME280传感器、一个实时时钟DS3231和一个由八个WS2812B智能 LED组成的小条带。
BME280 能够测量温度、压力、湿度,并提供一些关于绝对湿度和高度的线索,但正如我们将在下面看到的,高度和压力是绑定在一起的,为了我们的目的,我们需要找到我们的真实高度侏儒天气预报员。
需要 DS3231 实时时钟模块,因为部分 Zambretti 计算与季节有关,而该设备了解季节的唯一方法是通过正确设置实时时钟模块。这可能看起来是一种资源浪费,但您可以改进我们提供的代码,包括根据一天中的时间和其他便利设施进行亮度控制等功能,并在草图中使用更多的 RTC。
最后一个组件,LED 灯带相当于改变颜色的小雕像的彩色涂料。在这里,我们利用 RGB 颜色来更详细地表示天气预报,即使 Zambretti 预报的全部 26 种不同条件的表示对于简单的颜色显示来说太多了。
我们决定对其进行简化,这是一项正在进行的工作,您可以轻松更改为不同的颜色编码。
两个主要模块都基于I2C ,因此接线非常简单。我们使用的 RTC 模块甚至有四个连接的通道,这使我们的接线只需 10 分钟。VCC 和 GND 取自 Arduino Nano 排针上的每个 3V3(红色)和 GND(黑色)引脚并焊接到 DS3231 模块一侧的相应引脚,然后 I2C 接口与 Arduino 的 A4 和 A5 一样. A4为SDA(图中蓝色线),A5为SCL(图中黄色线)。我们从 RTC 模块的另一侧采用相同的四个连接,并将它们连接到 BME280 模块,只需要注意顺序即可。VCC / GND / SDL / SCA 顺序没有标准,每个模块可能有不同的顺序需要注意。
LED 灯带通常有三个标签 VDC、DIN 和 GND。这次电源将来自 5V 引脚。一个原因是我们的焊盘可以自由焊接,另一个原因是我们从 USB 为电路板供电,而 5V 直接来自 USB,对 Nano 的电源调节器没有压力。
数据被馈送到 D7 引脚上的条带,但可以是您认为合适的任何其他引脚。只需使用您在靠近顶部的#define LED_PIN 7行中选择的引脚编辑草图。
这是它的接线。我们将通过 USB 为电路供电,因为它需要持续开启以监测环境参数并做出预测。手机的移动电源可能会为电路供电好几个小时,但它不可避免地会耗尽能量。
为了让这个项目工作,我们需要几个库,你可以在草图的第一行找到它们作为#INCLUDEs。
I2C 通信需要电线, Adafruit_Sensors和Adafruit_BME280允许我们从压力、湿度和温度传感器读取数据。LED 灯带由Adafruit_NeoPixel库管理,使我们能够快速有效地控制每个像素颜色。最后但同样重要的是RTCLib ,它允许我们从 DS3231 实时时钟读取所有信息。
我们使用的常数是平均海平面压力和 LED 灯带的常数。我们使用的平均海平面压力值是 1013,25 mbar,相当于 101,325 kPa,这是国际公认的值。
在各种设备初始化之后,我们定义了一些变量,这些变量将用于预测以及串行监视器上的一些文本输出。如果你想深入了解天气情况,你可以连接电脑并读取提供的数据,否则,你可能会简化很多草图,只是避免所有的字符串格式化和打印。
我们决定保留这些调试信息,以在项目中保留一些教育价值。
数组一开始是空的,代码每 10 分钟用一个新值填充它,以便数组的最后一个单元格包含最新的压力读数。包含压力的值是海压,计算它是为了补偿设备放置的高度。
一个非常重要的变量是设备的高度。我们知道海平面压力,我们需要调整传感器的读数,以便我们可以将我们从传感器读取的数据开始读取的海平面压力输入到 Zambretti 公式中。有一个公式可以在知道一系列参数的情况下进行此计算,如果您手头有一个 GPS(甚至您的智能手机也可以有一个)来读取海拔高度,您可以将该值放入海拔高度变量中。有了这些信息,公式就是
随着以下:
P0为相对海平面压力;
P为站压,单位为 hPa;
h是以米为单位的高度
T是摄氏温度。
通过这个公式的输出,我们得到了海平面的压力,这样我们就可以将它输入到我们的数组中。该数组就像一个移位寄存器,每当添加一个新值时,所有以前的值都会向左移动一个位置(最旧的值是 0,最新的值是 9)。
有了这 10 个值的数组,时间间隔为 10 分钟,Zambretti 公式可以找出压力变化趋势(下降、稳定或上升)和在过去 100 分钟内收集的值的滑动窗口上的值。在公式中还考虑了月份,因为 Zambra 和 Negretti 发现它与获得更准确的预测有关。
然而,在最初的 100 分钟内,设备正在收集第一套完整的压力读数,因此预测将是完全错误的。完成此设置后,预测将每 10 分钟调整一次。
以下几行复制物理对象以使用三个窗口(下降/稳定/上升)和压力读数找出与预测对应的字母。这意味着对于相同的压力读数,造成差异的是短期变化以及夏季/冬季。它是在函数calc_zambretti中完成的,该函数获取最旧的三个平均压力值、最后三个平均值以及最后确定季节的月份作为输入。
长长的if...then...else列表最终描绘了 Zambretti 的输出,并将 26 条消息重新排列成更简单的组,即Sunny、Sunny Cloudy、Worsening、Cloudy、Rainy ,告诉我们压力是在升高、稳定还是在下降。我们保留了Fandonov的原始算法,因为它可以让您很好地理解预测的工作原理,然后我们将五种可能情况的输出编码简化为五种不同的 LED 颜色。条带的使用允许从一种颜色缓慢变化到另一种颜色,在每个新预测时向上滚动一个 LED;这也是一个给你预测趋势的解决方案。
我们使用一个简单的例程来实现 LED 条的滚动,该例程从顶部开始将每个 LED 的内容复制到下一个,以便将所有内容向上移动,然后新值由 Zambretti 算法定义并写入第一个 LED 位置。
我们在我们的“标准”3D 打印 Gnome 中托管电路。这次 BME280 部分位于 Gnome 的后部,从他的脚后跟处,而 USB 位于中等高度。您可以修改我们在之前的项目Gnome Traveler中共享的 STL 文件,让传感器和 USB 端口可以从外部访问。
布线非常简单,因此将所有东西放入 3D 打印的 Gnome 中应该非常容易。在我们的设置中,条带位于 Gnome 的上部,因此头部和帽子会以预测的颜色点亮。最好将传感器放在 Gnome 外面,因为它可以从环境中获取空气。最好的结果要求传感器在户外,而不是在湿度和温度受到控制的公寓中。
一种解决方案是让小矮人靠近窗户,并通过 4 线电缆连接将传感器保持在外面;I2C 最多可以容忍一米,这比您将传感器放在窗外所需的要多。
设置好所有硬件后,您可以继续绘制草图。从这里复制它并与 Library Manager 检查您是否拥有所有需要的库:
Arduino Nano Every 使用MegaAVR 核心,您也应该正确安装它:如果您在可用列表中有该板,则它已安装,否则您需要使用Board Manager来安装它。
启动草图验证以确保一切正确,然后上传。打开Serial Monitor,看看慢慢会打印出来的数据。每分钟您都会获得一个压力读数,每十分钟就会存储一次读数。
休息一下,让数组填满真实数据。几个小时后回来,您所看到和阅读的内容应该是有意义的。
黄色是晴天,天蓝色是多云,然后当天气恶化到下雨时,它会变成紫色和红色。
我们将文本保留在草图中,以便您可以轻松更改每个受控天气条件的颜色。语法是strip.setPixelColor(LED, R, G, B); LED 应该始终是条带中的第一个 (0),RGB 值从 0 到 255。有一个整体亮度设置,您可以使用它来全天获得不同的 LED 强度;寻找strip.setBrightness(100); 线并将其变成与日夜阅读 RTC 相关的内容。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !