读取 Maxim 1-Wire 温度传感器
作者:Noah Crowley / 用例, 产品, 开发者
2019 年 9 月 5 日
导航至
我最喜欢的传感器之一是 Maxim DS18*20 系列,这是一系列廉价的温度传感器,它们通过称为 1-Wire 的“单触点串行接口”进行通信。多年来,我一直将它们集成到各种项目中,它们始终可靠、准确且极其易于使用。这部分归功于它们使用单触点进行通信——当您希望在嵌入式计算机或微控制器上节省引脚时,这非常宝贵——但也归功于 Linux 内核中内置的 w1_therm
驱动程序,这意味着它们可以在任何具有适当物理接口的 Linux 机器上工作。
为了举例说明,我们将使用带有连接到 GPIO 引脚的 DS18B20 的 Raspberry Pi。您可以在这篇博文中找到接线图。我们将加载 w1_therm
内核模块以及 w1_gpio
模块,该模块使用 GPIO API 来提供 1-Wire 接口
modprobe w1_gpio
modprobe w1_therm
启用内核模块后,传感器现在可以通过 sysfs 接口作为单独的目录访问。我们可以使用带有某些通配符的 ls
命令来查找有关我们传感器的信息
$ ls -laH /sys/class/hwmon/hwmon*
total 0
drwxr-xr-x 3 root root 0 Apr 24 23:59 .
drwxr-xr-x 3 root root 0 Apr 24 23:59 ..
lrwxrwxrwx 1 root root 0 Apr 24 23:59 device -> ../../../28-000002e36be9
-r--r--r-- 1 root root 4096 Apr 24 23:59 name
drwxr-xr-x 2 root root 0 Apr 24 23:59 power
lrwxrwxrwx 1 root root 0 Apr 24 23:59 subsystem -> ../../../../../class/hwmon
-r--r--r-- 1 root root 4096 Apr 24 23:59 temp1_input
-rw-r--r-- 1 root root 4096 Apr 24 23:59 uevent
在此目录中,您会找到各种文件,包括指向设备本身的符号链接、传感器名称以及名为 temp1_input
的文件,您可以读取该文件以获取传感器温度,单位为摄氏度 * 1000
$ cat /sys/class/hwmon/hwmon0/temp1_input
27562
此外,您可以通过读取 /sys/class/hwmon/hwmon0/device/w1_slave file
来访问有关传感器的更多信息,它看起来像这样
$ cat /sys/class/hwmon/hwmon0/device/w1_slave
bb 01 4b 46 7f ff 05 10 c6 : crc=c6 YES
bb 01 4b 46 7f ff 05 10 c6 t=27678
这在左侧显示设备的十六进制输出,右侧显示 CRC 错误检查和温度读数的结果。
Telegraf 的 Temp 插件
Telegraf 的 temp
输入插件在每次采集期间从文件系统读取有关温度传感器的数据。您可以使用官方 InfluxData 存储库在 Raspberry Pi 上安装 Telegraf 和 InfluxDB。安装完成后,我们可以通过取消注释 /etc/telegraf/telegraf.conf
中的以下部分来配置 Telegraf
# # Read metrics about temperature
[[inputs.temp]]
# # no configuration
由于除了启用插件之外没有其他配置,我们可以重启 Telegraf,并且应该看到数据开始出现在 telegraf
数据库的 temp
测量中(因为我们使用的是默认配置)。
使用多个传感器
不幸的是,当前 temp 插件的实现存在一个缺点:它仅支持单个传感器。这是因为 DS18*20 传感器以及 Telegraf 的 temp
插件用来访问文件系统的库:gopsutil 存在问题。
当使用 gopsutil 读取温度时,该库使用来自文件系统的数据生成 SensorKey,其中包括 label
文件。以下是 内核文档 对这些文件的说明
temp[1-*]_label Suggested temperature channel label.
Text string
Should only be created if the driver has hints about what
this temperature channel is being used for, and user-space
doesn't. In all other cases, the label is provided by
user-space.
RO
由于 DS18B20 和其他类似传感器的应用可能有所不同,因此驱动程序是通用的,并且没有任何关于温度通道用途的信息,因此不会创建此文件。这意味着当 Telegraf 从多个传感器收集数据时,它们的标签值是相同的,因为它们都具有相同的 SensorKey
。因此,即使我们从每个传感器收集数据,数据点也具有相同的元数据和时间戳,因此会相互覆盖。我们可以通过使用 --test
参数运行 Telegraf 来验证这一点,这将把行协议打印到命令行。
使用 Python 的多传感器解决方法
我们可以解决此问题的一种方法是使用 Python 脚本读取数据(您可以在此处找到示例 gist),并使用 Telegraf 的 exec
插件来执行脚本。
下载脚本并将其复制到更永久的位置;现在,让我们将文件放在 /usr/local/bin
中。由于我们使用官方 InfluxData 存储库安装了 Telegraf,因此 Telegraf 以 telegraf
用户身份运行,这意味着我们还需要更改脚本的权限,以便 Telegraf 可以执行该脚本,如下所示
sudo chown telegraf:telegraf /usr/local/bin/read_multiple_ds18b20.py
$ sudo chmod 755 /usr/local/bin/read_multiple_ds18b20.py
然后,我们可以通过启用 exec
插件并将文件添加到 commands
参数来配置 Telegraf 的 exec
插件以执行脚本
# # Read metrics from one or more commands that can output to stdout
[[inputs.exec]]
# ## Commands array
commands = [
"/usr/local/bin/read_multiple_ds18b20.py"
]
完整的配置文件在此处,其中包含描述默认值的注释。由于多个 DS18B20 可以共享一条数据线,因此连接额外的设备非常简单:它将共享第一个传感器使用的接地、电源和数据连接。重启 telegraf,它应该开始从每个设备收集数据。
未来改进
我有一些应用程序,每个设备使用多个温度传感器,因此如果可能的话,最好迭代内置的 temp
插件,而不是依赖我们的 Python 脚本解决方法。
一种可能性是对 gopsutil 库进行小的更改,这将为设备名称(每个 DS18*20 唯一)的 SensorKey
结构添加一个额外的字段。然后,Telegraf 可以使用该字段向数据添加额外的标签,并防止点相互覆盖。我将整理一个拉取请求,并从 gopsutil 维护者那里获得一些反馈。同时,请随意使用我的 Python 脚本,并通过我们的社区站点或直接通过 [email protected] 或 Twitter @noahcrowley 与我联系,如果您有任何问题!