#dht #raspberry-pi-pico #pico #pio

无std dht-pio

使用PIO(可编程输入/输出)实现的DHT,已在Rasberry Pi Pico上进行测试

9个版本 (4个重大更改)

0.6.0 2023年10月10日
0.5.4 2023年11月5日
0.5.3 2023年10月10日
0.4.0 2023年9月21日
0.1.0 2023年9月9日

#372 in 嵌入式开发

每月下载量 23次

MIT 许可证

21KB
414

DHT PIO Rust库

crates.io MIT GitHub

法语版本

为什么?

DHT(22或11)使用1-Wire协议,与同名的Dallas半导体协议不兼容。 Raspberry Pico(与其他微控制器一样)没有为该协议设置专用外围设备。

许多crate存在,可以通过数字引脚使用DHT,但在测试了其中几个之后,它们不能可靠地工作。主要问题是embedded_halrp2040_hal实现。操纵引脚的状态和方向花费的时间太长(我测量的时间是2µs到6µs不等,具体取决于请求的操作)。这主要是因为无法将引脚置于开漏状态,这需要“模拟”此功能。

PIO ❤️

RP2040芯片(用于Pico)有一个相当不寻常的外围设备称为PIO(可编程输入/输出),数据表第3章。简单来说,想法是能够运行一个小程序(最多32条指令),该程序独立执行。它可以操作GPIO并与其他程序共享信息。

使用名为pioasm的汇编器来编程PIO,只有几条非常基本的指令。有趣的是,每条指令(通常)执行1个周期。更重要的是,可以划分程序执行的时钟。在我们的例子中,我们将主时钟125 MHz除以125,从而得到每微秒一条指令。

用法

首先,创建并检索PIO对象

let (dht_pio, dht_sm, _, _, _) = pac.PIO0.split(&mut pac.RESETS);

创建新对象

  • DHT22
    let mut dht = Dht22::new(dht_pio, dht_sm, pins.gpio0.into_function());
    ```
    
  • DHT11
    let mut dht = Dht11::new(dht_pio, dht_sm, pins.gpio0.into_function());
    ```
    
    

读取数据

let dht_data = dht.read(&mut delay);

注意: read返回一个Result<DhtResult, DhtError>

DHT22类型2 🧐

看起来DHT22有两种版本。我还没有找到真正确凿的信息,但可以确定的是,并非所有DHT22的数据格式都相同...在一种情况下,格式与(几乎)所有数据表中的格式相同,即如果数值为负,则最高有效位设置为1,但绝对温度值的二进制表示没有改变。例如

  • 0000 0000 0110 1001 = 105 或 10.5°C
  • 1000 0000 0110 1001 = 32873 或 -10.5°C

这就是DHT22结构体如何“解码”从传感器来的数据。然而,我也遇到过一些传感器完全不符合这种工作方式。但是以一种(最终)更合理的方式。因为数据是以二进制补码表示的。在这种情况下,使用Dht22Type2。例如

  • 0000 0000 0110 1001 = 105 即 10.5°C
  • 1111 1111 1001 0111 = 65431 即 -10.5°C

为了简化,如果你的传感器是DHT22,但数值看起来不一致(有负值),那么尝试“类型2”(如果真的什么都没用,就打开出口吧 😉 )。

支持

板子

目前,这些crate只在Raspberry Pico上进行了测试。

DHT

✅ DHT22
❔ DHT11

待办事项

  • 完成Readme
  • 添加CRC读取
  • 检查CRC
  • DHT11支持
  • 测试DHT11
  • 记录代码

感谢

Geir Ertzaas (grukx),积极发现(太多?)错误。

依赖关系

~11–19MB
~276K SLoC