使用Arduino和InfluxDB入门
作者:社区 / 产品, 用例, 开发者, 入门
2022年2月10日
导航至
本文由Cameron Pavey撰写。向下滚动查看作者的图片和简介。
时序数据 与“正常”数据在有趣的方式上有所不同。其本质特征是数据的主要参考点是时间戳,显示数据样本是在什么时间测量的。如InfluxDB这样的时序数据库 对于涉及此类数据的情况很有帮助。也许您想记录车辆随时间的变化速度并识别最大速度,或者您可能想每十秒钟记录某个位置的温度和湿度。后者将是本教程的基础。使用小型、廉价的开发板,您将了解如何创建一个Arduino应用程序,通过WiFi将气候数据记录到InfluxDB实例中。
客户端库
对于本教程,您可以使用Arduino的InfluxDB客户端库。此库支持InfluxDB 1和2,但本教程将重点介绍InfluxDB 2。
入门
在开始之前,您需要准备一些东西。作为一个Arduino项目,当然涉及到硬件问题。客户端库与ESP8266和ESP32板(两者都与Arduino IDE兼容)配合良好。本教程将使用ESP32板,该板使用WiFi连接到InfluxDB服务器。您也可以使用其他硬件配置,例如带WiFi护盾的Arduino Uno,但如果您这样做,下面的示例可能需要一些调整。
除了ESP32之外,没有数据存储的数据库还有什么用?为了获取一些有趣的数据来处理,我们将ESP32与DHT11温度和湿度传感器配对。如果您没有这样的传感器,但周围有其他传感器,您可以记录其他数据。数据的重要性不如您将如何使用它。InfluxDB包括一些示例数据集,如果您没有本教程中使用的硬件,您可以使用这些数据集。
在软件方面,您需要一个InfluxDB实例来发送您的数据。本教程将使用Influx Docker镜像来完成这项工作。如果您想跟从而没有Docker,您可以参考您选择的操作系统的官方文档。您还可以使用InfluxDB Cloud来获得免费的托管InfluxDB实例。
一旦Docker启动并运行,您可以通过以下命令启动InfluxDB实例:
docker run -d --name=influxdb \
-p 8086:8086 \
-v /tmp/testdata/influx:/root/.influxdb2 \
Influxdb:2.0
这将创建一个运行InfluxDB 2镜像的容器,并将应用程序暴露在主机8086端口上。如果命令执行成功,将返回容器ID作为输出。接下来,您可以使用浏览器登录InfluxDB并设置一些附加元素。
在浏览器中导航到 https://127.0.0.1:8086 ,您应该会提示设置用户。请继续设置,并记下您设置的详细信息,以备后用。
之后,InfluxDB应为您提供一些快速入门选项。选择“加载数据”,当它要求您选择客户端库时,您可以选择“Arduino”。这提供了一些入门代码,非常实用。此页面上还有一些其他参考,例如您的令牌,您可以在稍后从您的Arduino设备发送数据时使用。现在您在这里需要做的就这些。接下来,是处理Arduino代码的时候了。
Arduino
如果您尚未安装Arduino IDE,请访问此处 并根据您的操作系统选择正确的构建进行安装。因为ESP32不是默认的Arduino板之一,您必须通过板管理器添加它。转到 工具 > 板 > 板管理器,IDE将显示一个对话框。在搜索框中输入“ESP”,结果应该看到一个名为 esp32的条目。安装此(或如果您使用的是其他板,则安装相应的板)。
接下来,您需要添加几个库。如果您跟随并使用DHT传感器,您将需要一个用于该传感器的库和一个用于InfluxDB客户端的库。
在菜单栏中,转到 草图 > 包含库 > 管理库。
IDE将再次显示一个对话框。这次,搜索“InfluxDB”并安装相应的库。
对于DHT传感器,只需搜索“DHT”并安装“DHT传感器库”,如此处所示。
一旦您有了您的板,以及这两个库(或如果您使用的是不同的传感器,则所需的其他库),您就准备好编写代码了。
代码
此代码将基于您选择Arduino时InfluxDB Web界面提供的示例,但修改为使用DHT11传感器而不是记录WiFi测量数据,如默认程序所做的那样。
您可以在此处找到所有代码,或者您可以按照说明进行。首先,您需要定义一些常量并导入您的库
// This helps with compatibility with the ESP8266
#if defined(ESP32)
#include <WiFiMulti.h>
WiFiMulti wifiMulti;
#define DEVICE "ESP32"
#elif defined(ESP8266)
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti wifiMulti;
#define DEVICE "ESP8266"
#endif
// Import the InfluxDB libraries
#include <InfluxDbClient.h>
#include <InfluxDbCloud.h>
// Import the DHT sensor library, and set some constants
#include "DHT.h"
#define DHTPIN 4 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT11 // DHT 11
// Set up your WiFi connection here
// WiFi AP SSID
#define WIFI_SSID "<your ssid>"
// WiFi password
#define WIFI_PASSWORD "<your password>"
// Set up your InfluxDB details here
// InfluxDB v2 server url (Use: InfluxDB UI -> Load Data -> Client Libraries)
#define INFLUXDB_URL "http://<your influx server ip>:8086"
// InfluxDB v2 server or cloud API authentication token (Use: InfluxDB UI -> Data -> Tokens -> <select token>)
#define INFLUXDB_TOKEN "<your influx token>
// InfluxDB v2 organization id (Use: InfluxDB UI -> User -> About -> Common Ids )
#define INFLUXDB_ORG "<your org name>"
// InfluxDB v2 bucket name (Use: InfluxDB UI -> Data -> Buckets)
#define INFLUXDB_BUCKET "<your bucket name>"
// Set timezone string according to <https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html>
#define TZ_INFO "CET-1CEST,M3.5.0,M10.5.0/3"
// InfluxDB client instance with preconfigured InfluxCloud certificate
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN, InfluxDbCloud2CACert);
// Create your Data Point here
Point sensor("climate");
// Set up the DHT connection
DHT dht(DHTPIN, DHTTYPE);
在此代码中,您设置了所有依赖项,特别是针对WiFi、DHT和Influx。请注意,这些都在 public void setup() {} 函数之前,您将准备此函数。
void setup() {
// Start Serial for monitoring
Serial.begin(115200);
// Init the DHT sensor
dht.begin();
// Setup wifi
WiFi.mode(WIFI_STA);
wifiMulti.addAP(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to wifi");
while (wifiMulti.run() != WL_CONNECTED) {
Serial.print(".");
delay(100);
}
Serial.println();
// Add tags. Here we will track which device our data is coming from
sensor.addTag("device", DEVICE);
// Accurate time is necessary for certificate validation and writing in batches
// For the fastest time sync, find NTP servers in your area: https://www.pool.ntp.org/zone/
// Syncing progress and the time will be printed to Serial.
timeSync(TZ_INFO, "pool.ntp.org", "time.nis.gov");
// Check server connection
if (client.validateConnection()) {
Serial.print("Connected to InfluxDB: ");
Serial.println(client.getServerUrl());
} else {
Serial.print("InfluxDB connection failed: ");
Serial.println(client.getLastErrorMessage());
}
}
在设置代码中,发生了几件事情。所有库都已被初始化,启动了一个串行,并将标签添加到您的 Influx Point 对象中。在这个例子中,唯一的标签是您的设备名称(ESP32)。这有助于您区分这些读取数据的来源,如果您在周围设置了多个实例,那么包含它可能是有帮助的。还有时间同步,以确保您的设备不会因为与服务器时间不同步而产生任何问题。最后,InfluxDB 客户端确认其与服务器的连接。如果一切正常,您应该在串行监视器中看到“已连接到 InfluxDB”。最后要查看的是循环函数
void loop() {
// Clear fields for reusing the point. Tags will remain untouched
sensor.clearFields();
// Read the temperature and humidity from the sensor, and add them to your data point, along with a calculated heat index
float h = dht.readHumidity();
float t = dht.readTemperature();
sensor.addField("humidity", h);
sensor.addField("temperature", t);
sensor.addField("heat_index", dht.computeHeatIndex(t, h, false));
// Print what are we exactly writing
Serial.print("Writing: ");
Serial.println(sensor.toLineProtocol());
// If no Wifi signal, try to reconnect it
if ((WiFi.RSSI() == 0) && (wifiMulti.run() != WL_CONNECTED)) {
Serial.println("Wifi connection lost");
}
// Write point
if (!client.writePoint(sensor)) {
Serial.print("InfluxDB write failed: ");
Serial.println(client.getLastErrorMessage());
}
//Wait 10s
Serial.println("Wait 10s");
delay(10000);
}
在这里,将 Point 对象的字段清除以允许在循环之间重复使用,然后读取 DHT11 传感器。传感器的读数随后被添加到 Point 作为字段。如果您使用的是不同的传感器或记录不同的数据,您需要做一些更改。之后,串行监视器将显示要写入的 Line Protocol 格式的数据。如果您需要调试任何问题,这些信息可能是有帮助的。最后,在等待十秒重复此过程之前,客户端将写入数据点。
您可以在GitHub Gist上找到完整的代码。请上传此代码到您的板子上,然后从工具菜单连接串行监视器。您应该看到类似以下的内容
如果这样,您现在应该已经在您的 InfluxDB 实例中填充了一些数据。回到网络界面,转到数据 > 存储桶 > {您的存储桶},并选择您创建的度量(赋予您的 Point 对象的名称——在本例中为“Climate”)。您需要让它运行一段时间以获取一些有趣的数据,但这是它在整个白天开启和关闭后的情况
您可以与图表交互,查看特定时间点的具体值。如果您已经做到这一步,您现在已成功将 Arduino 板上的传感器数据通过 WiFi 记录到 InfluxDB 中。
为什么选择 InfluxDB?
InfluxDB 是一个时序数据库,在存储与特定时间戳相关的数据方面表现突出。这类数据库有很多用例,本例很好地展示了其力量。对于像温度这样的数据,随着时间的推移进行记录非常有意义,这样您就可以看到它在一段时间内的变化。使用标签,您可以进一步对数据进行分类。本例中有一个设备名称的标签,但这也很容易被考虑用于“位置”这样的内容。如果您在多个不同位置或气象站运行多个温度传感器,这将是一个很好的候选标签,因为它可以让所有气候数据按位置分类,这使得比较和分析变得容易。
结论
如果您已经跟随了整个教程,您现在有一个 Arduino 兼容的板将传感器数据发送到 InfluxDB 实例。虽然这是一个相当基础的教程,但希望您可以看到这种配对背后的潜力。通过廉价的 Arduino 板,您可以记录任何可想象的传感器数据,并通过无线将其发送到时序数据库。时序数据库为各种新的机会打开了大门,而这些机会通常用传统的数据库是不可行的,例如,如本例中 DHT11 传感器的数据,可以轻松地分析纵向数据。如果您发现自己需要在应用程序中利用时序数据,请记住,InfluxDB 不仅适用于 Arduino。InfluxDB 具有多种集成,允许您从许多来源收集和处理数据。
关于作者
卡梅隆是一位在墨尔本生活和工作的全栈开发者。他将自己的精力投入到对高质量代码的复杂性、开发者生产力和工作满意度的无限探索中。