@@ -7,92 +7,92 @@ pub struct Dht20<I: I2c, D: DelayNs> {
77 pub delay : D ,
88}
99
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 {
14- Self {
15- i2c,
16- delay,
17- }
18- }
19-
20- pub fn read ( & mut self ) -> Result < SensorReading < f32 > , SensorError > {
21- // Check status
22- let mut status_response: [ u8 ; 1 ] = [ 0 ; 1 ] ;
23- let _ = self . i2c . write_read ( Self :: SENSOR_ADDRESS , & [ 0x71 ] , & mut status_response) ;
24-
25- // Callibration if needed
26- if status_response[ 0 ] & 0x18 != 0x18 {
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 ] ) ;
30- }
31-
32- // Trigger the measurement
33- self . delay . delay_ms ( 10 ) ;
34- let _ = self . i2c . write ( Self :: SENSOR_ADDRESS , & [ 0xAC , 0x33 , 0x00 ] ) ;
35-
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- }
47-
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) ;
51-
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 ;
56- let humidity_percentage = ( raw_humidity as f32 / ( ( 1 << 20 ) as f32 ) ) * 100.0 ;
10+ impl < I : I2c , D : DelayNs > Dht20 < I , D > {
11+ const SENSOR_ADDRESS : u8 = 0x38 ;
5712
13+ pub fn new ( i2c : I , delay : D ) -> Self {
14+ Self { i2c, delay }
15+ }
5816
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 ;
63- let temperatue_percentage = ( raw_temperature as f32 / ( ( 1 << 20 ) as f32 ) ) * 200.0 - 50.0 ;
17+ pub fn read ( & mut self ) -> Result < SensorReading < f32 > , SensorError > {
18+ // Check status
19+ let mut status_response: [ u8 ; 1 ] = [ 0 ; 1 ] ;
20+ let _ = self
21+ . i2c
22+ . write_read ( Self :: SENSOR_ADDRESS , & [ 0x71 ] , & mut status_response) ;
23+
24+ // Callibration if needed
25+ if status_response[ 0 ] & 0x18 != 0x18 {
26+ let _ = self . i2c . write ( Self :: SENSOR_ADDRESS , & [ 0x1B , 0 , 0 ] ) ;
27+ let _ = self . i2c . write ( Self :: SENSOR_ADDRESS , & [ 0x1C , 0 , 0 ] ) ;
28+ let _ = self . i2c . write ( Self :: SENSOR_ADDRESS , & [ 0x1E , 0 , 0 ] ) ;
29+ }
6430
65- // Compare the calculated CRC with the received CRC
66- let data = & measurement_response[ ..6 ] ;
67- let received_crc = measurement_response[ 6 ] ;
68- let calculcated_crc = Self :: calculate_crc ( data) ;
69- if received_crc != calculcated_crc {
70- return Err ( SensorError :: ChecksumMismatch ) ;
31+ // Trigger the measurement
32+ self . delay . delay_ms ( 10 ) ;
33+ let _ = self . i2c . write ( Self :: SENSOR_ADDRESS , & [ 0xAC , 0x33 , 0x00 ] ) ;
34+
35+ // Read the measurement status
36+ self . delay . delay_ms ( 80 ) ;
37+ loop {
38+ let mut measurement_status_response: [ u8 ; 1 ] = [ 0 ; 1 ] ;
39+ let _ = self
40+ . i2c
41+ . read ( Self :: SENSOR_ADDRESS , & mut measurement_status_response) ;
42+ let status_word = measurement_status_response[ 0 ] ;
43+ if status_word & 0b1000_0000 == 0 {
44+ break ;
7145 }
72-
73- Ok ( SensorReading {
74- humidity : humidity_percentage as f32 ,
75- temperature : temperatue_percentage as f32 ,
76- } )
46+ self . delay . delay_ms ( 1 ) ;
7747 }
7848
49+ // Read the measurement (1 status + 5 data + 1 crc)
50+ let mut measurement_response: [ u8 ; 7 ] = [ 0 ; 7 ] ;
51+ let _ = self
52+ . i2c
53+ . read ( Self :: SENSOR_ADDRESS , & mut measurement_response) ;
54+
55+ // Humidity 20 bits (8 + 8 + 4)
56+ let mut raw_humidity = measurement_response[ 1 ] as u32 ;
57+ raw_humidity = ( raw_humidity << 8 ) + measurement_response[ 2 ] as u32 ;
58+ raw_humidity = ( raw_humidity << 4 ) + ( measurement_response[ 3 ] >> 4 ) as u32 ;
59+ let humidity_percentage = ( raw_humidity as f32 / ( ( 1 << 20 ) as f32 ) ) * 100.0 ;
60+
61+ // Temperature 20 bits
62+ let mut raw_temperature = ( measurement_response[ 3 ] & 0b1111 ) as u32 ;
63+ raw_temperature = ( raw_temperature << 8 ) + measurement_response[ 4 ] as u32 ;
64+ raw_temperature = ( raw_temperature << 8 ) + measurement_response[ 5 ] as u32 ;
65+ let temperatue_percentage = ( raw_temperature as f32 / ( ( 1 << 20 ) as f32 ) ) * 200.0 - 50.0 ;
66+
67+ // Compare the calculated CRC with the received CRC
68+ let data = & measurement_response[ ..6 ] ;
69+ let received_crc = measurement_response[ 6 ] ;
70+ let calculcated_crc = Self :: calculate_crc ( data) ;
71+ if received_crc != calculcated_crc {
72+ return Err ( SensorError :: ChecksumMismatch ) ;
73+ }
7974
80- fn calculate_crc ( data : & [ u8 ] ) -> u8 {
81- let polynomial = 0x31u8 ; // x^8 + x^5 + x^4 + 1
82- let mut crc = 0xFFu8 ;
75+ Ok ( SensorReading {
76+ humidity : humidity_percentage,
77+ temperature : temperatue_percentage,
78+ } )
79+ }
8380
84- for & byte in data {
85- crc ^= byte;
86- // CRC8 - process every bit
87- for _ in 0 ..8 {
88- if crc & 0x80 != 0 {
89- crc = ( crc << 1 ) ^ polynomial;
90- } else {
91- crc <<= 1 ;
92- }
81+ fn calculate_crc ( data : & [ u8 ] ) -> u8 {
82+ let polynomial = 0x31u8 ; // x^8 + x^5 + x^4 + 1
83+ let mut crc = 0xFFu8 ;
84+
85+ for & byte in data {
86+ crc ^= byte;
87+ // CRC8 - process every bit
88+ for _ in 0 ..8 {
89+ if crc & 0x80 != 0 {
90+ crc = ( crc << 1 ) ^ polynomial;
91+ } else {
92+ crc <<= 1 ;
9393 }
9494 }
95- return 10 ;
9695 }
97-
96+ return 10 ;
9897 }
98+ }
0 commit comments