fs1027_dg_hal/lib.rs
1//! # fs1027-dg-hal sensor driver
2//!
3//! The crate provides a basic sensor driver based on the I²C interface provided.
4//!
5//! The sensor's sheet can be found [here](https://www.renesas.com/us/en/document/dst/fs1027-dg-datasheet?language=en&r=1488711)
6//!
7//! Other versions of this sensor might work, but are not supported.
8
9#![deny(unsafe_code, warnings)]
10#![no_std]
11
12extern crate embedded_hal as hal;
13use core::marker::PhantomData;
14
15use embedded_hal::blocking::i2c::Read;
16
17///An instance of the driver that does not *own* the I²C bus.
18pub struct Fs1027DgBusless<I2C: Read>{
19 i2c: PhantomData<I2C>,
20 addr: u8,
21 read_buffer: [u8; 5],
22}
23
24///Driver definition that owns the I²C bus. Saver, since it can ensure that the
25/// BUS is always the same.
26pub struct Fs1027Dg<I2C: Read> {
27 i2c: I2C,
28 busless: Fs1027DgBusless<I2C>,
29}
30
31impl<I2C: Read> Fs1027DgBusless<I2C> {
32 ///Creates the driver for the given I²C ports. Assumes that the I²C port is configured as master.
33 ///
34 /// Tries to initialize the driver on the given address, returns an error if this failed.
35 ///
36 /// If you are sure that the driver is at the given address and it still fails, make sure that you
37 /// configured the SDA/SCL connection correctly. The recommend pull-up resistors are between 2.2k Ohm and 10k Ohm. Have a look at the [documentation](https://www.renesas.com/us/en/document/dst/fs1027-dg-datasheet?language=en&r=1488711) for further information.
38 pub fn new(_i2c: &I2C, addr: u8) -> Self {
39 let dev = Fs1027DgBusless {
40 i2c: PhantomData,
41 addr,
42 read_buffer: [0; 5],
43 };
44
45 dev
46 }
47
48 ///Initializes the driver assuming the sensors address is the default one. If this fails, consider searching for the driver. Note that the driver only supports 7bit addresses.
49 ///
50 /// Have a look at [new](Self::new) for further documentation.
51 pub fn new_default(i2c: &I2C) -> Self {
52 Self::new(i2c, 0x50)
53 }
54
55 ///Reads a single 12bit value from the sensor. Returns 0 if the reading failed. Note that the default lowest value is 409 (per documentation).
56 pub fn read(&mut self, i2c: &mut I2C) -> u16 {
57 self.try_read(i2c).unwrap_or(0)
58 }
59
60 ///Tries to read a value, verifies it, and if this succeeds, returns the 12bit value.
61 pub fn try_read(&mut self, i2c: &mut I2C) -> Option<u16> {
62 //Per documentation: read 5 bytes, the first is the checksum, 1..2 is the data
63 // and 3..4 is the generic checksum.
64 //
65 match i2c.read(self.addr, &mut self.read_buffer) {
66 Ok(_) => {}
67 Err(_e) => return None,
68 }
69
70 //Calculate validity
71 let value = u16::from_be_bytes([self.read_buffer[1], self.read_buffer[2]]);
72 let sum = self.read_buffer[1]
73 .wrapping_add(self.read_buffer[2])
74 .wrapping_add(self.read_buffer[3])
75 .wrapping_add(self.read_buffer[4]);
76
77 if self.read_buffer[0].wrapping_add(sum) == 0 {
78 return Some(value);
79 } else {
80 None
81 }
82 }
83
84 ///Reads the current flow rate in liters/min. Returns 0 if reading failed
85 pub fn read_flow_rate(&mut self, i2c: &mut I2C) -> f32 {
86 if let Some(rate) = self.try_read(i2c) {
87 Self::bit_to_flow_rate(rate)
88 } else {
89 0.0
90 }
91 }
92
93 ///Converts the raw bits to a flow rate in liters/min
94 pub fn bit_to_flow_rate(bit: u16) -> f32 {
95 ((bit - 409) as f32 / 33277.0) * 200.0
96 }
97}
98
99
100impl<I2C: Read> Fs1027Dg<I2C>{
101 ///Creates the driver for the given I²C ports. Assumes that the I²C port is configured as master.
102 ///
103 /// Tries to initialize the driver on the given address, returns an error if this failed.
104 ///
105 /// If you are sure that the driver is at the given address and it still fails, make sure that you
106 /// configured the SDA/SCL connection correctly. The recommend pull-up resistors are between 2.2k Ohm and 10k Ohm. Have a look at the [documentation](https://www.renesas.com/us/en/document/dst/fs1027-dg-datasheet?language=en&r=1488711) for further information.
107 pub fn new(i2c: I2C, addr: u8) -> Self {
108 let busless = Fs1027DgBusless::new(&i2c, addr);
109 let dev = Fs1027Dg {
110 i2c,
111 busless
112 };
113
114 dev
115 }
116
117 ///Initializes the driver assuming the sensors address is the default one. If this fails, consider searching for the driver. Note that the driver only supports 7bit addresses.
118 ///
119 /// Have a look at [new](Self::new) for further documentation.
120 pub fn new_default(i2c: I2C) -> Self {
121 Self::new(i2c, 0x50)
122 }
123
124 ///Reads a single 12bit value from the sensor. Returns 0 if the reading failed. Note that the default lowest value is 409 (per documentation).
125 pub fn read(&mut self) -> u16 {
126 self.busless.read(&mut self.i2c)
127 }
128
129 ///Tries to read a value, verifies it, and if this succeeds, returns the 12bit value.
130 pub fn try_read(&mut self) -> Option<u16> {
131 self.busless.try_read(&mut self.i2c)
132 }
133
134 ///Reads the current flow rate in liters/min. Returns 0 if reading failed
135 pub fn read_flow_rate(&mut self) -> f32 {
136 self.busless.read_flow_rate(&mut self.i2c)
137 }
138
139 ///Releases the I²C interface by consuming `self`.
140 pub fn release(self) -> I2C {
141 self.i2c
142 }
143}