vl53l0x_simple/lib.rs
1#![doc = include_str!("../README.md")]
2#![no_std]
3
4mod imp;
5mod reg;
6
7/// The default I2C address for the VL53L0X.
8pub const DEFAULT_ADDRESS: u8 = 0b010_1001;
9
10/// Possible errors that can occur during initialisation.
11#[derive(Debug)]
12pub enum InitialisationError<EI2C, EX> {
13 /// An error occurred on the I2C bus.
14 I2C(EI2C),
15 /// An error occurred setting the xshut pin.
16 XShut(EX),
17
18 /// The model ID read from the device was invalid.
19 InvalidModelId(u8),
20 /// The signal rate limit was invalid.
21 InvalidSignalRateLimit(f32),
22 /// The measurement timing budget was too short.
23 TimingBudgetTooShort,
24 /// The device timed out.
25 Timeout,
26}
27
28/// A VL53L0X driver. Use the `new` function to create a new instance, then
29/// call `range` to get the current range, if available.
30pub struct Vl53l0x<I2C, X> {
31 i2c: I2C,
32 _x_shut: X,
33 address: u8,
34
35 stop_variable: u8,
36 measurement_timing_budget_us: u32,
37}
38
39impl<I2C, X, EI2C, EX> Vl53l0x<I2C, X>
40where
41 I2C: embedded_hal::i2c::I2c<Error = EI2C>,
42 X: embedded_hal::digital::OutputPin<Error = EX>,
43{
44 /// Create a new instance of the VL53L0X driver. This performs a reset of
45 /// the device and may fail if the device is not present. This will use the
46 /// `x_shut` pin to select the device to be reset, then it will change that
47 /// devices' address to the provided address.
48 ///
49 /// If these sensors are being used in an array, set all the xshut pins low
50 /// prior to calling this function which will allow this to only initialize
51 /// a single sensor.
52 ///
53 /// # Errors
54 /// Forwards any errors from the I2C bus and xshut pin, as well as any
55 /// initialisation errors from the device itself.
56 pub fn new(
57 i2c: I2C,
58 mut x_shut: X,
59 address: u8,
60 delay: &mut impl embedded_hal::delay::DelayNs,
61 ) -> Result<Self, InitialisationError<EI2C, EX>> {
62 // Reset the device by driving XSHUT low for 10ms.
63 x_shut.set_low().map_err(InitialisationError::XShut)?;
64 delay.delay_ms(10);
65 x_shut.set_high().map_err(InitialisationError::XShut)?;
66 delay.delay_ms(10);
67
68 let mut this = Self {
69 i2c,
70 _x_shut: x_shut,
71 address: DEFAULT_ADDRESS,
72
73 stop_variable: 0,
74 measurement_timing_budget_us: 0,
75 };
76
77 this.init(delay)?;
78
79 this.set_address(address)
80 .map_err(InitialisationError::I2C)?;
81
82 this.start_continuous(50)
83 .map_err(InitialisationError::I2C)?;
84
85 Ok(this)
86 }
87
88 /// Poll the device for a new range value. Returns `None` if the device is
89 /// still measuring.
90 ///
91 /// The range is returned in millimeters.
92 ///
93 /// # Errors
94 /// Forwards any errors from the I2C bus.
95 pub fn try_read(&mut self) -> Result<Option<u16>, EI2C> {
96 self.try_read_range_continuous_millimeters()
97 }
98}