Workbench on Elysium

「Nice try.」

在树莓派上使用SHTC3/SHTC1温湿度传感器

Apache553's Avatar 2020-12-26 折腾记录

在树莓派上接温湿度传感器是很常见的操作,然而对于SHTC1/SHTC3的传感器而言,虽然有内核驱动可以直接用,但是似乎并没有现成的dtoverlay可用,导致在使用方面的不便(在用户空间请求加载导致生成的hwmon sysfs的目录顺序不定)。

写在前面

根据shtc1内核模块的代码,该驱动对于shtc1、shtc3、shtw1型号的芯片的传感器都可通用。拥有这些型号传感器的用户也可使用本文中的方法。对于其他型号的芯片的用户,只要是基于i2c总线的芯片,按理说也可以依葫芦画瓢来使用。

最开始我用的办法是在rc.local中加入一行

1
echo shtc1 0x70 > /sys/bus/i2c/devices/i2c-1/new_device

来让内核加载驱动。然而因为不明原因让他生成的hwmon目录在hwmon2hwmon3之间反复横跳,结果就是完全难以使用。

设备树叠加层

树莓派和其他不少arm设备一样,使用了device tree overlay的机制来”动态”在设备树上增添条目,我们也要用到它来让树莓派自动加载我们的传感器驱动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/dts-v1/;
/plugin/;

/ {
compatible = "brcm,bcm2835";

fragment@0 {
target = <&i2c_arm>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";

shtc1: shtc1@70 {
compatible = "shtc1";
reg = <0x70>;
status = "okay";
};
};
};

__overrides__ {
addr = <&shtc1>,"reg:0";
};
};

以上就是为了加载传感器驱动而写出的设备树叠加层。

其中fragment@0段包括了了我们要叠加的目标和内容,其中的target属性指明了我们要附加到的设备树节点是i2c_arm__overlay__段实际定义了我们的叠加内容:一个名为shtc1@70的节点,别名为shtc1。其中的compatible属性指明了该设备兼容的驱动名字,由于我们要使用shtc1模块作为其驱动,根据驱动源代码里定义的device id table中的值,这里填入了shtc1reg属性指明了这个i2c设备的地址。设置statusokay表示启用这个节点。

在下面的__overrides__段,有一个addr = <&shtc1>,"reg:0",根据树莓派官方给的文档,其表示定义了一个dtoverlay参数addr,其指向shtc1节点的reg属性的偏移为0的值(即第一个值)。这样我们就可以在config.txt中写入类似于dtoverlay=shtc1-i2c,addr=0x69之类的东西来指定这个设备对应的i2c地址,而不用重新编译dtbo。

使用

将上述代码保存为shtc1-i2c.dts,在树莓派上执行命令

1
dtc -@ -I dts -O dtb -o shtc1-i2c.dtbo shtc1-i2c.dts

将他编译成内核可以用的二进制格式

如果提示未找到命令,你可能需要安装device-tree-compiler包,或者从其他地方获取dtc程序。

然后将编译出来的shtc1-i2c.dtbo文件拷贝到/boot/overlays/文件夹下。

如果直接使用上面提供的代码编译的话,最后在/boot/config.txt中加入一行

1
dtoverlay=shtc1-i2c

保存后重启树莓派,应该就能在/sys/class/hwmon/下找到传感器驱动注册的hwmon目录了。

Enjoy~

本文最后更新于 天前,文中所描述的信息可能已发生改变