tinkerforge/bindings/
load_cell_bricklet.rs

1/* ***********************************************************
2 * This file was automatically generated on 2024-02-27.      *
3 *                                                           *
4 * Rust Bindings Version 2.0.21                              *
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//! Measures weight with a load cell.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/LoadCell_Bricklet_Rust.html).
14use crate::{
15    byte_converter::*, converting_callback_receiver::ConvertingCallbackReceiver, converting_receiver::ConvertingReceiver, device::*,
16    ip_connection::GetRequestSender,
17};
18pub enum LoadCellBrickletFunction {
19    GetWeight,
20    SetWeightCallbackPeriod,
21    GetWeightCallbackPeriod,
22    SetWeightCallbackThreshold,
23    GetWeightCallbackThreshold,
24    SetDebouncePeriod,
25    GetDebouncePeriod,
26    SetMovingAverage,
27    GetMovingAverage,
28    LedOn,
29    LedOff,
30    IsLedOn,
31    Calibrate,
32    Tare,
33    SetConfiguration,
34    GetConfiguration,
35    GetIdentity,
36    CallbackWeight,
37    CallbackWeightReached,
38}
39impl From<LoadCellBrickletFunction> for u8 {
40    fn from(fun: LoadCellBrickletFunction) -> Self {
41        match fun {
42            LoadCellBrickletFunction::GetWeight => 1,
43            LoadCellBrickletFunction::SetWeightCallbackPeriod => 2,
44            LoadCellBrickletFunction::GetWeightCallbackPeriod => 3,
45            LoadCellBrickletFunction::SetWeightCallbackThreshold => 4,
46            LoadCellBrickletFunction::GetWeightCallbackThreshold => 5,
47            LoadCellBrickletFunction::SetDebouncePeriod => 6,
48            LoadCellBrickletFunction::GetDebouncePeriod => 7,
49            LoadCellBrickletFunction::SetMovingAverage => 8,
50            LoadCellBrickletFunction::GetMovingAverage => 9,
51            LoadCellBrickletFunction::LedOn => 10,
52            LoadCellBrickletFunction::LedOff => 11,
53            LoadCellBrickletFunction::IsLedOn => 12,
54            LoadCellBrickletFunction::Calibrate => 13,
55            LoadCellBrickletFunction::Tare => 14,
56            LoadCellBrickletFunction::SetConfiguration => 15,
57            LoadCellBrickletFunction::GetConfiguration => 16,
58            LoadCellBrickletFunction::GetIdentity => 255,
59            LoadCellBrickletFunction::CallbackWeight => 17,
60            LoadCellBrickletFunction::CallbackWeightReached => 18,
61        }
62    }
63}
64pub const LOAD_CELL_BRICKLET_THRESHOLD_OPTION_OFF: char = 'x';
65pub const LOAD_CELL_BRICKLET_THRESHOLD_OPTION_OUTSIDE: char = 'o';
66pub const LOAD_CELL_BRICKLET_THRESHOLD_OPTION_INSIDE: char = 'i';
67pub const LOAD_CELL_BRICKLET_THRESHOLD_OPTION_SMALLER: char = '<';
68pub const LOAD_CELL_BRICKLET_THRESHOLD_OPTION_GREATER: char = '>';
69pub const LOAD_CELL_BRICKLET_RATE_10HZ: u8 = 0;
70pub const LOAD_CELL_BRICKLET_RATE_80HZ: u8 = 1;
71pub const LOAD_CELL_BRICKLET_GAIN_128X: u8 = 0;
72pub const LOAD_CELL_BRICKLET_GAIN_64X: u8 = 1;
73pub const LOAD_CELL_BRICKLET_GAIN_32X: u8 = 2;
74
75#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
76pub struct WeightCallbackThreshold {
77    pub option: char,
78    pub min: i32,
79    pub max: i32,
80}
81impl FromByteSlice for WeightCallbackThreshold {
82    fn bytes_expected() -> usize { 9 }
83    fn from_le_byte_slice(bytes: &[u8]) -> WeightCallbackThreshold {
84        WeightCallbackThreshold {
85            option: <char>::from_le_byte_slice(&bytes[0..1]),
86            min: <i32>::from_le_byte_slice(&bytes[1..5]),
87            max: <i32>::from_le_byte_slice(&bytes[5..9]),
88        }
89    }
90}
91
92#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
93pub struct Configuration {
94    pub rate: u8,
95    pub gain: u8,
96}
97impl FromByteSlice for Configuration {
98    fn bytes_expected() -> usize { 2 }
99    fn from_le_byte_slice(bytes: &[u8]) -> Configuration {
100        Configuration { rate: <u8>::from_le_byte_slice(&bytes[0..1]), gain: <u8>::from_le_byte_slice(&bytes[1..2]) }
101    }
102}
103
104#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
105pub struct Identity {
106    pub uid: String,
107    pub connected_uid: String,
108    pub position: char,
109    pub hardware_version: [u8; 3],
110    pub firmware_version: [u8; 3],
111    pub device_identifier: u16,
112}
113impl FromByteSlice for Identity {
114    fn bytes_expected() -> usize { 25 }
115    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
116        Identity {
117            uid: <String>::from_le_byte_slice(&bytes[0..8]),
118            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
119            position: <char>::from_le_byte_slice(&bytes[16..17]),
120            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
121            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
122            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
123        }
124    }
125}
126
127/// Measures weight with a load cell
128#[derive(Clone)]
129pub struct LoadCellBricklet {
130    device: Device,
131}
132impl LoadCellBricklet {
133    pub const DEVICE_IDENTIFIER: u16 = 253;
134    pub const DEVICE_DISPLAY_NAME: &'static str = "Load Cell Bricklet";
135    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
136    pub fn new<T: GetRequestSender>(uid: &str, req_sender: T) -> LoadCellBricklet {
137        let mut result = LoadCellBricklet { device: Device::new([2, 0, 0], uid, req_sender, 0) };
138        result.device.response_expected[u8::from(LoadCellBrickletFunction::GetWeight) as usize] = ResponseExpectedFlag::AlwaysTrue;
139        result.device.response_expected[u8::from(LoadCellBrickletFunction::SetWeightCallbackPeriod) as usize] = ResponseExpectedFlag::True;
140        result.device.response_expected[u8::from(LoadCellBrickletFunction::GetWeightCallbackPeriod) as usize] =
141            ResponseExpectedFlag::AlwaysTrue;
142        result.device.response_expected[u8::from(LoadCellBrickletFunction::SetWeightCallbackThreshold) as usize] =
143            ResponseExpectedFlag::True;
144        result.device.response_expected[u8::from(LoadCellBrickletFunction::GetWeightCallbackThreshold) as usize] =
145            ResponseExpectedFlag::AlwaysTrue;
146        result.device.response_expected[u8::from(LoadCellBrickletFunction::SetDebouncePeriod) as usize] = ResponseExpectedFlag::True;
147        result.device.response_expected[u8::from(LoadCellBrickletFunction::GetDebouncePeriod) as usize] = ResponseExpectedFlag::AlwaysTrue;
148        result.device.response_expected[u8::from(LoadCellBrickletFunction::SetMovingAverage) as usize] = ResponseExpectedFlag::False;
149        result.device.response_expected[u8::from(LoadCellBrickletFunction::GetMovingAverage) as usize] = ResponseExpectedFlag::AlwaysTrue;
150        result.device.response_expected[u8::from(LoadCellBrickletFunction::LedOn) as usize] = ResponseExpectedFlag::False;
151        result.device.response_expected[u8::from(LoadCellBrickletFunction::LedOff) as usize] = ResponseExpectedFlag::False;
152        result.device.response_expected[u8::from(LoadCellBrickletFunction::IsLedOn) as usize] = ResponseExpectedFlag::AlwaysTrue;
153        result.device.response_expected[u8::from(LoadCellBrickletFunction::Calibrate) as usize] = ResponseExpectedFlag::False;
154        result.device.response_expected[u8::from(LoadCellBrickletFunction::Tare) as usize] = ResponseExpectedFlag::False;
155        result.device.response_expected[u8::from(LoadCellBrickletFunction::SetConfiguration) as usize] = ResponseExpectedFlag::False;
156        result.device.response_expected[u8::from(LoadCellBrickletFunction::GetConfiguration) as usize] = ResponseExpectedFlag::AlwaysTrue;
157        result.device.response_expected[u8::from(LoadCellBrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
158        result
159    }
160
161    /// Returns the response expected flag for the function specified by the function ID parameter.
162    /// It is true if the function is expected to send a response, false otherwise.
163    ///
164    /// For getter functions this is enabled by default and cannot be disabled, because those
165    /// functions will always send a response. For callback configuration functions it is enabled
166    /// by default too, but can be disabled by [`set_response_expected`](crate::load_cell_bricklet::LoadCellBricklet::set_response_expected).
167    /// For setter functions it is disabled by default and can be enabled.
168    ///
169    /// Enabling the response expected flag for a setter function allows to detect timeouts
170    /// and other error conditions calls of this setter as well. The device will then send a response
171    /// for this purpose. If this flag is disabled for a setter function then no response is sent
172    /// and errors are silently ignored, because they cannot be detected.
173    ///
174    /// See [`set_response_expected`](crate::load_cell_bricklet::LoadCellBricklet::set_response_expected) for the list of function ID constants available for this function.
175    pub fn get_response_expected(&mut self, fun: LoadCellBrickletFunction) -> Result<bool, GetResponseExpectedError> {
176        self.device.get_response_expected(u8::from(fun))
177    }
178
179    /// Changes the response expected flag of the function specified by the function ID parameter.
180    /// This flag can only be changed for setter (default value: false) and callback configuration
181    /// functions (default value: true). For getter functions it is always enabled.
182    ///
183    /// Enabling the response expected flag for a setter function allows to detect timeouts and
184    /// other error conditions calls of this setter as well. The device will then send a response
185    /// for this purpose. If this flag is disabled for a setter function then no response is sent
186    /// and errors are silently ignored, because they cannot be detected.
187    pub fn set_response_expected(
188        &mut self,
189        fun: LoadCellBrickletFunction,
190        response_expected: bool,
191    ) -> Result<(), SetResponseExpectedError> {
192        self.device.set_response_expected(u8::from(fun), response_expected)
193    }
194
195    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
196    pub fn set_response_expected_all(&mut self, response_expected: bool) { self.device.set_response_expected_all(response_expected) }
197
198    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
199    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
200    pub fn get_api_version(&self) -> [u8; 3] { self.device.api_version }
201
202    /// This receiver is triggered periodically with the period that is set by
203    /// [`set_weight_callback_period`]. The parameter is the weight
204    /// as measured by the load cell.
205    ///
206    /// The [`get_weight_callback_receiver`] receiver is only triggered if the weight has changed since the
207    /// last triggering.
208    ///
209    /// [`set_weight_callback_period`]: #method.set_weight_callback_period
210    /// [`get_weight_callback_receiver`]: #method.get_weight_callback_receiver
211    pub fn get_weight_callback_receiver(&self) -> ConvertingCallbackReceiver<i32> {
212        self.device.get_callback_receiver(u8::from(LoadCellBrickletFunction::CallbackWeight))
213    }
214
215    /// This receiver is triggered when the threshold as set by
216    /// [`set_weight_callback_threshold`] is reached.
217    /// The parameter is the weight as measured by the load cell.
218    ///
219    /// If the threshold keeps being reached, the receiver is triggered periodically
220    /// with the period as set by [`set_debounce_period`].
221    pub fn get_weight_reached_callback_receiver(&self) -> ConvertingCallbackReceiver<i32> {
222        self.device.get_callback_receiver(u8::from(LoadCellBrickletFunction::CallbackWeightReached))
223    }
224
225    /// Returns the currently measured weight.
226    ///
227    /// If you want to get the weight periodically, it is recommended
228    /// to use the [`get_weight_callback_receiver`] receiver and set the period with
229    /// [`set_weight_callback_period`].
230    pub fn get_weight(&self) -> ConvertingReceiver<i32> {
231        let payload = vec![0; 0];
232
233        self.device.get(u8::from(LoadCellBrickletFunction::GetWeight), payload)
234    }
235
236    /// Sets the period with which the [`get_weight_callback_receiver`] receiver is triggered
237    /// periodically. A value of 0 turns the receiver off.
238    ///
239    /// The [`get_weight_callback_receiver`] receiver is only triggered if the weight has changed since the
240    /// last triggering.
241    pub fn set_weight_callback_period(&self, period: u32) -> ConvertingReceiver<()> {
242        let mut payload = vec![0; 4];
243        payload[0..4].copy_from_slice(&<u32>::to_le_byte_vec(period));
244
245        self.device.set(u8::from(LoadCellBrickletFunction::SetWeightCallbackPeriod), payload)
246    }
247
248    /// Returns the period as set by [`set_weight_callback_period`].
249    pub fn get_weight_callback_period(&self) -> ConvertingReceiver<u32> {
250        let payload = vec![0; 0];
251
252        self.device.get(u8::from(LoadCellBrickletFunction::GetWeightCallbackPeriod), payload)
253    }
254
255    /// Sets the thresholds for the [`get_weight_reached_callback_receiver`] receiver.
256    ///
257    /// The following options are possible:
258    ///
259    ///  Option| Description
260    ///  --- | ---
261    ///  'x'|    Receiver is turned off
262    ///  'o'|    Receiver is triggered when the weight is *outside* the min and max values
263    ///  'i'|    Receiver is triggered when the weight is *inside* the min and max values
264    ///  '<'|    Receiver is triggered when the weight is smaller than the min value (max is ignored)
265    ///  '>'|    Receiver is triggered when the weight is greater than the min value (max is ignored)
266    ///
267    /// Associated constants:
268    /// * LOAD_CELL_BRICKLET_THRESHOLD_OPTION_OFF
269    ///	* LOAD_CELL_BRICKLET_THRESHOLD_OPTION_OUTSIDE
270    ///	* LOAD_CELL_BRICKLET_THRESHOLD_OPTION_INSIDE
271    ///	* LOAD_CELL_BRICKLET_THRESHOLD_OPTION_SMALLER
272    ///	* LOAD_CELL_BRICKLET_THRESHOLD_OPTION_GREATER
273    pub fn set_weight_callback_threshold(&self, option: char, min: i32, max: i32) -> ConvertingReceiver<()> {
274        let mut payload = vec![0; 9];
275        payload[0..1].copy_from_slice(&<char>::to_le_byte_vec(option));
276        payload[1..5].copy_from_slice(&<i32>::to_le_byte_vec(min));
277        payload[5..9].copy_from_slice(&<i32>::to_le_byte_vec(max));
278
279        self.device.set(u8::from(LoadCellBrickletFunction::SetWeightCallbackThreshold), payload)
280    }
281
282    /// Returns the threshold as set by [`set_weight_callback_threshold`].
283    ///
284    /// Associated constants:
285    /// * LOAD_CELL_BRICKLET_THRESHOLD_OPTION_OFF
286    ///	* LOAD_CELL_BRICKLET_THRESHOLD_OPTION_OUTSIDE
287    ///	* LOAD_CELL_BRICKLET_THRESHOLD_OPTION_INSIDE
288    ///	* LOAD_CELL_BRICKLET_THRESHOLD_OPTION_SMALLER
289    ///	* LOAD_CELL_BRICKLET_THRESHOLD_OPTION_GREATER
290    pub fn get_weight_callback_threshold(&self) -> ConvertingReceiver<WeightCallbackThreshold> {
291        let payload = vec![0; 0];
292
293        self.device.get(u8::from(LoadCellBrickletFunction::GetWeightCallbackThreshold), payload)
294    }
295
296    /// Sets the period with which the threshold receiver
297    ///
298    /// * [`get_weight_reached_callback_receiver`]
299    ///
300    /// is triggered, if the threshold
301    ///
302    /// * [`set_weight_callback_threshold`]
303    ///
304    /// keeps being reached.
305    pub fn set_debounce_period(&self, debounce: u32) -> ConvertingReceiver<()> {
306        let mut payload = vec![0; 4];
307        payload[0..4].copy_from_slice(&<u32>::to_le_byte_vec(debounce));
308
309        self.device.set(u8::from(LoadCellBrickletFunction::SetDebouncePeriod), payload)
310    }
311
312    /// Returns the debounce period as set by [`set_debounce_period`].
313    pub fn get_debounce_period(&self) -> ConvertingReceiver<u32> {
314        let payload = vec![0; 0];
315
316        self.device.get(u8::from(LoadCellBrickletFunction::GetDebouncePeriod), payload)
317    }
318
319    /// Sets the length of a [moving averaging](https://en.wikipedia.org/wiki/Moving_average)__
320    /// for the weight value.
321    ///
322    /// Setting the length to 1 will turn the averaging off. With less
323    /// averaging, there is more noise on the data.
324    pub fn set_moving_average(&self, average: u8) -> ConvertingReceiver<()> {
325        let mut payload = vec![0; 1];
326        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(average));
327
328        self.device.set(u8::from(LoadCellBrickletFunction::SetMovingAverage), payload)
329    }
330
331    /// Returns the length moving average as set by [`set_moving_average`].
332    pub fn get_moving_average(&self) -> ConvertingReceiver<u8> {
333        let payload = vec![0; 0];
334
335        self.device.get(u8::from(LoadCellBrickletFunction::GetMovingAverage), payload)
336    }
337
338    /// Turns the LED on.
339    pub fn led_on(&self) -> ConvertingReceiver<()> {
340        let payload = vec![0; 0];
341
342        self.device.set(u8::from(LoadCellBrickletFunction::LedOn), payload)
343    }
344
345    /// Turns the LED off.
346    pub fn led_off(&self) -> ConvertingReceiver<()> {
347        let payload = vec![0; 0];
348
349        self.device.set(u8::from(LoadCellBrickletFunction::LedOff), payload)
350    }
351
352    /// Returns *true* if the led is on, *false* otherwise.
353    pub fn is_led_on(&self) -> ConvertingReceiver<bool> {
354        let payload = vec![0; 0];
355
356        self.device.get(u8::from(LoadCellBrickletFunction::IsLedOn), payload)
357    }
358
359    /// To calibrate your Load Cell Bricklet you have to
360    ///
361    /// * empty the scale and call this function with 0 and
362    /// * add a known weight to the scale and call this function with the weight.
363    ///
364    /// The calibration is saved in the EEPROM of the Bricklet and only
365    /// needs to be done once.
366    ///
367    /// We recommend to use the Brick Viewer for calibration, you don't need
368    /// to call this function in your source code.
369    pub fn calibrate(&self, weight: u32) -> ConvertingReceiver<()> {
370        let mut payload = vec![0; 4];
371        payload[0..4].copy_from_slice(&<u32>::to_le_byte_vec(weight));
372
373        self.device.set(u8::from(LoadCellBrickletFunction::Calibrate), payload)
374    }
375
376    /// Sets the currently measured weight as tare weight.
377    pub fn tare(&self) -> ConvertingReceiver<()> {
378        let payload = vec![0; 0];
379
380        self.device.set(u8::from(LoadCellBrickletFunction::Tare), payload)
381    }
382
383    /// The measurement rate and gain are configurable.
384    ///
385    /// The rate can be either 10Hz or 80Hz. A faster rate will produce more noise.
386    /// It is additionally possible to add a moving average
387    /// (see [`set_moving_average`]) to the measurements.
388    ///
389    /// The gain can be 128x, 64x or 32x. It represents a measurement range of
390    /// ±20mV, ±40mV and ±80mV respectively. The Load Cell Bricklet uses an
391    /// excitation voltage of 5V and most load cells use an output of 2mV/V. That
392    /// means the voltage range is ±15mV for most load cells (i.e. gain of 128x
393    /// is best). If you don't know what all of this means you should keep it at
394    /// 128x, it will most likely be correct.
395    ///
396    /// The configuration is saved in the EEPROM of the Bricklet and only
397    /// needs to be done once.
398    ///
399    /// We recommend to use the Brick Viewer for configuration, you don't need
400    /// to call this function in your source code.
401    ///
402    /// Associated constants:
403    /// * LOAD_CELL_BRICKLET_RATE_10HZ
404    ///	* LOAD_CELL_BRICKLET_RATE_80HZ
405    ///	* LOAD_CELL_BRICKLET_GAIN_128X
406    ///	* LOAD_CELL_BRICKLET_GAIN_64X
407    ///	* LOAD_CELL_BRICKLET_GAIN_32X
408    pub fn set_configuration(&self, rate: u8, gain: u8) -> ConvertingReceiver<()> {
409        let mut payload = vec![0; 2];
410        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(rate));
411        payload[1..2].copy_from_slice(&<u8>::to_le_byte_vec(gain));
412
413        self.device.set(u8::from(LoadCellBrickletFunction::SetConfiguration), payload)
414    }
415
416    /// Returns the configuration as set by [`set_configuration`].
417    ///
418    /// Associated constants:
419    /// * LOAD_CELL_BRICKLET_RATE_10HZ
420    ///	* LOAD_CELL_BRICKLET_RATE_80HZ
421    ///	* LOAD_CELL_BRICKLET_GAIN_128X
422    ///	* LOAD_CELL_BRICKLET_GAIN_64X
423    ///	* LOAD_CELL_BRICKLET_GAIN_32X
424    pub fn get_configuration(&self) -> ConvertingReceiver<Configuration> {
425        let payload = vec![0; 0];
426
427        self.device.get(u8::from(LoadCellBrickletFunction::GetConfiguration), payload)
428    }
429
430    /// Returns the UID, the UID where the Bricklet is connected to,
431    /// the position, the hardware and firmware version as well as the
432    /// device identifier.
433    ///
434    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
435    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
436    /// position 'z'.
437    ///
438    /// The device identifier numbers can be found [here](device_identifier).
439    /// |device_identifier_constant|
440    pub fn get_identity(&self) -> ConvertingReceiver<Identity> {
441        let payload = vec![0; 0];
442
443        self.device.get(u8::from(LoadCellBrickletFunction::GetIdentity), payload)
444    }
445}