embedded_hdc1080_rs/
lib.rs

1#![deny(unsafe_code)]
2#![no_std]
3use embedded_hal::blocking::{
4    delay::DelayMs,
5    i2c::{Write, WriteRead, Read},
6};
7
8const I2C_ADDRESS: u8 = 0x40;
9
10
11/// Error.
12#[derive(Debug, Copy, Clone)]
13pub enum Error<E> {
14    /// Device is not calibrated.
15    Uncalibrated,
16    /// Underlying bus error.
17    Bus(E),
18    /// Checksum mismatch.
19    Checksum,
20}
21
22/// Resolution of temperature
23#[derive(Debug, Clone, Copy)]
24pub enum TResolution {
25    /// 11 bits
26    _11,
27    /// 14 bits
28    _14,
29}
30
31/// Resolution of humidity
32#[derive(Debug, Clone, Copy)]
33pub enum HResolution {
34    /// 8 bits
35    _8,
36    /// 11 bits
37    _11,
38    /// 14 bits
39    _14,
40}
41
42/// Registers 
43struct Register;
44
45impl Register {
46    const TEMPERATURE: u8 = 0x00;
47    const HUMIDITY: u8 = 0x01;
48    const CONFIGURATION: u8 = 0x02;
49    const SERIAL_ID1: u8 = 0xFB;
50    const SERIAL_ID2: u8 = 0xFC;
51    const SERIAL_ID3: u8 = 0xFD;
52    const MANUFACTURER: u8 = 0xFE;
53    const DEVICE_ID: u8 = 0xFF;
54}
55
56/// configuration masks
57/// used when setting device configuration : 
58/// device.set_config(0x00|ConfigBitFlags::T_MODE|ConfigBitFlags::MODE| ConfigBitFlags::H_MODE8 & !ConfigBitFlags::H_MODE9)
59struct ConfigBitFlags;
60
61impl ConfigBitFlags {
62    const RST: u16 = 0b1000_0000_0000_0000;
63    const HEAT: u16 = 0b0010_0000_0000_0000;
64    const MODE: u16 = 0b0001_0000_0000_0000;
65    const BTST: u16 = 0b0000_1000_0000_0000;
66    const T_MODE: u16 = 0b0000_0100_0000_0000;
67    const H_MODE9: u16 = 0b000_0010_0000_0000;
68    const H_MODE8: u16 = 0b000_0001_0000_0000;
69}
70
71pub struct Hdc1080<I2C, D> {
72    i2c: I2C,
73    config: u16,
74    delay: D,
75}
76
77impl<I2C, D, E> Hdc1080<I2C, D> where
78    I2C: WriteRead<Error = E> + Write<Error = E>+ Read<Error = E>,
79    D: DelayMs<u16>,
80{
81    /// New HDC1080 device from an I2C peripheral.
82    /// default: temperature 11-bit humidity 11-b
83    pub fn new(i2c: I2C, delay: D ) -> Result<Self, Error<E>> {
84        let dev = Self {
85            i2c: i2c,
86            delay: delay,
87            config:0x00|ConfigBitFlags::T_MODE|ConfigBitFlags::MODE| ConfigBitFlags::H_MODE8 & !ConfigBitFlags::H_MODE9
88        };
89
90        Ok(dev)
91    }
92
93    /// Init with default config
94    pub fn init(& mut self) -> Result<(), E>{
95        self.set_config(self.config).unwrap_or_default();
96        Ok(())
97    }
98
99    /// Soft resets the sensor.
100    pub fn reset(&mut self) -> Result<(), E> {
101        // Send soft reset command
102        let bytes:[u8;2] = ConfigBitFlags::RST.to_be_bytes();
103        self.i2c.write(I2C_ADDRESS, &[Register::CONFIGURATION, bytes[0]]).unwrap_or_default();
104
105        self.delay.delay_ms(10);
106
107        Ok(())
108    }
109
110    /// Set temperature resolution
111    pub fn set_t_resolution(& mut self, resolution: TResolution) -> Result<(), E> {
112        match resolution {
113            TResolution::_11 => self.set_config(self.config | ConfigBitFlags::T_MODE).unwrap_or_default(),
114            TResolution::_14 => self.set_config(self.config & !ConfigBitFlags::T_MODE).unwrap_or_default(),
115        }
116        Ok(())
117    }
118
119    /// Set humidity resolution
120    pub fn set_h_resolution(& mut self, resolution: HResolution) -> Result<(), E> {
121        match resolution {
122            HResolution::_8 => self.set_config(self.config & !ConfigBitFlags::H_MODE8 | ConfigBitFlags::H_MODE9).unwrap_or_default(),
123            HResolution::_11 => self.set_config(self.config | ConfigBitFlags::H_MODE8 & !ConfigBitFlags::H_MODE9).unwrap_or_default(),
124            HResolution::_14 => self.set_config(self.config & !ConfigBitFlags::H_MODE8 & !ConfigBitFlags::H_MODE9).unwrap_or_default(),
125        }
126        Ok(())
127    }
128
129    /// Read config from register
130    pub fn read_config(& mut self) -> Result<u16, E>{
131        let mut current_config:[u8;2] = [0,0];
132        let result = self.i2c.write_read(I2C_ADDRESS, &[Register::CONFIGURATION], &mut current_config).unwrap_or_default();
133        
134        Ok(u16::from_be_bytes(current_config))
135    }
136
137    /// Set config from u16
138    pub fn set_config(& mut self, bits:u16) -> Result<(), E> {
139        self.config = bits;
140        let conf_u8: [u8;2] = self.config.to_be_bytes();
141        self.i2c.write(I2C_ADDRESS, &[Register::CONFIGURATION, conf_u8[0]]).unwrap_or_default();
142        self.delay.delay_ms(10);
143        Ok(())
144    }
145
146    /// Read temperature and humidity
147    pub fn read(& mut self) -> Result<(f32, f32),Error<E>> {
148        let mut buf:[u8;4] = [0,0,0,0];
149        let t_raw_u16:u16 ;
150        let h_raw_u16:u16 ;
151        let temper:f32;
152        let humm:f32;
153
154        self.i2c.write(I2C_ADDRESS, &[Register::TEMPERATURE]).unwrap_or_default();
155        self.delay.delay_ms(20);
156        self.i2c.read(I2C_ADDRESS,&mut buf).unwrap_or_default();
157        t_raw_u16 = u16::from_be_bytes([buf[0], buf[1]]);
158        temper = f32::from(t_raw_u16) / 65536.0 * 165.0 - 40.0;
159
160        if self.config & ConfigBitFlags::MODE != 0 {
161            h_raw_u16 = u16::from_be_bytes([buf[2], buf[3]]);
162            humm = f32::from(h_raw_u16) / 65536.0 * 100.0;
163        } else {
164            humm = self.humidity().unwrap_or_default();
165        }
166
167        Ok((temper, humm))
168    }
169
170    /// Temperature only
171    pub fn temperature(& mut self) -> Result<f32,Error<E>> {
172        let mut buf:[u8;2] = [0,0];
173        let result:u16 ;
174        let temper:f32;
175
176        self.i2c.write(I2C_ADDRESS, &[Register::TEMPERATURE]).unwrap_or_default();
177        self.delay.delay_ms(20);
178        self.i2c.read(I2C_ADDRESS,&mut buf).unwrap_or_default();
179
180        result = u16::from_be_bytes(buf);
181        temper = f32::from(result) / 65536.0 * 165.0 - 40.0;
182        Ok(temper)
183    }
184
185    /// Humidity only
186    pub fn humidity(& mut self) -> Result<f32,Error<E>> {
187        let mut buf:[u8;2] = [0,0];
188        let result:u16 ;
189        let humid:f32;
190
191        self.i2c.write(I2C_ADDRESS, &[Register::HUMIDITY]).unwrap_or_default();
192        self.delay.delay_ms(20);
193        self.i2c.read(I2C_ADDRESS,&mut buf).unwrap_or_default();
194
195        result = u16::from_be_bytes(buf);
196        humid = f32::from(result) / 65536.0 * 100.0;
197        Ok(humid)
198    }
199
200    /// Device ID. Expect u16 0x1050
201    pub fn get_device_id(&mut self) -> Result<u16, Error<E>> {
202        let mut buf:[u8;2] = [0,0];
203        let result:u16 ;
204        self.i2c.write_read(I2C_ADDRESS, &[Register::DEVICE_ID],&mut buf).unwrap_or_default();
205        result = ((buf[0] as u16)<<8)|(buf[1] as u16);
206        Ok(result)
207    }
208
209    /// Manufacturer ID. Expect u16 0x5449
210    pub fn get_man_id(&mut self) -> Result<u16, Error<E>> {
211        let mut buf = [0u8; 2];
212        let result:u16 ;
213        self.i2c.write_read(I2C_ADDRESS, &[Register::MANUFACTURER],&mut buf).unwrap_or_default();
214        result = ((buf[0] as u16)<<8)|(buf[1] as u16);
215        Ok(result)
216    }
217
218    /// Serial ID. Expect [u16;3]
219    pub fn get_serial_id(&mut self) -> Result<[u16;3], Error<E>> {
220        let mut buf1 = [0u8; 2];
221        let mut buf2 = [0u8; 2];
222        let mut buf3 = [0u8; 2];
223        let mut result: [u16;3] = [0,0,0] ;
224        self.i2c.write_read(I2C_ADDRESS,&[Register::SERIAL_ID1], &mut buf1 ).unwrap_or_default();
225        self.i2c.write_read(I2C_ADDRESS,&[Register::SERIAL_ID2], &mut buf2 ).unwrap_or_default();
226        self.i2c.write_read(I2C_ADDRESS,&[Register::SERIAL_ID3], &mut buf3 ).unwrap_or_default();
227        result[0] = u16::from_be_bytes(buf1);
228        result[1] = u16::from_be_bytes(buf2);
229        result[2] = u16::from_be_bytes(buf3);
230        Ok(result)
231    }
232
233    /// Returns true if battery voltage is under 2.8v
234    pub fn battery_low(&mut self) -> Result<bool, E> {
235        let config = self.read_config().unwrap_or_default();
236        Ok((config & ConfigBitFlags::BTST) == ConfigBitFlags::BTST)
237    }
238
239}