Skip to content

Commit dc8364d

Browse files
committed
feat: add checksum checking; update docs
1 parent 7b0fe33 commit dc8364d

File tree

3 files changed

+38
-24
lines changed

3 files changed

+38
-24
lines changed

README.md

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,44 +44,49 @@ fn main() -> ! {
4444

4545
loop {
4646
delay.delay(1000.millis());
47-
let reading = led_sensor.read().unwrap();
48-
log::info!(
49-
"Temperature: {}, humidity: {}",
50-
reading.temperature,
51-
reading.humidity
52-
);
47+
match led_sensor.read() {
48+
Ok(sensor_reading) => log::info!(
49+
"Temperature: {}, humidity: {}",
50+
sensor_reading.temperature,
51+
sensor_reading.humidity
52+
),
53+
Err(error) => log::error!("An error occurred while trying to read sensor: {:?}", error),
54+
}
5355
}
5456
}
5557
```
5658

57-
---
59+
![running](/docs/example_esp32_dht11_running.png)
60+
61+
62+
## Implementation Specification
5863

5964
![steps](/docs/steps.png)
6065

61-
## Step 1
66+
### Step 1
6267

6368
After powering on the DHT11 (once powered, allow 1 second to pass during which the sensor stabilizes; during this time, no commands should be sent), it measures the temperature and humidity of the surrounding environment and stores the data. Meanwhile, the DATA line of the DHT11 is kept high by a pull-up resistor. The DATA pin of the DHT11 is in input mode, ready to detect any external signals.
6469

65-
## Step 2
70+
### Step 2
6671

6772
The microprocessor's I/O pin is set to output mode and pulled low, holding this state for at least 18 milliseconds. Then, the microprocessor's I/O is switched to input mode. Due to the pull-up resistor, the microprocessor’s I/O line and the DHT11 DATA line will remain high, waiting for the DHT11 to respond with a signal, as illustrated below:
6873

6974
![step2](/docs/step2.png)
7075

7176

72-
## Step 3
77+
### Step 3
7378

7479
The DHT11’s DATA pin detects an external signal and goes low, indicating that it is waiting for the external signal to complete. Once the signal ends, the DHT11’s DATA pin switches to output mode, producing a low signal for 80 microseconds as a response. This is followed by an 80-microsecond high signal, notifying the microprocessor that the sensor is ready to transmit data. At this point, the microprocessor's I/O pin, still in input mode, detects the low signal from the DHT11 (indicating the response) and then waits for the 80-microsecond high signal to start receiving data. The sequence of signal transmission is illustrated below:
7580

7681
![step3](/docs/step3.png)
7782

78-
## Step 4
83+
### Step 4
7984

8085
The DHT11 outputs 40 bits of data through the DATA pin, and the microprocessor receives these 40 data bits. The format for a data bit "0" consists of a low level lasting 50 microseconds, followed by a high level lasting 26-28 microseconds, depending on changes in the I/O level. For a data bit "1," the format includes a low level of 50 microseconds followed by a high level lasting up to 70 microseconds. The signal formats for data bits "0" and "1" are shown below.
8186

8287
![step4](/docs/step4.png)
8388

84-
# End signal
89+
### End signal
8590

8691
After outputting a low signal for 50 microseconds, the DHT11 completes sending the 40 bits of data and switches the DATA pin back to input mode, which, along with the pull-up resistor, returns to a high state. Meanwhile, the DHT11 internally re-measures the environmental temperature and humidity, records the new data, and waits for the next external signal.
8792

103 KB
Loading

src/lib.rs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@ pub struct SensorReading {
1515
pub temperature: i8,
1616
}
1717

18+
#[derive(Debug)]
19+
pub enum SensorError {
20+
ChecksumMismatch,
21+
}
22+
1823
impl<P: InputPin + OutputPin, D: DelayNs> Dht11<P, D> {
1924
pub fn new(pin: P, delay: D) -> Self {
20-
Self { pin, delay }
25+
Self { pin, delay }
2126
}
2227

23-
pub fn read(&mut self) -> Result<SensorReading, <P as ErrorType>::Error> {
28+
pub fn read(&mut self) -> Result<SensorReading, SensorError> {
2429
// Start communication: pull pin low for 18ms, then release.
2530
let _ = self.pin.set_low();
2631
self.delay.delay_ms(18);
@@ -34,21 +39,25 @@ impl<P: InputPin + OutputPin, D: DelayNs> Dht11<P, D> {
3439
let _ = self.wait_until_state(PinState::Low);
3540

3641
// Start reading 40 bits
37-
let humidity_integer = self.read_byte();
38-
let humidity_decimal = self.read_byte();
39-
let temperature_integer = self.read_byte();
40-
let temperature_decimal = self.read_byte();
41-
let checksum = self.read_byte();
42+
let humidity_integer = self.read_byte()?;
43+
let humidity_decimal = self.read_byte()?;
44+
let temperature_integer = self.read_byte()?;
45+
let temperature_decimal = self.read_byte()?;
46+
let checksum = self.read_byte()?;
47+
48+
// Checksum
49+
let sum = humidity_integer + humidity_decimal + temperature_integer + temperature_decimal;
50+
if sum != checksum {
51+
return Err(SensorError::ChecksumMismatch);
52+
}
4253

43-
// TODO
44-
// panic!("{:?} {:?} {:?} {:?} {:?}", humidity_integer, humidity_decimal, temperature_integer, temperature_decimal, checksum);
4554
Ok(SensorReading {
46-
humidity: humidity_integer.unwrap(),
47-
temperature: temperature_integer.unwrap() as i8,
55+
humidity: humidity_integer,
56+
temperature: temperature_integer as i8,
4857
})
4958
}
5059

51-
fn read_byte(&mut self) -> Result<u8, <P as ErrorType>::Error> {
60+
fn read_byte(&mut self) -> Result<u8, SensorError> {
5261
let mut byte: u8 = 0;
5362
for n in 0..8 {
5463
let _ = self.wait_until_state(PinState::High);

0 commit comments

Comments
 (0)