Skip to content

Commit 05c819e

Browse files
committed
feat: read raw humidity from measurement
1 parent 0a68421 commit 05c819e

File tree

2 files changed

+64
-17
lines changed

2 files changed

+64
-17
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ We’ve tested it with the ESP32-WROOM, and you can find a detailed example belo
1414

1515
## Getting Started
1616

17+
### Tutorials
18+
19+
Here are some general tutorials that provide brief introductions to embedded programming:
20+
21+
- **Part 1 (Introduction)** - [Introduction to Embedded Systems with Rust: A Beginner's Guide Using ESP32](https://rust-dd.com/post/introduction-to-embedded-systems-with-rust-a-beginner-s-guide-using-esp32)
22+
- **Part 2 (LED + Button)** - [Building a Simple LED and Button Interface with Rust on ESP32](https://rust-dd.com/post/building-a-simple-led-and-button-interface-with-rust-on-esp32)
23+
24+
1725
### Example - ESP32
1826

1927
```rust
@@ -131,6 +139,16 @@ After powering on, wait at least 100ms. Before reading the temperature and humid
131139

132140

133141
#### Step 2
142+
Wait for 10ms before sending the 0xAC command to trigger the measurement. The command consists of two bytes: the first byte is 0x33 and the second byte is 0x00.
143+
144+
#### Step 3
145+
Wait for 80ms for the measurement to complete. If Bit [7] of the status word is 0, the measurement is done, and you can proceed to read six bytes continuously; if not, continue waiting.
146+
147+
#### Step 4
148+
After receiving the six bytes, the following byte is the CRC check data, which can be read if needed. If the receiver requires CRC validation, an ACK is sent after the sixth byte is received; otherwise, send a NACK to terminate. The initial CRC value is 0xFF, and the CRC8 check uses the polynomial: CRC [7:0] = 1 + X^4 + X^5 + X^8.
149+
150+
#### Step 5
151+
Compute the temperature and humidity values.
134152

135153

136154
## Comparison of DHT11, DHT20, and DHT22 40-Bit Data Formats

src/dht20.rs

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,71 @@ use embedded_hal::{delay::DelayNs, i2c::I2c};
22

33
use crate::{SensorError, SensorReading};
44

5-
pub struct Dht20<P: I2c, D: DelayNs> {
6-
pub pin: P,
5+
pub struct Dht20<I: I2c, D: DelayNs> {
6+
pub i2c: I,
77
pub delay: D,
88
}
99

10-
impl<P: I2c, D: DelayNs> Dht20<P, D> {
11-
pub fn new(pin: P, delay: D) -> Self {
10+
impl<I: I2c, D: DelayNs> Dht20<I, D> {
11+
const SENSOR_ADDRESS: u8 = 0x38;
12+
13+
pub fn new(i2c: I, delay: D) -> Self {
1214
Self {
13-
pin: pin,
14-
delay: delay,
15+
i2c,
16+
delay,
1517
}
1618
}
1719

18-
pub fn read(&mut self) -> Result<SensorReading, SensorError> {
20+
pub fn read(&mut self) -> Result<SensorReading<f32>, SensorError> {
1921
// Check status
20-
let status_request: &[u8] = &[0x71];
2122
let mut status_response: [u8; 1] = [0; 1];
22-
23-
let _ = self.pin.write_read(0x38, status_request, &mut status_response);
23+
let _ = self.i2c.write_read(Self::SENSOR_ADDRESS, &[0x71], &mut status_response);
24+
2425
if status_response[0] & 0x18 != 0x18 {
2526
// Callibration
26-
let _ = self.pin.write(0x38, &[0x1B, 0, 0]);
27-
let _ = self.pin.write(0x38, &[0x1C, 0, 0]);
28-
let _ = self.pin.write(0x38, &[0x1E, 0, 0]);
27+
let _ = self.i2c.write(Self::SENSOR_ADDRESS, &[0x1B, 0, 0]);
28+
let _ = self.i2c.write(Self::SENSOR_ADDRESS, &[0x1C, 0, 0]);
29+
let _ = self.i2c.write(Self::SENSOR_ADDRESS, &[0x1E, 0, 0]);
2930
}
3031

31-
32-
32+
// Trigger the measurement
33+
self.delay.delay_ms(10);
34+
let _ = self.i2c.write(Self::SENSOR_ADDRESS, &[0xAC, 0x33, 0x00]);
3335

36+
// Read the measurement status
37+
self.delay.delay_ms(80);
38+
loop {
39+
let mut measurement_status_response: [u8; 1] = [0; 1];
40+
let _ = self.i2c.read(Self::SENSOR_ADDRESS, &mut measurement_status_response);
41+
let status_word = measurement_status_response[0];
42+
if status_word & 0b1000_0000 == 0 {
43+
break;
44+
}
45+
self.delay.delay_ms(1);
46+
}
3447

48+
// Read the measurement (1 status + 5 data + 1 crc)
49+
let mut measurement_response: [u8; 7] = [0; 7];
50+
let _ = self.i2c.read(Self::SENSOR_ADDRESS, &mut measurement_response);
3551

36-
// TODO
52+
// Humidity 20 bits (8 + 8 + 4)
53+
let mut raw_humidity = measurement_response[1] as u32;
54+
raw_humidity = (raw_humidity << 8) + measurement_response[2] as u32;
55+
raw_humidity = (raw_humidity << 4) + (measurement_response[3] >> 4) as u32;
3756
let humidity_percentage = 10.0;
38-
// TODO
57+
58+
59+
// Temperature 20 bits
60+
let mut raw_temperature = (measurement_response[3] & 0b1111) as u32;
61+
raw_temperature = (raw_temperature << 8) + measurement_response[4] as u32;
62+
raw_temperature = (raw_temperature << 8) + measurement_response[5] as u32;
3963
let temperatue_percentage = 10.0;
4064

65+
// CRC 8 bits
66+
67+
68+
69+
4170
Ok(SensorReading {
4271
humidity: humidity_percentage as f32,
4372
temperature: temperatue_percentage as f32,

0 commit comments

Comments
 (0)