ev3dev_lang_rust/sensors/
ultrasonic_sensor.rs1use super::{Sensor, SensorPort};
4use crate::{sensor_mode, Attribute, Device, Driver, Ev3Error, Ev3Result};
5use std::cell::Cell;
6
7#[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 pub fn get_distance(&self) -> Ev3Result<i32> {
84 self.get_value0()
85 }
86
87 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 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}