ev3dev_lang_rust/sensors/
ultrasonic_sensor.rs

1//! LEGO EV3 ultrasonic sensor
2
3use super::{Sensor, SensorPort};
4use crate::{sensor_mode, Attribute, Device, Driver, Ev3Error, Ev3Result};
5use std::cell::Cell;
6
7/// LEGO EV3 ultrasonic sensor.
8#[derive(Debug, Clone, Device, Sensor)]
9pub struct UltrasonicSensor {
10    driver: Driver,
11    cm_scale: Cell<Option<f32>>,
12    in_scale: Cell<Option<f32>>,
13}
14
15impl UltrasonicSensor {
16    fn new(driver: Driver) -> Self {
17        Self {
18            driver,
19            cm_scale: Cell::new(None),
20            in_scale: Cell::new(None),
21        }
22    }
23
24    findable!(
25        "lego-sensor",
26        ["lego-ev3-us", "lego-nxt-us"],
27        SensorPort,
28        "UltrasonicSensor",
29        "in"
30    );
31
32    sensor_mode!(
33        "US-DIST-CM",
34        MODE_US_DIST_CM,
35        "Continuous measurement - sets LEDs on, steady. Units in centimeters. Distance (0-2550)",
36        set_mode_us_dist_cm,
37        is_mode_us_dist_cm
38    );
39    sensor_mode!(
40        "US-DIST-IN",
41        MODE_US_DIST_IN,
42        "Continuous measurement - sets LEDs on, steady. Units in inches. Distance (0-1003)",
43        set_mode_us_dist_in,
44        is_mode_us_dist_in
45    );
46    sensor_mode!(
47        "US-LISTEN",
48        MODE_US_LISTEN,
49        "Listen - sets LEDs on, blinking. Presence (0-1) #",
50        set_mode_us_listen,
51        is_mode_us_listen
52    );
53    sensor_mode!(
54        "US-SI-CM",
55        MODE_US_SI_CM,
56        "Single measurement - LEDs on momentarily when mode is set, then off. Units in centimeters. Distance (0-2550)",
57        set_mode_us_si_cm,
58        is_mode_us_si_cm
59    );
60    sensor_mode!(
61        "US-SI-IN",
62        MODE_US_SI_IN,
63        "Single measurement - LEDs on momentarily when mode is set, then off. Units in inches. Distance (0-1003)",
64        set_mode_us_si_in,
65        is_mode_us_si_in
66    );
67    sensor_mode!(
68        "US-DC-CM",
69        MODE_US_DC_CM,
70        "??? - sets LEDs on, steady. Units in centimeters. Distance (0-2550)",
71        set_mode_us_dc_cm,
72        is_mode_us_dc_cm
73    );
74    sensor_mode!(
75        "US-DC-IN",
76        MODE_US_DC_IN,
77        "??? - sets LEDs on, steady. Units in inches. Distance (0-1003)",
78        set_mode_us_dc_in,
79        is_mode_us_dc_in
80    );
81
82    /// Measurement of the distance detected by the sensor, unscaled.
83    pub fn get_distance(&self) -> Ev3Result<i32> {
84        self.get_value0()
85    }
86
87    /// Measurement of the distance detected by the sensor, in centimeters.
88    pub fn get_distance_centimeters(&self) -> Ev3Result<f32> {
89        let scale_field = self.cm_scale.get();
90        let scale = match scale_field {
91            Some(s) => s,
92            None => {
93                let decimals = self.get_decimals()?;
94                let s = 10f32.powi(-decimals);
95                self.cm_scale.set(Some(s));
96                s
97            }
98        };
99
100        Ok((self.get_value0()? as f32) * scale)
101    }
102
103    /// Measurement of the distance detected by the sensor, in inches.
104    pub fn get_distance_inches(&self) -> Ev3Result<f32> {
105        let scale_field = self.in_scale.get();
106        let scale = match scale_field {
107            Some(s) => s,
108            None => {
109                let decimals = self.get_decimals()?;
110                let s = 10f32.powi(-decimals);
111                self.in_scale.set(Some(s));
112                s
113            }
114        };
115
116        Ok((self.get_value0()? as f32) * scale)
117    }
118}