给自己建个气象站

2020-06-15 13:48:54

我住在离办公室相当远的地方,所以我每天的通勤时间可能需要2.5到4个小时😱。这包括大量的步行时间。我记不清从家里出门时忘了检查有没有下雨。或者,更糟糕的是,在我去火车站的中途下起了雨。另外,我iPhone上的天气应用程序不太擅长做出准确的预报。它可以很容易地让我相信,当一场小雨开始落下时,外面是阳光明媚的。

几个月前,我开始潜心研究电子产品、微控制器和PCB,所以一个附带项目的想法自然浮出水面。我会创建一个简单的气象站,每天早上检查室外的湿度和温度,如果我需要带雨伞或暖和的衣服,会通知我。从硬件的角度来看,这是一个有趣又简单的物联网项目,所以我决定试一试。

在这一系列的帖子中,我们将介绍如何构建一个由网络仪表盘和电报机器人供电的物联网气象站。我们将首先从鸟瞰开始,然后介绍我们将要制作的建筑。

Graph LR D(fa:FA-MicroChip IoT Device)-->;|天气测量|B(fa:FA-Gears后端)B-->;DB(fa:FA-数据库天气DB)B-->;TG(fa:FA-Telegram Bot)B-->;API(fa:FA-Gear REST API)API-->;F(fa:FA-线图前端仪表板)classDef CLS Fill。

这是系统中的一般信息流。在本文中,我们将介绍构建每个组件的过程:

Telegram Bot将用作通知服务,多个用户可以订阅和接收新的天气信息。

REST API和前端仪表板用于在在线仪表板中显示天气数据库中的信息。

在开始编码之前,我们需要决定的第一件事是使用什么协议在物联网设备和后端之间进行通信。我想我可能不仅要在家里放置站点,还要在我们的乡村住宅放置站点,因此我们需要能够将来自多个设备的消息发布到单个端点。所有消息都可以异步处理,我们的边缘设备不需要从后台获得任何响应。

在这种情况下,最合适的通信模式是某种发布-订阅消息传递协议。在物联网世界中,最流行的选择之一是MQTT。许多设备都支持它,而且使用开源消息代理(如Eclipse Mosquito,我们将在本项目中使用它)既好又简单。

至于后端组件,我决定使用Rust。我可以详述这门语言的所有好处,但老实说,主要原因是我正在学习这门语言,并希望有更多的练习😊。

首先我们要建设的是气象站本身。尽管Arduino很受欢迎,我还是决定将该项目基于ESP32芯片。首先,这是一个便宜得多的选择。开发板的成本不到4美元。其次,与竞争对手相比,它相当有冲击力:

FreeRTOS免费实时操作系统包含多任务原语(如异步任务、队列和事件)的有用实现。

非易失性内存存储NVM就像芯片上的一个小硬盘,允许您在电路板断电时存储信息。

低功耗和深度睡眠模式,允许使用充电电池为芯片供电。

还有更多有用的东西,比如网状网络,它允许您将许多设备放入网状网络,无需访问WiFi接入点即可在设备之间传播消息。

另一个重要的部分是将测量温度的传感器。我已经决定使用流行的BME280传感器。它体积小,价格便宜,而且准确。另外,它不仅可以测量温度,还可以测量压力和湿度💪🏻。

BME 280传感器。我强烈建议使用接线板,因为传感器本身非常小,如果您要为传感器订购中国接线板,您可能需要将引脚焊接到接线板上。这不难,但要确保你手头有必要的焊接设备。如果你不知道如何焊接,请参考互联网上的大量指南和视频。例如,这个。它可以使用广泛支持的SPI和I2C协议与其他PCB进行通信。

ESP32板的3.3V或5V微型USB电源。我用一个你经常用来给手机充电的简单的电源库,另一个选择是使用电池组。这是一个稍微复杂的设置,我将在另一篇文章中介绍。

一台带有免费USB端口的计算机,您可以使用该端口进行编码和刷新。

线路并不复杂,您需要将BME280传感器连接到电路板上并为其通电。您不必连接电源,因为开发板可以通过微型USB端口供电。您可以简单地将其连接到您的PC、手机充电器或电源库。

下一个还不确定的部分是传感器如何与我们的ESP32板通信。与具有用于设备间通信的TCP/IP或UDP堆栈的软件一样,硬件也具有一组用于数据传输的常用协议。我们将使用I2C(内部集成电路)协议进行通信,因为它意味着更少的线路和更简单的设置。I2C用于紧密放置的多个设备之间的数据传输,这非常适合我们的情况。另一种选择是使用SPI(串行外设接口),但它需要更多导线,因此我们将选择更经济的选项来节省ESP32板上的引脚。

您可以在原理图上看到连接到BME280的SDA(红色)和SCL(黄色)线。这些将用于我们的ESP32板和传感器之间的通信。

接下来,我们将介绍I2C的工作原理,这对于理解我们何时开始编码非常重要。

I2C是一种同步通信协议,允许多个设备交换信息。同步意味着所有连接的设备都使用公共时钟进行同步。在I2C的情况下,时钟在SCL线上滴答作响。

所有帧和时钟信号均以二进制格式发送。要实现这一点,需要选择一组阈值。例如,如果导线上的电压介于0.4V和0.8V之间,则认为是0,如果是从2V到2.7V,则认为是高电压。所有其他值都被认为是无效的。不同的微控制器使用不同的阈值,因此有几组常见的阈值。具体的价值对我们来说并不重要,只要你抓住要点。

让我们稍微扩展一下说“时钟”是什么意思。它实际上不过是某个预定频率的周期性脉冲,大多数I2C器件可以以100 kHz或400 kHz的时钟速率进行通信。时钟本身并不是很有用,但与第二根导线SDA结合使用时,它允许在一个或多个称为主设备的主设备和称为从设备的多个辅助设备之间进行数据传输。在空闲状态下,时钟持续脉冲,而SDA线在空闲状态下设置为1。

在I2C中,信息是在称为帧的块中交换的。每帧包含8位信息和用于从属设备确认的附加ACK/NACK位。发送帧的前8位后,从属设备将获得对SDA的控制权。要确认帧已收到,器件必须在第9个时钟脉冲之前将SDA线路拉低。如果它没有这样做,那么主设备可以推断出发生了不好的事情,并决定如何继续。

主设备是启动通信的设备。在I2C中,主机可以发送两种类型的消息,也称为帧:地址帧和数据帧。地址帧用于选择应该接收数据的从属设备,该数据出现在接下来的一个或几个帧中。

首先,我们需要指出数据传输即将发生。为此使用了一个特殊的启动条件:主机器件必须将SCL设置为1,并在此之后将SDA拉至0。请注意,主机始终以恒定速率振荡SCL。因此,启动条件可能被视为在时钟较高时等待,然后将SDA线设置为。此操作通知所有从属设备数据传输即将开始。

下一帧始终是地址帧。I2C中的每个器件地址都是7位长的0000001、0000010、0000011,依此类推。地址帧包含每次时钟变高时由从属设备读取的那1000位。然后,这7位后面跟着单个读/写位,该读/写位指示随后的数据帧将读取还是写入信息。

随后的一个或多个帧是数据帧,其还包含8双信息,后跟ACK/NACK确认/未确认位。在时钟从0转换到1之前,主机将设置每一位。当时钟为1时,从机可以读取传入的位。寻址的从器件将接收数据,直到满足停止条件:在SCL从0转换到1之后,主器件立即将SDA从0拉到1。

至此,我们已经概述了体系结构和技术堆栈,选择并布线了硬件,并深入了解了集成电路如何使用两根线和I2C协议进行相互通信。

在下一篇文章中,我们将通过编写固件来利用ESP32的功能,该固件将从BME280收集数据并通过无线网络将其发送到我们的MQTT服务器。订阅RSS提要,以便在下一篇帖子发布时收到通知。