rs-dht-pio/readme_fr.md
2023-11-05 15:09:18 +01:00

4.4 KiB

DHT PIO Rust Library

crates.io MIT GitHub

english version

Pourquoi ?

Les DHT (22 ou 11) utilisent un protocole 1-Wire, qui n'est pas compatible avec le protocole du même nom de Dallas Semicondutors. Le Raspberry Pico (comme d'autres microcontrôleurs) ne possède pas de périphérique dédié à ce protocole.

De nombreuses crates existes pour utiliser le DHT via un pin digital, mais après en avoir testée plusieurs, leur fonctionnement n'est pas fiable. Le problème vient de l'implémentation de la embedded_hal par rp2040_hal. La manipulation de l'état et de la direction d'une pin, prend trop de temps (j'ai pu mesure entre 2µs et 6µs suivant l'action demandée). Venant, entre autre, de l'impossibilité de mettre une pin en drain ouvert ("open drain"), ce qui nécessite de "simuler" ce comportant.

Le PIO ❤️

Le chip RP2040 (utilisé pour le Pico), possède un périphérique un peu atypique nommée PIO (Programmable Input/Output), Chapitre 3 de la DataSheet. En simplifiant, le principe est de pouvoir faire tourner un petit programme (32 instruction max), qui s'éxécutera de manière indépendante. Il peut manipuler les GPIO et partager des informations avec le programme principal.

Le PIO se programme à l'aide d'un assembleur nommé pioasm, il ne comporte que quelques instructions très basiques. Le plus intéressant est que chaque instruction prends (en général), 1 cycle pour s'exécute. De plus il est possible de diviser la clock à laquelle le programme s'éxécute. Dans le notre cas, on disive la clock principale, de 125 MHz, par 125, ce qui nous donne une instruction par microsecondes.

Usage

Dans un premier temps créer récupérer les objets PIO

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

Pour créer un nouvelle objet:

  • 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());
    

Lire les données:

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

NB: read renvoi un Result<DhtResult, DhtError>.

DHT22 Type 2 🧐

Il semble qu'il existe deux versions de DHT22. Je n'ai rien trouvé de vraiment probant, mais ce qui est certain c'est que tous les DHT22 n'ont pas le même format de donnée... Dans un cas le format est le même que présenté dans (quasi) toutes les datasheet, à savoir le bit de poids fort est à l'état 1 si le nombre est négatif, mais la représentation binaire de la valeur absolue de la température n'en est pas changée. Par exemple:

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

C'est comme cela que la struct Dht22 va "décoder" les données en provenance du capteur. Or je suis tombé sur des capteurs qui ne fonctionnaient pas du tout comme cela. Mais de manière (au final) plus logique. Puisque les données sont représentées en complément à deux. Dans ce cas il faut utiliser Dht22Type2. Par exemple:

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

Pour simplifier si votre capteur est un DHT22 mais que les valeurs ne semblent pas cohérentes (valeurs négatives) alors essayez le "Type 2" (et si vraiment rien ne marche, ouvrez une issue 😉).

Support

Board

Pour le moment le crates n'a été testé que sur un Raspberry Pico.

DHT

DHT22
DHT11

TODO

  • Finir le Readme
  • Ajouter la lecture du CRC
  • Vérifier le CRC
  • Support du DHT11
  • Tester DHT11
  • Documenter le code

Remerciement

Geir Ertzaas (grukx), pour avoir découvert (trop?) de bugs.