fs3000/
lib.rs

1#![deny(unsafe_code)]
2#![no_std]
3
4use embedded_hal::blocking::i2c;
5use interp::interp;
6
7#[derive(Debug)]
8pub struct FS3000<I2C> {
9    // The concrete I2C device implementation
10    i2c: I2C,
11    // We don't need a device address because all FS3000 chips are at
12    // hex 0x28
13    address: DeviceAddr,
14    // There are two variants of the FS3000 chip with different velocity measurement ranges
15    subtype: ChipType,
16}
17
18impl<I2C, E> FS3000<I2C>
19where
20    I2C: i2c::Read<Error = E>,
21    E: core::fmt::Debug,
22{
23    pub fn new(i2c: I2C, address: DeviceAddr, subtype: ChipType) -> Result<Self, E> {
24        Ok(Self {
25            i2c,
26            address,
27            subtype,
28        })
29    }
30
31    pub fn get_raw_velocity(&mut self) -> Result<RawData, E> {
32        let mut buffer = [0u8; 5];
33        self.i2c.read(self.address as u8, &mut buffer)?;
34        let data = RawData {
35            checksum: buffer[0],
36            data_high: buffer[1],
37            data_low: buffer[2],
38            generic_checksum_1: buffer[3],
39            generic_checksum_2: buffer[4],
40        };
41        Ok(data)
42    }
43
44    pub fn get_counts(&mut self) -> u16 {
45        let data = self.get_raw_velocity();
46        get_counts(data.unwrap())
47    }
48
49    pub fn debug_values(&mut self) -> [u8; 5] {
50        let data = self.get_raw_velocity();
51        let result = data.unwrap();
52        [
53            result.checksum,
54            result.data_high,
55            result.data_low,
56            result.generic_checksum_1,
57            result.generic_checksum_2,
58        ]
59    }
60    #[allow(unused)]
61    fn calculate_checksum(&mut self, rawdata: RawData) -> bool {
62        let sum = rawdata.data_high
63            + rawdata.data_low
64            + rawdata.generic_checksum_1
65            + rawdata.generic_checksum_2;
66        let checksum_result = u8::wrapping_add(sum, rawdata.checksum);
67        if checksum_result == 0 {
68            true
69        } else {
70            false
71        }
72    }
73    #[allow(unused)]
74    pub fn get_measurement(&mut self) -> f32 {
75        let counts = self.get_counts();
76        match &self.subtype {
77            ChipType::Type1005 => interp(&COUNTS_1005, &MPS_1005, counts as f32),
78            ChipType::Type1015 => interp(&COUNTS_1015, &MPS_1015, counts as f32),
79        }
80    }
81}
82
83#[derive(Debug, Copy, Clone)]
84pub enum DeviceAddr {
85    Default = 0x28,
86}
87
88#[derive(Debug)]
89pub enum ChipType {
90    Type1005,
91    Type1015,
92}
93
94#[derive(Debug, Clone, PartialEq, Eq)]
95pub struct RawData {
96    pub checksum: u8,
97    pub data_high: u8,
98    pub data_low: u8,
99    pub generic_checksum_1: u8,
100    pub generic_checksum_2: u8,
101}
102
103pub fn get_counts(rawdata: RawData) -> u16 {
104    let result = u16::from_be_bytes([rawdata.data_high, rawdata.data_low]);
105    result
106}
107
108const COUNTS_1005: [f32; 9] = [
109    409.0, 915.0, 1522.0, 2066.0, 2523.0, 2908.0, 3256.0, 3572.0, 3686.0,
110];
111const MPS_1005: [f32; 9] = [0.0, 1.07, 2.01, 3.00, 3.97, 4.96, 5.98, 6.99, 7.23];
112const COUNTS_1015: [f32; 13] = [
113    409.0, 1203.0, 1597.0, 1908.0, 2187.0, 2400.0, 2629.0, 2801.0, 3006.0, 3178.0, 3309.0, 3563.0,
114    3686.0,
115];
116const MPS_1015: [f32; 13] = [
117    0.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 13.0, 15.0,
118];