tinkerforge_async/bindings/
hall_effect_bricklet.rs

1/* ***********************************************************
2 * This file was automatically generated on 2024-02-16.      *
3 *                                                           *
4 * Rust Bindings Version 2.0.20                              *
5 *                                                           *
6 * If you have a bugfix for this file and want to commit it, *
7 * please fix the bug in the generator. You can find a link  *
8 * to the generators git repository on tinkerforge.com       *
9 *************************************************************/
10
11//! Detects presence of magnetic field.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/HallEffect_Bricklet_Rust.html).
14#[allow(unused_imports)]
15use crate::{
16    base58::Uid, byte_converter::*, device::*, error::TinkerforgeError, ip_connection::async_io::AsyncIpConnection,
17    low_level_traits::LowLevelRead,
18};
19#[allow(unused_imports)]
20use futures_core::Stream;
21#[allow(unused_imports)]
22use tokio_stream::StreamExt;
23pub enum HallEffectBrickletFunction {
24    GetValue,
25    GetEdgeCount,
26    SetEdgeCountConfig,
27    GetEdgeCountConfig,
28    SetEdgeInterrupt,
29    GetEdgeInterrupt,
30    SetEdgeCountCallbackPeriod,
31    GetEdgeCountCallbackPeriod,
32    EdgeInterrupt,
33    GetIdentity,
34    CallbackEdgeCount,
35}
36impl From<HallEffectBrickletFunction> for u8 {
37    fn from(fun: HallEffectBrickletFunction) -> Self {
38        match fun {
39            HallEffectBrickletFunction::GetValue => 1,
40            HallEffectBrickletFunction::GetEdgeCount => 2,
41            HallEffectBrickletFunction::SetEdgeCountConfig => 3,
42            HallEffectBrickletFunction::GetEdgeCountConfig => 4,
43            HallEffectBrickletFunction::SetEdgeInterrupt => 5,
44            HallEffectBrickletFunction::GetEdgeInterrupt => 6,
45            HallEffectBrickletFunction::SetEdgeCountCallbackPeriod => 7,
46            HallEffectBrickletFunction::GetEdgeCountCallbackPeriod => 8,
47            HallEffectBrickletFunction::EdgeInterrupt => 9,
48            HallEffectBrickletFunction::GetIdentity => 255,
49            HallEffectBrickletFunction::CallbackEdgeCount => 10,
50        }
51    }
52}
53pub const HALL_EFFECT_BRICKLET_EDGE_TYPE_RISING: u8 = 0;
54pub const HALL_EFFECT_BRICKLET_EDGE_TYPE_FALLING: u8 = 1;
55pub const HALL_EFFECT_BRICKLET_EDGE_TYPE_BOTH: u8 = 2;
56
57#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
58pub struct EdgeCountConfig {
59    pub edge_type: u8,
60    pub debounce: u8,
61}
62impl FromByteSlice for EdgeCountConfig {
63    fn bytes_expected() -> usize {
64        2
65    }
66    fn from_le_byte_slice(bytes: &[u8]) -> EdgeCountConfig {
67        EdgeCountConfig { edge_type: <u8>::from_le_byte_slice(&bytes[0..1]), debounce: <u8>::from_le_byte_slice(&bytes[1..2]) }
68    }
69}
70
71#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
72pub struct EdgeInterrupt {
73    pub count: u32,
74    pub value: bool,
75}
76impl FromByteSlice for EdgeInterrupt {
77    fn bytes_expected() -> usize {
78        5
79    }
80    fn from_le_byte_slice(bytes: &[u8]) -> EdgeInterrupt {
81        EdgeInterrupt { count: <u32>::from_le_byte_slice(&bytes[0..4]), value: <bool>::from_le_byte_slice(&bytes[4..5]) }
82    }
83}
84
85#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
86pub struct EdgeCountEvent {
87    pub count: u32,
88    pub value: bool,
89}
90impl FromByteSlice for EdgeCountEvent {
91    fn bytes_expected() -> usize {
92        5
93    }
94    fn from_le_byte_slice(bytes: &[u8]) -> EdgeCountEvent {
95        EdgeCountEvent { count: <u32>::from_le_byte_slice(&bytes[0..4]), value: <bool>::from_le_byte_slice(&bytes[4..5]) }
96    }
97}
98
99#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
100pub struct Identity {
101    pub uid: String,
102    pub connected_uid: String,
103    pub position: char,
104    pub hardware_version: [u8; 3],
105    pub firmware_version: [u8; 3],
106    pub device_identifier: u16,
107}
108impl FromByteSlice for Identity {
109    fn bytes_expected() -> usize {
110        25
111    }
112    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
113        Identity {
114            uid: <String>::from_le_byte_slice(&bytes[0..8]),
115            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
116            position: <char>::from_le_byte_slice(&bytes[16..17]),
117            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
118            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
119            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
120        }
121    }
122}
123
124/// Detects presence of magnetic field
125#[derive(Clone)]
126pub struct HallEffectBricklet {
127    device: Device,
128}
129impl HallEffectBricklet {
130    pub const DEVICE_IDENTIFIER: u16 = 240;
131    pub const DEVICE_DISPLAY_NAME: &'static str = "Hall Effect Bricklet";
132    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
133    pub fn new(uid: Uid, connection: AsyncIpConnection) -> HallEffectBricklet {
134        let mut result = HallEffectBricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
135        result.device.response_expected[u8::from(HallEffectBrickletFunction::GetValue) as usize] = ResponseExpectedFlag::AlwaysTrue;
136        result.device.response_expected[u8::from(HallEffectBrickletFunction::GetEdgeCount) as usize] = ResponseExpectedFlag::AlwaysTrue;
137        result.device.response_expected[u8::from(HallEffectBrickletFunction::SetEdgeCountConfig) as usize] = ResponseExpectedFlag::False;
138        result.device.response_expected[u8::from(HallEffectBrickletFunction::GetEdgeCountConfig) as usize] =
139            ResponseExpectedFlag::AlwaysTrue;
140        result.device.response_expected[u8::from(HallEffectBrickletFunction::SetEdgeInterrupt) as usize] = ResponseExpectedFlag::True;
141        result.device.response_expected[u8::from(HallEffectBrickletFunction::GetEdgeInterrupt) as usize] = ResponseExpectedFlag::AlwaysTrue;
142        result.device.response_expected[u8::from(HallEffectBrickletFunction::SetEdgeCountCallbackPeriod) as usize] =
143            ResponseExpectedFlag::True;
144        result.device.response_expected[u8::from(HallEffectBrickletFunction::GetEdgeCountCallbackPeriod) as usize] =
145            ResponseExpectedFlag::AlwaysTrue;
146        result.device.response_expected[u8::from(HallEffectBrickletFunction::EdgeInterrupt) as usize] = ResponseExpectedFlag::AlwaysTrue;
147        result.device.response_expected[u8::from(HallEffectBrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
148        result
149    }
150
151    /// Returns the response expected flag for the function specified by the function ID parameter.
152    /// It is true if the function is expected to send a response, false otherwise.
153    ///
154    /// For getter functions this is enabled by default and cannot be disabled, because those
155    /// functions will always send a response. For callback configuration functions it is enabled
156    /// by default too, but can be disabled by [`set_response_expected`](crate::hall_effect_bricklet::HallEffectBricklet::set_response_expected).
157    /// For setter functions it is disabled by default and can be enabled.
158    ///
159    /// Enabling the response expected flag for a setter function allows to detect timeouts
160    /// and other error conditions calls of this setter as well. The device will then send a response
161    /// for this purpose. If this flag is disabled for a setter function then no response is sent
162    /// and errors are silently ignored, because they cannot be detected.
163    ///
164    /// See [`set_response_expected`](crate::hall_effect_bricklet::HallEffectBricklet::set_response_expected) for the list of function ID constants available for this function.
165    pub fn get_response_expected(&mut self, fun: HallEffectBrickletFunction) -> Result<bool, GetResponseExpectedError> {
166        self.device.get_response_expected(u8::from(fun))
167    }
168
169    /// Changes the response expected flag of the function specified by the function ID parameter.
170    /// This flag can only be changed for setter (default value: false) and callback configuration
171    /// functions (default value: true). For getter functions it is always enabled.
172    ///
173    /// Enabling the response expected flag for a setter function allows to detect timeouts and
174    /// other error conditions calls of this setter as well. The device will then send a response
175    /// for this purpose. If this flag is disabled for a setter function then no response is sent
176    /// and errors are silently ignored, because they cannot be detected.
177    pub fn set_response_expected(
178        &mut self,
179        fun: HallEffectBrickletFunction,
180        response_expected: bool,
181    ) -> Result<(), SetResponseExpectedError> {
182        self.device.set_response_expected(u8::from(fun), response_expected)
183    }
184
185    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
186    pub fn set_response_expected_all(&mut self, response_expected: bool) {
187        self.device.set_response_expected_all(response_expected)
188    }
189
190    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
191    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
192    pub fn get_api_version(&self) -> [u8; 3] {
193        self.device.api_version
194    }
195
196    /// This receiver is triggered periodically with the period that is set by
197    /// [`set_edge_count_callback_period`]. The parameters are the
198    /// current count and the current value (see [`get_value`] and
199    /// [`get_edge_count`]).
200    ///
201    /// The [`get_edge_count_callback_receiver`] receiver is only triggered if the count or value changed
202    /// since the last triggering.
203    ///
204    /// [`get_value`]: #method.get_value
205    /// [`get_edge_count`]: #method.get_edge_count
206    /// [`set_edge_count_callback_period`]: #method.set_edge_count_callback_period
207    /// [`get_edge_count_callback_receiver`]: #method.get_edge_count_callback_receiver
208    pub async fn get_edge_count_callback_receiver(&mut self) -> impl Stream<Item = EdgeCountEvent> {
209        self.device
210            .get_callback_receiver(u8::from(HallEffectBrickletFunction::CallbackEdgeCount))
211            .await
212            .map(|p| EdgeCountEvent::from_le_byte_slice(p.body()))
213    }
214
215    /// Returns *true* if a magnetic field of 3.5 millitesla or greater is detected.
216    pub async fn get_value(&mut self) -> Result<bool, TinkerforgeError> {
217        let payload = [0; 0];
218
219        #[allow(unused_variables)]
220        let result = self.device.get(u8::from(HallEffectBrickletFunction::GetValue), &payload).await?;
221        Ok(bool::from_le_byte_slice(result.body()))
222    }
223
224    /// Returns the current value of the edge counter. You can configure
225    /// edge type (rising, falling, both) that is counted with
226    /// [`set_edge_count_config`].
227    ///
228    /// If you set the reset counter to *true*, the count is set back to 0
229    /// directly after it is read.
230    pub async fn get_edge_count(&mut self, reset_counter: bool) -> Result<u32, TinkerforgeError> {
231        let mut payload = [0; 1];
232        reset_counter.write_to_slice(&mut payload[0..1]);
233
234        #[allow(unused_variables)]
235        let result = self.device.get(u8::from(HallEffectBrickletFunction::GetEdgeCount), &payload).await?;
236        Ok(u32::from_le_byte_slice(result.body()))
237    }
238
239    /// The edge type parameter configures if rising edges, falling edges or
240    /// both are counted. Possible edge types are:
241    ///
242    /// * 0 = rising
243    /// * 1 = falling
244    /// * 2 = both
245    ///
246    /// A magnetic field of 3.5 millitesla or greater causes a falling edge and a
247    /// magnetic field of 2.5 millitesla or smaller causes a rising edge.
248    ///
249    /// If a magnet comes near the Bricklet the signal goes low (falling edge), if
250    /// a magnet is removed from the vicinity the signal goes high (rising edge).
251    ///
252    /// Configuring an edge counter resets its value to 0.
253    ///
254    /// If you don't know what any of this means, just leave it at default. The
255    /// default configuration is very likely OK for you.
256    ///
257    /// Associated constants:
258    /// * HALL_EFFECT_BRICKLET_EDGE_TYPE_RISING
259    ///	* HALL_EFFECT_BRICKLET_EDGE_TYPE_FALLING
260    ///	* HALL_EFFECT_BRICKLET_EDGE_TYPE_BOTH
261    pub async fn set_edge_count_config(&mut self, edge_type: u8, debounce: u8) -> Result<(), TinkerforgeError> {
262        let mut payload = [0; 2];
263        edge_type.write_to_slice(&mut payload[0..1]);
264        debounce.write_to_slice(&mut payload[1..2]);
265
266        #[allow(unused_variables)]
267        let result = self.device.set(u8::from(HallEffectBrickletFunction::SetEdgeCountConfig), &payload).await?;
268        Ok(())
269    }
270
271    /// Returns the edge type and debounce time as set by [`set_edge_count_config`].
272    ///
273    /// Associated constants:
274    /// * HALL_EFFECT_BRICKLET_EDGE_TYPE_RISING
275    ///	* HALL_EFFECT_BRICKLET_EDGE_TYPE_FALLING
276    ///	* HALL_EFFECT_BRICKLET_EDGE_TYPE_BOTH
277    pub async fn get_edge_count_config(&mut self) -> Result<EdgeCountConfig, TinkerforgeError> {
278        let payload = [0; 0];
279
280        #[allow(unused_variables)]
281        let result = self.device.get(u8::from(HallEffectBrickletFunction::GetEdgeCountConfig), &payload).await?;
282        Ok(EdgeCountConfig::from_le_byte_slice(result.body()))
283    }
284
285    /// Sets the number of edges until an interrupt is invoked.
286    ///
287    /// If *edges* is set to n, an interrupt is invoked for every n-th detected edge.
288    ///
289    /// If *edges* is set to 0, the interrupt is disabled.
290    pub async fn set_edge_interrupt(&mut self, edges: u32) -> Result<(), TinkerforgeError> {
291        let mut payload = [0; 4];
292        edges.write_to_slice(&mut payload[0..4]);
293
294        #[allow(unused_variables)]
295        let result = self.device.set(u8::from(HallEffectBrickletFunction::SetEdgeInterrupt), &payload).await?;
296        Ok(())
297    }
298
299    /// Returns the edges as set by [`set_edge_interrupt`].
300    pub async fn get_edge_interrupt(&mut self) -> Result<u32, TinkerforgeError> {
301        let payload = [0; 0];
302
303        #[allow(unused_variables)]
304        let result = self.device.get(u8::from(HallEffectBrickletFunction::GetEdgeInterrupt), &payload).await?;
305        Ok(u32::from_le_byte_slice(result.body()))
306    }
307
308    /// Sets the period with which the [`get_edge_count_callback_receiver`] receiver is triggered
309    /// periodically. A value of 0 turns the receiver off.
310    ///
311    /// The [`get_edge_count_callback_receiver`] receiver is only triggered if the edge count has changed
312    /// since the last triggering.
313    pub async fn set_edge_count_callback_period(&mut self, period: u32) -> Result<(), TinkerforgeError> {
314        let mut payload = [0; 4];
315        period.write_to_slice(&mut payload[0..4]);
316
317        #[allow(unused_variables)]
318        let result = self.device.set(u8::from(HallEffectBrickletFunction::SetEdgeCountCallbackPeriod), &payload).await?;
319        Ok(())
320    }
321
322    /// Returns the period as set by [`set_edge_count_callback_period`].
323    pub async fn get_edge_count_callback_period(&mut self) -> Result<u32, TinkerforgeError> {
324        let payload = [0; 0];
325
326        #[allow(unused_variables)]
327        let result = self.device.get(u8::from(HallEffectBrickletFunction::GetEdgeCountCallbackPeriod), &payload).await?;
328        Ok(u32::from_le_byte_slice(result.body()))
329    }
330
331    /// This receiver is triggered every n-th count, as configured with
332    /// [`set_edge_interrupt`]. The parameters are the
333    /// current count and the current value (see [`get_value`] and
334    /// [`get_edge_count`]).
335    pub async fn edge_interrupt(&mut self) -> Result<EdgeInterrupt, TinkerforgeError> {
336        let payload = [0; 0];
337
338        #[allow(unused_variables)]
339        let result = self.device.get(u8::from(HallEffectBrickletFunction::EdgeInterrupt), &payload).await?;
340        Ok(EdgeInterrupt::from_le_byte_slice(result.body()))
341    }
342
343    /// Returns the UID, the UID where the Bricklet is connected to,
344    /// the position, the hardware and firmware version as well as the
345    /// device identifier.
346    ///
347    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
348    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
349    /// position 'z'.
350    ///
351    /// The device identifier numbers can be found [here](device_identifier).
352    /// |device_identifier_constant|
353    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
354        let payload = [0; 0];
355
356        #[allow(unused_variables)]
357        let result = self.device.get(u8::from(HallEffectBrickletFunction::GetIdentity), &payload).await?;
358        Ok(Identity::from_le_byte_slice(result.body()))
359    }
360}