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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
// Copyright (C) 2026 Jorge Andre Castro
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//! Driver async no_std pour le capteur de température et d'humidité AM2302 (DHT22).
//! Compatible avec toutes les cartes et tous les exécuteurs via `embedded-hal`.
//!
//! ## Caractéristiques
//!
//! - `#![no_std]` — aucune dépendance à la bibliothèque standard
//! - Zéro dépendance Embassy — fonctionne avec n'importe quel exécuteur async
//! - Compatible RP2040, STM32, nRF, ESP32… via les traits `embedded-hal`
//! - Protocole 1-Wire implémenté bit à bit
//! - Vérification de la somme de contrôle (checksum) intégrée
//! - Support des températures négatives
//!
//! ## Protocole de communication
//!
//! Le DHT22 utilise un protocole 1-Wire propriétaire :
//!
//! ```text
//! Maître ──── 20ms bas ────┐
//! Capteur └── 80µs bas ── 80µs haut ──┐
//! Bit 0 : 50µs bas + ~28µs haut │ × 40 bits
//! Bit 1 : 50µs bas + ~70µs haut │
//! ```
//!
//! Un signal haut `> 40µs` est interprété comme un bit `1`, sinon bit `0`.
//!
//! ## Format des données
//!
//! Les 40 bits reçus sont répartis en 5 octets :
//!
//! ```text
//! [0] humidité (partie entière)
//! [1] humidité (partie décimale)
//! [2] température (partie entière, bit 7 = signe négatif)
//! [3] température (partie décimale)
//! [4] checksum = [0] + [1] + [2] + [3]
//! ```
//!
//! ## Exemple — Embassy RP2040
//!
//! ```rust,ignore
//! use embassy_rp::gpio::Flex;
//! use embassy_time::Delay;
//! use embassy_am2302::am2302_read;
//!
//! #[embassy_executor::task]
//! async fn sensor_task(mut pin: Flex<'static>) {
//! let mut delay = Delay;
//! loop {
//! match am2302_read(&mut pin, &mut delay).await {
//! Ok(data) => ENV_SIGNAL.signal(data),
//! Err(_) => {}
//! }
//! delay.delay_ms(3000).await;
//! }
//! }
//! ```
use ;
use DelayNs;
/// Données environnementales lues depuis le capteur AM2302.
///
/// Les valeurs sont exprimées en unités physiques directement exploitables,
/// après décodage du format binaire DHT22 et division par 10.
///
/// # Champs
///
/// * `temp` — température en degrés Celsius (négatif possible)
/// * `hum` — humidité relative en pourcentage `[0.0, 100.0]`
/// Erreurs possibles lors de la lecture du capteur AM2302.
/// Lit une seule mesure depuis le capteur AM2302.
///
/// # Arguments
///
/// * `pin` — broche GPIO implémentant [`InputPin`] + [`OutputPin`]
/// * `delay` — implémentation async de [`DelayNs`] fournie par le HAL
///
/// # Retour
///
/// `Ok(EnvData)` si la lecture et le checksum sont valides,
/// `Err(Am2302Error)` sinon.
///
/// # Exemple
///
/// ```rust,ignore
/// match am2302_read(&mut pin, &mut delay).await {
/// Ok(data) => defmt::info!("{}°C {}%", data.temp, data.hum),
/// Err(Am2302Error::ChecksumMismatch) => defmt::warn!("Données corrompues"),
/// Err(Am2302Error::Timeout) => defmt::warn!("Capteur ne répond pas"),
/// Err(Am2302Error::Gpio(_)) => defmt::error!("Erreur GPIO"),
/// }
/// ```
pub async