如何从 Arduino Uno 发送传感器数据到 InfluxDB
作者 Todd Persen / 产品,用例
2015年9月29日
导航至
简介
由于 InfluxDB 是一个时序数据库,因此它是存储从传感器和各种其他设备收集的数据的完美选择,这些设备构成了物联网。在本文中,我们将探讨一个基本用例,即从连接到 Arduino Uno 的温度传感器收集数据,然后通过本机 UDP 插件发送到 InfluxDB。
为什么使用 UDP?
由于大多数互联网设备中使用的处理器都是为了节能(因此相对功率较低)并且可能通过低带宽链路连接,因此我们最好使用尽可能少处理和网络开销的通信方法。
因此,UDP(用户数据报协议)是这项练习的一个优秀选择。与它的姐妹协议TCP不同,UDP是无连接的——这意味着它不需要任何握手或等待成功数据传输的确认。这也意味着使用UDP的一个潜在缺点是,失败的传输将不会被检测到。正因为如此,它通常被称为“发射并忘记”协议。
其他协议,如MQTT,提供了与UDP相似效率的数据传输属性,但需要更复杂的客户端实现来获得更好的数据接收保证。
InfluxDB 行协议
幸运的是,向InfluxDB发送数据很容易——它有一个紧凑的、基于文本的行协议,可以用于通过HTTP API和UDP接口写入数据。每行提供一个点,其规范如下
[key] [fields] [timestamp]
时间戳字段(以纪元以来的纳秒指定)是可选的,因此一个样本点可能如下所示
temperature,device=arduino01 value=83.2
在此示例中,device
指定了一个标签,这允许在InfluxDB中进行方便的索引。您还可以提供其他标签以帮助识别特定测量的具体细节。
启用InfluxDB上的UDP
默认情况下,InfluxDB上的UDP接口是禁用的。您需要修改配置文件,使其类似于以下内容
...
[[udp]]
enabled = true
bind-address = ":8888"
database = "arduino"
...
在您可以通过UDP接口接收数据包之前,需要创建指定的数据库。为此,您可以使用以下命令与InfluxDB CLI
CREATE DATABASE arduino
硬件
我们将使用以下硬件
注意:一些版本的Arduino WiFi Shield附带有故障固件。如果您在检查了其他所有内容后仍遇到发送UDP数据包的问题,您可以在这里学习如何升级固件这里。
示例代码
此代码假定TMP36连接到模拟引脚0,并且每秒轮询一次,通过UDP将值发送到指定的InfluxDB主机。
#include <SPI.h>
#include <WiFi.h>
#include <WiFiUDP.h>
char ssid[] = "your network name"; // your network SSID (name)
char pass[] = "network password"; // your network password
int status = WL_IDLE_STATUS; // the Wifi radio's status
// the IP address of your InfluxDB host
byte host[] = {10, 0, 1, 11};
// the port that the InfluxDB UDP plugin is listening on
int port = 8888;
WiFiUDP udp;
void setup() {
// initialize serial port
Serial.begin(9600);
// attempt to connect using WPA2 encryption
Serial.println("Attempting to connect to WPA network...");
status = WiFi.begin(ssid, pass);
// if unable to connect, halt
if ( status != WL_CONNECTED) {
Serial.println("Couldn't get a WiFi connection");
while(true);
}
// if the conneciton succeeded, print network info
else {
Serial.println("Connected to network");
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
}
float getTemperature() {
// get the reading from the temperature sensor
int reading = analogRead(0);
// convert that reading to voltage
float voltage = reading * 5.0;
voltage /= 1024.0;
// convert the voltage to temperature in Celsius (10mV per degree + 500mV offset)
float temperatureC = (voltage - 0.5) * 100 ;
// now convert to Fahrenheit
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
return temperatureF;
}
void loop() {
String line, temperature;
// wait 1 second
delay(1000);
// get the current temperature from the sensor, to 2 decimal places
temperature = String(getTemperature(), 2);
// concatenate the temperature into the line protocol
line = String("temperature value=" + temperature);
Serial.println(line);
// send the packet
Serial.println("Sending UDP packet...");
udp.beginPacket(host, port);
udp.print(line);
udp.endPacket();
}
从InfluxDB查询数据
数据已写入InfluxDB后,现在您可以发出查询以检索它。最快的方法是从命令行使用curl
。使用上面代码示例中提供的宿主机和端口号,以下内容将为您提供来自temperature
测量的最新点
curl -G 'https://127.0.0.1:8086/query' --data-urlencode "db=arduino" --data-urlencode "q=SELECT value FROM temperature LIMIT 1"
如果数据已成功接收,您应该看到以下行
{"results":[{"series":[{"name":"temperature","columns":["time","value"],"values":[["2015-08-27T04:09:53.883221046Z",83.2]]}]}]}
恭喜——您的数据正在被收集!
故障排除
如果您看不到任何数据点,以下是一些您可以检查的事项
- 确保WiFi盾运行最新的固件
- 确保InfluxDB内部的UDP接口已启用,并且已重新启动服务
- 确保主机和端口与您的实际InfluxDB实例匹配
- 确保WiFi或以太网盾已成功连接到网络
- 确保您要写入的数据库已被创建
下一步
- 下载InfluxDB
- 了解更多关于开源平台
希望上述之一能帮助您回到正轨。祝你好运!