tinkerforge_async/bindings/
imu_brick.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//! Full fledged AHRS with 9 degrees of freedom.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricks/IMU_Brick_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 ImuBrickFunction {
24    GetAcceleration,
25    GetMagneticField,
26    GetAngularVelocity,
27    GetAllData,
28    GetOrientation,
29    GetQuaternion,
30    GetImuTemperature,
31    LedsOn,
32    LedsOff,
33    AreLedsOn,
34    SetAccelerationRange,
35    GetAccelerationRange,
36    SetMagnetometerRange,
37    GetMagnetometerRange,
38    SetConvergenceSpeed,
39    GetConvergenceSpeed,
40    SetCalibration,
41    GetCalibration,
42    SetAccelerationPeriod,
43    GetAccelerationPeriod,
44    SetMagneticFieldPeriod,
45    GetMagneticFieldPeriod,
46    SetAngularVelocityPeriod,
47    GetAngularVelocityPeriod,
48    SetAllDataPeriod,
49    GetAllDataPeriod,
50    SetOrientationPeriod,
51    GetOrientationPeriod,
52    SetQuaternionPeriod,
53    GetQuaternionPeriod,
54    OrientationCalculationOn,
55    OrientationCalculationOff,
56    IsOrientationCalculationOn,
57    SetSpitfpBaudrateConfig,
58    GetSpitfpBaudrateConfig,
59    GetSendTimeoutCount,
60    SetSpitfpBaudrate,
61    GetSpitfpBaudrate,
62    GetSpitfpErrorCount,
63    EnableStatusLed,
64    DisableStatusLed,
65    IsStatusLedEnabled,
66    GetProtocol1BrickletName,
67    GetChipTemperature,
68    Reset,
69    WriteBrickletPlugin,
70    ReadBrickletPlugin,
71    GetIdentity,
72    CallbackAcceleration,
73    CallbackMagneticField,
74    CallbackAngularVelocity,
75    CallbackAllData,
76    CallbackOrientation,
77    CallbackQuaternion,
78}
79impl From<ImuBrickFunction> for u8 {
80    fn from(fun: ImuBrickFunction) -> Self {
81        match fun {
82            ImuBrickFunction::GetAcceleration => 1,
83            ImuBrickFunction::GetMagneticField => 2,
84            ImuBrickFunction::GetAngularVelocity => 3,
85            ImuBrickFunction::GetAllData => 4,
86            ImuBrickFunction::GetOrientation => 5,
87            ImuBrickFunction::GetQuaternion => 6,
88            ImuBrickFunction::GetImuTemperature => 7,
89            ImuBrickFunction::LedsOn => 8,
90            ImuBrickFunction::LedsOff => 9,
91            ImuBrickFunction::AreLedsOn => 10,
92            ImuBrickFunction::SetAccelerationRange => 11,
93            ImuBrickFunction::GetAccelerationRange => 12,
94            ImuBrickFunction::SetMagnetometerRange => 13,
95            ImuBrickFunction::GetMagnetometerRange => 14,
96            ImuBrickFunction::SetConvergenceSpeed => 15,
97            ImuBrickFunction::GetConvergenceSpeed => 16,
98            ImuBrickFunction::SetCalibration => 17,
99            ImuBrickFunction::GetCalibration => 18,
100            ImuBrickFunction::SetAccelerationPeriod => 19,
101            ImuBrickFunction::GetAccelerationPeriod => 20,
102            ImuBrickFunction::SetMagneticFieldPeriod => 21,
103            ImuBrickFunction::GetMagneticFieldPeriod => 22,
104            ImuBrickFunction::SetAngularVelocityPeriod => 23,
105            ImuBrickFunction::GetAngularVelocityPeriod => 24,
106            ImuBrickFunction::SetAllDataPeriod => 25,
107            ImuBrickFunction::GetAllDataPeriod => 26,
108            ImuBrickFunction::SetOrientationPeriod => 27,
109            ImuBrickFunction::GetOrientationPeriod => 28,
110            ImuBrickFunction::SetQuaternionPeriod => 29,
111            ImuBrickFunction::GetQuaternionPeriod => 30,
112            ImuBrickFunction::OrientationCalculationOn => 37,
113            ImuBrickFunction::OrientationCalculationOff => 38,
114            ImuBrickFunction::IsOrientationCalculationOn => 39,
115            ImuBrickFunction::SetSpitfpBaudrateConfig => 231,
116            ImuBrickFunction::GetSpitfpBaudrateConfig => 232,
117            ImuBrickFunction::GetSendTimeoutCount => 233,
118            ImuBrickFunction::SetSpitfpBaudrate => 234,
119            ImuBrickFunction::GetSpitfpBaudrate => 235,
120            ImuBrickFunction::GetSpitfpErrorCount => 237,
121            ImuBrickFunction::EnableStatusLed => 238,
122            ImuBrickFunction::DisableStatusLed => 239,
123            ImuBrickFunction::IsStatusLedEnabled => 240,
124            ImuBrickFunction::GetProtocol1BrickletName => 241,
125            ImuBrickFunction::GetChipTemperature => 242,
126            ImuBrickFunction::Reset => 243,
127            ImuBrickFunction::WriteBrickletPlugin => 246,
128            ImuBrickFunction::ReadBrickletPlugin => 247,
129            ImuBrickFunction::GetIdentity => 255,
130            ImuBrickFunction::CallbackAcceleration => 31,
131            ImuBrickFunction::CallbackMagneticField => 32,
132            ImuBrickFunction::CallbackAngularVelocity => 33,
133            ImuBrickFunction::CallbackAllData => 34,
134            ImuBrickFunction::CallbackOrientation => 35,
135            ImuBrickFunction::CallbackQuaternion => 36,
136        }
137    }
138}
139pub const IMU_BRICK_CALIBRATION_TYPE_ACCELEROMETER_GAIN: u8 = 0;
140pub const IMU_BRICK_CALIBRATION_TYPE_ACCELEROMETER_BIAS: u8 = 1;
141pub const IMU_BRICK_CALIBRATION_TYPE_MAGNETOMETER_GAIN: u8 = 2;
142pub const IMU_BRICK_CALIBRATION_TYPE_MAGNETOMETER_BIAS: u8 = 3;
143pub const IMU_BRICK_CALIBRATION_TYPE_GYROSCOPE_GAIN: u8 = 4;
144pub const IMU_BRICK_CALIBRATION_TYPE_GYROSCOPE_BIAS: u8 = 5;
145pub const IMU_BRICK_COMMUNICATION_METHOD_NONE: u8 = 0;
146pub const IMU_BRICK_COMMUNICATION_METHOD_USB: u8 = 1;
147pub const IMU_BRICK_COMMUNICATION_METHOD_SPI_STACK: u8 = 2;
148pub const IMU_BRICK_COMMUNICATION_METHOD_CHIBI: u8 = 3;
149pub const IMU_BRICK_COMMUNICATION_METHOD_RS485: u8 = 4;
150pub const IMU_BRICK_COMMUNICATION_METHOD_WIFI: u8 = 5;
151pub const IMU_BRICK_COMMUNICATION_METHOD_ETHERNET: u8 = 6;
152pub const IMU_BRICK_COMMUNICATION_METHOD_WIFI_V2: u8 = 7;
153
154#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
155pub struct Acceleration {
156    pub x: i16,
157    pub y: i16,
158    pub z: i16,
159}
160impl FromByteSlice for Acceleration {
161    fn bytes_expected() -> usize {
162        6
163    }
164    fn from_le_byte_slice(bytes: &[u8]) -> Acceleration {
165        Acceleration {
166            x: <i16>::from_le_byte_slice(&bytes[0..2]),
167            y: <i16>::from_le_byte_slice(&bytes[2..4]),
168            z: <i16>::from_le_byte_slice(&bytes[4..6]),
169        }
170    }
171}
172
173#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
174pub struct MagneticField {
175    pub x: i16,
176    pub y: i16,
177    pub z: i16,
178}
179impl FromByteSlice for MagneticField {
180    fn bytes_expected() -> usize {
181        6
182    }
183    fn from_le_byte_slice(bytes: &[u8]) -> MagneticField {
184        MagneticField {
185            x: <i16>::from_le_byte_slice(&bytes[0..2]),
186            y: <i16>::from_le_byte_slice(&bytes[2..4]),
187            z: <i16>::from_le_byte_slice(&bytes[4..6]),
188        }
189    }
190}
191
192#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
193pub struct AngularVelocity {
194    pub x: i16,
195    pub y: i16,
196    pub z: i16,
197}
198impl FromByteSlice for AngularVelocity {
199    fn bytes_expected() -> usize {
200        6
201    }
202    fn from_le_byte_slice(bytes: &[u8]) -> AngularVelocity {
203        AngularVelocity {
204            x: <i16>::from_le_byte_slice(&bytes[0..2]),
205            y: <i16>::from_le_byte_slice(&bytes[2..4]),
206            z: <i16>::from_le_byte_slice(&bytes[4..6]),
207        }
208    }
209}
210
211#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
212pub struct AllData {
213    pub acc_x: i16,
214    pub acc_y: i16,
215    pub acc_z: i16,
216    pub mag_x: i16,
217    pub mag_y: i16,
218    pub mag_z: i16,
219    pub ang_x: i16,
220    pub ang_y: i16,
221    pub ang_z: i16,
222    pub temperature: i16,
223}
224impl FromByteSlice for AllData {
225    fn bytes_expected() -> usize {
226        20
227    }
228    fn from_le_byte_slice(bytes: &[u8]) -> AllData {
229        AllData {
230            acc_x: <i16>::from_le_byte_slice(&bytes[0..2]),
231            acc_y: <i16>::from_le_byte_slice(&bytes[2..4]),
232            acc_z: <i16>::from_le_byte_slice(&bytes[4..6]),
233            mag_x: <i16>::from_le_byte_slice(&bytes[6..8]),
234            mag_y: <i16>::from_le_byte_slice(&bytes[8..10]),
235            mag_z: <i16>::from_le_byte_slice(&bytes[10..12]),
236            ang_x: <i16>::from_le_byte_slice(&bytes[12..14]),
237            ang_y: <i16>::from_le_byte_slice(&bytes[14..16]),
238            ang_z: <i16>::from_le_byte_slice(&bytes[16..18]),
239            temperature: <i16>::from_le_byte_slice(&bytes[18..20]),
240        }
241    }
242}
243
244#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
245pub struct Orientation {
246    pub roll: i16,
247    pub pitch: i16,
248    pub yaw: i16,
249}
250impl FromByteSlice for Orientation {
251    fn bytes_expected() -> usize {
252        6
253    }
254    fn from_le_byte_slice(bytes: &[u8]) -> Orientation {
255        Orientation {
256            roll: <i16>::from_le_byte_slice(&bytes[0..2]),
257            pitch: <i16>::from_le_byte_slice(&bytes[2..4]),
258            yaw: <i16>::from_le_byte_slice(&bytes[4..6]),
259        }
260    }
261}
262
263#[derive(Clone, Copy, Debug, Default, PartialEq)]
264pub struct Quaternion {
265    pub x: f32,
266    pub y: f32,
267    pub z: f32,
268    pub w: f32,
269}
270impl FromByteSlice for Quaternion {
271    fn bytes_expected() -> usize {
272        16
273    }
274    fn from_le_byte_slice(bytes: &[u8]) -> Quaternion {
275        Quaternion {
276            x: <f32>::from_le_byte_slice(&bytes[0..4]),
277            y: <f32>::from_le_byte_slice(&bytes[4..8]),
278            z: <f32>::from_le_byte_slice(&bytes[8..12]),
279            w: <f32>::from_le_byte_slice(&bytes[12..16]),
280        }
281    }
282}
283
284#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
285pub struct AccelerationEvent {
286    pub x: i16,
287    pub y: i16,
288    pub z: i16,
289}
290impl FromByteSlice for AccelerationEvent {
291    fn bytes_expected() -> usize {
292        6
293    }
294    fn from_le_byte_slice(bytes: &[u8]) -> AccelerationEvent {
295        AccelerationEvent {
296            x: <i16>::from_le_byte_slice(&bytes[0..2]),
297            y: <i16>::from_le_byte_slice(&bytes[2..4]),
298            z: <i16>::from_le_byte_slice(&bytes[4..6]),
299        }
300    }
301}
302
303#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
304pub struct MagneticFieldEvent {
305    pub x: i16,
306    pub y: i16,
307    pub z: i16,
308}
309impl FromByteSlice for MagneticFieldEvent {
310    fn bytes_expected() -> usize {
311        6
312    }
313    fn from_le_byte_slice(bytes: &[u8]) -> MagneticFieldEvent {
314        MagneticFieldEvent {
315            x: <i16>::from_le_byte_slice(&bytes[0..2]),
316            y: <i16>::from_le_byte_slice(&bytes[2..4]),
317            z: <i16>::from_le_byte_slice(&bytes[4..6]),
318        }
319    }
320}
321
322#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
323pub struct AngularVelocityEvent {
324    pub x: i16,
325    pub y: i16,
326    pub z: i16,
327}
328impl FromByteSlice for AngularVelocityEvent {
329    fn bytes_expected() -> usize {
330        6
331    }
332    fn from_le_byte_slice(bytes: &[u8]) -> AngularVelocityEvent {
333        AngularVelocityEvent {
334            x: <i16>::from_le_byte_slice(&bytes[0..2]),
335            y: <i16>::from_le_byte_slice(&bytes[2..4]),
336            z: <i16>::from_le_byte_slice(&bytes[4..6]),
337        }
338    }
339}
340
341#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
342pub struct AllDataEvent {
343    pub acc_x: i16,
344    pub acc_y: i16,
345    pub acc_z: i16,
346    pub mag_x: i16,
347    pub mag_y: i16,
348    pub mag_z: i16,
349    pub ang_x: i16,
350    pub ang_y: i16,
351    pub ang_z: i16,
352    pub temperature: i16,
353}
354impl FromByteSlice for AllDataEvent {
355    fn bytes_expected() -> usize {
356        20
357    }
358    fn from_le_byte_slice(bytes: &[u8]) -> AllDataEvent {
359        AllDataEvent {
360            acc_x: <i16>::from_le_byte_slice(&bytes[0..2]),
361            acc_y: <i16>::from_le_byte_slice(&bytes[2..4]),
362            acc_z: <i16>::from_le_byte_slice(&bytes[4..6]),
363            mag_x: <i16>::from_le_byte_slice(&bytes[6..8]),
364            mag_y: <i16>::from_le_byte_slice(&bytes[8..10]),
365            mag_z: <i16>::from_le_byte_slice(&bytes[10..12]),
366            ang_x: <i16>::from_le_byte_slice(&bytes[12..14]),
367            ang_y: <i16>::from_le_byte_slice(&bytes[14..16]),
368            ang_z: <i16>::from_le_byte_slice(&bytes[16..18]),
369            temperature: <i16>::from_le_byte_slice(&bytes[18..20]),
370        }
371    }
372}
373
374#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
375pub struct OrientationEvent {
376    pub roll: i16,
377    pub pitch: i16,
378    pub yaw: i16,
379}
380impl FromByteSlice for OrientationEvent {
381    fn bytes_expected() -> usize {
382        6
383    }
384    fn from_le_byte_slice(bytes: &[u8]) -> OrientationEvent {
385        OrientationEvent {
386            roll: <i16>::from_le_byte_slice(&bytes[0..2]),
387            pitch: <i16>::from_le_byte_slice(&bytes[2..4]),
388            yaw: <i16>::from_le_byte_slice(&bytes[4..6]),
389        }
390    }
391}
392
393#[derive(Clone, Copy, Debug, Default, PartialEq)]
394pub struct QuaternionEvent {
395    pub x: f32,
396    pub y: f32,
397    pub z: f32,
398    pub w: f32,
399}
400impl FromByteSlice for QuaternionEvent {
401    fn bytes_expected() -> usize {
402        16
403    }
404    fn from_le_byte_slice(bytes: &[u8]) -> QuaternionEvent {
405        QuaternionEvent {
406            x: <f32>::from_le_byte_slice(&bytes[0..4]),
407            y: <f32>::from_le_byte_slice(&bytes[4..8]),
408            z: <f32>::from_le_byte_slice(&bytes[8..12]),
409            w: <f32>::from_le_byte_slice(&bytes[12..16]),
410        }
411    }
412}
413
414#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
415pub struct SpitfpBaudrateConfig {
416    pub enable_dynamic_baudrate: bool,
417    pub minimum_dynamic_baudrate: u32,
418}
419impl FromByteSlice for SpitfpBaudrateConfig {
420    fn bytes_expected() -> usize {
421        5
422    }
423    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpBaudrateConfig {
424        SpitfpBaudrateConfig {
425            enable_dynamic_baudrate: <bool>::from_le_byte_slice(&bytes[0..1]),
426            minimum_dynamic_baudrate: <u32>::from_le_byte_slice(&bytes[1..5]),
427        }
428    }
429}
430
431#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
432pub struct SpitfpErrorCount {
433    pub error_count_ack_checksum: u32,
434    pub error_count_message_checksum: u32,
435    pub error_count_frame: u32,
436    pub error_count_overflow: u32,
437}
438impl FromByteSlice for SpitfpErrorCount {
439    fn bytes_expected() -> usize {
440        16
441    }
442    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
443        SpitfpErrorCount {
444            error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
445            error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
446            error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
447            error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
448        }
449    }
450}
451
452#[derive(Clone)]
453pub struct Protocol1BrickletName {
454    pub protocol_version: u8,
455    pub firmware_version: [u8; 3],
456    pub name: String,
457}
458impl FromByteSlice for Protocol1BrickletName {
459    fn bytes_expected() -> usize {
460        44
461    }
462    fn from_le_byte_slice(bytes: &[u8]) -> Protocol1BrickletName {
463        Protocol1BrickletName {
464            protocol_version: <u8>::from_le_byte_slice(&bytes[0..1]),
465            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[1..4]),
466            name: <String>::from_le_byte_slice(&bytes[4..44]),
467        }
468    }
469}
470
471#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
472pub struct Identity {
473    pub uid: String,
474    pub connected_uid: String,
475    pub position: char,
476    pub hardware_version: [u8; 3],
477    pub firmware_version: [u8; 3],
478    pub device_identifier: u16,
479}
480impl FromByteSlice for Identity {
481    fn bytes_expected() -> usize {
482        25
483    }
484    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
485        Identity {
486            uid: <String>::from_le_byte_slice(&bytes[0..8]),
487            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
488            position: <char>::from_le_byte_slice(&bytes[16..17]),
489            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
490            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
491            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
492        }
493    }
494}
495
496/// Full fledged AHRS with 9 degrees of freedom
497#[derive(Clone)]
498pub struct ImuBrick {
499    device: Device,
500}
501impl ImuBrick {
502    pub const DEVICE_IDENTIFIER: u16 = 16;
503    pub const DEVICE_DISPLAY_NAME: &'static str = "IMU Brick";
504    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
505    pub fn new(uid: Uid, connection: AsyncIpConnection) -> ImuBrick {
506        let mut result = ImuBrick { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
507        result.device.response_expected[u8::from(ImuBrickFunction::GetAcceleration) as usize] = ResponseExpectedFlag::AlwaysTrue;
508        result.device.response_expected[u8::from(ImuBrickFunction::GetMagneticField) as usize] = ResponseExpectedFlag::AlwaysTrue;
509        result.device.response_expected[u8::from(ImuBrickFunction::GetAngularVelocity) as usize] = ResponseExpectedFlag::AlwaysTrue;
510        result.device.response_expected[u8::from(ImuBrickFunction::GetAllData) as usize] = ResponseExpectedFlag::AlwaysTrue;
511        result.device.response_expected[u8::from(ImuBrickFunction::GetOrientation) as usize] = ResponseExpectedFlag::AlwaysTrue;
512        result.device.response_expected[u8::from(ImuBrickFunction::GetQuaternion) as usize] = ResponseExpectedFlag::AlwaysTrue;
513        result.device.response_expected[u8::from(ImuBrickFunction::GetImuTemperature) as usize] = ResponseExpectedFlag::AlwaysTrue;
514        result.device.response_expected[u8::from(ImuBrickFunction::LedsOn) as usize] = ResponseExpectedFlag::False;
515        result.device.response_expected[u8::from(ImuBrickFunction::LedsOff) as usize] = ResponseExpectedFlag::False;
516        result.device.response_expected[u8::from(ImuBrickFunction::AreLedsOn) as usize] = ResponseExpectedFlag::AlwaysTrue;
517        result.device.response_expected[u8::from(ImuBrickFunction::SetAccelerationRange) as usize] = ResponseExpectedFlag::False;
518        result.device.response_expected[u8::from(ImuBrickFunction::GetAccelerationRange) as usize] = ResponseExpectedFlag::AlwaysTrue;
519        result.device.response_expected[u8::from(ImuBrickFunction::SetMagnetometerRange) as usize] = ResponseExpectedFlag::False;
520        result.device.response_expected[u8::from(ImuBrickFunction::GetMagnetometerRange) as usize] = ResponseExpectedFlag::AlwaysTrue;
521        result.device.response_expected[u8::from(ImuBrickFunction::SetConvergenceSpeed) as usize] = ResponseExpectedFlag::False;
522        result.device.response_expected[u8::from(ImuBrickFunction::GetConvergenceSpeed) as usize] = ResponseExpectedFlag::AlwaysTrue;
523        result.device.response_expected[u8::from(ImuBrickFunction::SetCalibration) as usize] = ResponseExpectedFlag::False;
524        result.device.response_expected[u8::from(ImuBrickFunction::GetCalibration) as usize] = ResponseExpectedFlag::AlwaysTrue;
525        result.device.response_expected[u8::from(ImuBrickFunction::SetAccelerationPeriod) as usize] = ResponseExpectedFlag::True;
526        result.device.response_expected[u8::from(ImuBrickFunction::GetAccelerationPeriod) as usize] = ResponseExpectedFlag::AlwaysTrue;
527        result.device.response_expected[u8::from(ImuBrickFunction::SetMagneticFieldPeriod) as usize] = ResponseExpectedFlag::True;
528        result.device.response_expected[u8::from(ImuBrickFunction::GetMagneticFieldPeriod) as usize] = ResponseExpectedFlag::AlwaysTrue;
529        result.device.response_expected[u8::from(ImuBrickFunction::SetAngularVelocityPeriod) as usize] = ResponseExpectedFlag::True;
530        result.device.response_expected[u8::from(ImuBrickFunction::GetAngularVelocityPeriod) as usize] = ResponseExpectedFlag::AlwaysTrue;
531        result.device.response_expected[u8::from(ImuBrickFunction::SetAllDataPeriod) as usize] = ResponseExpectedFlag::True;
532        result.device.response_expected[u8::from(ImuBrickFunction::GetAllDataPeriod) as usize] = ResponseExpectedFlag::AlwaysTrue;
533        result.device.response_expected[u8::from(ImuBrickFunction::SetOrientationPeriod) as usize] = ResponseExpectedFlag::True;
534        result.device.response_expected[u8::from(ImuBrickFunction::GetOrientationPeriod) as usize] = ResponseExpectedFlag::AlwaysTrue;
535        result.device.response_expected[u8::from(ImuBrickFunction::SetQuaternionPeriod) as usize] = ResponseExpectedFlag::True;
536        result.device.response_expected[u8::from(ImuBrickFunction::GetQuaternionPeriod) as usize] = ResponseExpectedFlag::AlwaysTrue;
537        result.device.response_expected[u8::from(ImuBrickFunction::OrientationCalculationOn) as usize] = ResponseExpectedFlag::False;
538        result.device.response_expected[u8::from(ImuBrickFunction::OrientationCalculationOff) as usize] = ResponseExpectedFlag::False;
539        result.device.response_expected[u8::from(ImuBrickFunction::IsOrientationCalculationOn) as usize] = ResponseExpectedFlag::AlwaysTrue;
540        result.device.response_expected[u8::from(ImuBrickFunction::SetSpitfpBaudrateConfig) as usize] = ResponseExpectedFlag::False;
541        result.device.response_expected[u8::from(ImuBrickFunction::GetSpitfpBaudrateConfig) as usize] = ResponseExpectedFlag::AlwaysTrue;
542        result.device.response_expected[u8::from(ImuBrickFunction::GetSendTimeoutCount) as usize] = ResponseExpectedFlag::AlwaysTrue;
543        result.device.response_expected[u8::from(ImuBrickFunction::SetSpitfpBaudrate) as usize] = ResponseExpectedFlag::False;
544        result.device.response_expected[u8::from(ImuBrickFunction::GetSpitfpBaudrate) as usize] = ResponseExpectedFlag::AlwaysTrue;
545        result.device.response_expected[u8::from(ImuBrickFunction::GetSpitfpErrorCount) as usize] = ResponseExpectedFlag::AlwaysTrue;
546        result.device.response_expected[u8::from(ImuBrickFunction::EnableStatusLed) as usize] = ResponseExpectedFlag::False;
547        result.device.response_expected[u8::from(ImuBrickFunction::DisableStatusLed) as usize] = ResponseExpectedFlag::False;
548        result.device.response_expected[u8::from(ImuBrickFunction::IsStatusLedEnabled) as usize] = ResponseExpectedFlag::AlwaysTrue;
549        result.device.response_expected[u8::from(ImuBrickFunction::GetProtocol1BrickletName) as usize] = ResponseExpectedFlag::AlwaysTrue;
550        result.device.response_expected[u8::from(ImuBrickFunction::GetChipTemperature) as usize] = ResponseExpectedFlag::AlwaysTrue;
551        result.device.response_expected[u8::from(ImuBrickFunction::Reset) as usize] = ResponseExpectedFlag::False;
552        result.device.response_expected[u8::from(ImuBrickFunction::WriteBrickletPlugin) as usize] = ResponseExpectedFlag::False;
553        result.device.response_expected[u8::from(ImuBrickFunction::ReadBrickletPlugin) as usize] = ResponseExpectedFlag::AlwaysTrue;
554        result.device.response_expected[u8::from(ImuBrickFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
555        result
556    }
557
558    /// Returns the response expected flag for the function specified by the function ID parameter.
559    /// It is true if the function is expected to send a response, false otherwise.
560    ///
561    /// For getter functions this is enabled by default and cannot be disabled, because those
562    /// functions will always send a response. For callback configuration functions it is enabled
563    /// by default too, but can be disabled by [`set_response_expected`](crate::imu_brick::ImuBrick::set_response_expected).
564    /// For setter functions it is disabled by default and can be enabled.
565    ///
566    /// Enabling the response expected flag for a setter function allows to detect timeouts
567    /// and other error conditions calls of this setter as well. The device will then send a response
568    /// for this purpose. If this flag is disabled for a setter function then no response is sent
569    /// and errors are silently ignored, because they cannot be detected.
570    ///
571    /// See [`set_response_expected`](crate::imu_brick::ImuBrick::set_response_expected) for the list of function ID constants available for this function.
572    pub fn get_response_expected(&mut self, fun: ImuBrickFunction) -> Result<bool, GetResponseExpectedError> {
573        self.device.get_response_expected(u8::from(fun))
574    }
575
576    /// Changes the response expected flag of the function specified by the function ID parameter.
577    /// This flag can only be changed for setter (default value: false) and callback configuration
578    /// functions (default value: true). For getter functions it is always enabled.
579    ///
580    /// Enabling the response expected flag for a setter function allows to detect timeouts and
581    /// other error conditions calls of this setter as well. The device will then send a response
582    /// for this purpose. If this flag is disabled for a setter function then no response is sent
583    /// and errors are silently ignored, because they cannot be detected.
584    pub fn set_response_expected(&mut self, fun: ImuBrickFunction, response_expected: bool) -> Result<(), SetResponseExpectedError> {
585        self.device.set_response_expected(u8::from(fun), response_expected)
586    }
587
588    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
589    pub fn set_response_expected_all(&mut self, response_expected: bool) {
590        self.device.set_response_expected_all(response_expected)
591    }
592
593    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
594    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
595    pub fn get_api_version(&self) -> [u8; 3] {
596        self.device.api_version
597    }
598
599    /// This receiver is triggered periodically with the period that is set by
600    /// [`set_acceleration_period`]. The parameters are the acceleration
601    /// for the x, y and z axis.
602    ///
603    /// [`set_acceleration_period`]: #method.set_acceleration_period
604    pub async fn get_acceleration_callback_receiver(&mut self) -> impl Stream<Item = AccelerationEvent> {
605        self.device
606            .get_callback_receiver(u8::from(ImuBrickFunction::CallbackAcceleration))
607            .await
608            .map(|p| AccelerationEvent::from_le_byte_slice(p.body()))
609    }
610
611    /// This receiver is triggered periodically with the period that is set by
612    /// [`set_magnetic_field_period`]. The parameters are the magnetic
613    /// field for the x, y and z axis.
614    pub async fn get_magnetic_field_callback_receiver(&mut self) -> impl Stream<Item = MagneticFieldEvent> {
615        self.device
616            .get_callback_receiver(u8::from(ImuBrickFunction::CallbackMagneticField))
617            .await
618            .map(|p| MagneticFieldEvent::from_le_byte_slice(p.body()))
619    }
620
621    /// This receiver is triggered periodically with the period that is set by
622    /// [`set_angular_velocity_period`]. The parameters are the angular
623    /// velocity for the x, y and z axis.
624    pub async fn get_angular_velocity_callback_receiver(&mut self) -> impl Stream<Item = AngularVelocityEvent> {
625        self.device
626            .get_callback_receiver(u8::from(ImuBrickFunction::CallbackAngularVelocity))
627            .await
628            .map(|p| AngularVelocityEvent::from_le_byte_slice(p.body()))
629    }
630
631    /// This receiver is triggered periodically with the period that is set by
632    /// [`set_all_data_period`]. The parameters are the acceleration,
633    /// the magnetic field and the angular velocity for the x, y and z axis as
634    /// well as the temperature of the IMU Brick.
635    pub async fn get_all_data_callback_receiver(&mut self) -> impl Stream<Item = AllDataEvent> {
636        self.device
637            .get_callback_receiver(u8::from(ImuBrickFunction::CallbackAllData))
638            .await
639            .map(|p| AllDataEvent::from_le_byte_slice(p.body()))
640    }
641
642    /// This receiver is triggered periodically with the period that is set by
643    /// [`set_orientation_period`]. The parameters are the orientation
644    /// (roll, pitch and yaw) of the IMU Brick in Euler angles. See
645    /// [`get_orientation`] for details.
646    pub async fn get_orientation_callback_receiver(&mut self) -> impl Stream<Item = OrientationEvent> {
647        self.device
648            .get_callback_receiver(u8::from(ImuBrickFunction::CallbackOrientation))
649            .await
650            .map(|p| OrientationEvent::from_le_byte_slice(p.body()))
651    }
652
653    /// This receiver is triggered periodically with the period that is set by
654    /// [`set_quaternion_period`]. The parameters are the orientation
655    /// (x, y, z, w) of the IMU Brick in quaternions. See [`get_quaternion`]
656    /// for details.
657    pub async fn get_quaternion_callback_receiver(&mut self) -> impl Stream<Item = QuaternionEvent> {
658        self.device
659            .get_callback_receiver(u8::from(ImuBrickFunction::CallbackQuaternion))
660            .await
661            .map(|p| QuaternionEvent::from_le_byte_slice(p.body()))
662    }
663
664    /// Returns the calibrated acceleration from the accelerometer for the
665    /// x, y and z axis.
666    ///
667    /// If you want to get the acceleration periodically, it is recommended
668    /// to use the [`get_acceleration_callback_receiver`] receiver and set the period with
669    /// [`set_acceleration_period`].
670    pub async fn get_acceleration(&mut self) -> Result<Acceleration, TinkerforgeError> {
671        let payload = [0; 0];
672
673        #[allow(unused_variables)]
674        let result = self.device.get(u8::from(ImuBrickFunction::GetAcceleration), &payload).await?;
675        Ok(Acceleration::from_le_byte_slice(result.body()))
676    }
677
678    /// Returns the calibrated magnetic field from the magnetometer for the
679    /// x, y and z axis.
680    ///
681    /// If you want to get the magnetic field periodically, it is recommended
682    /// to use the [`get_magnetic_field_callback_receiver`] receiver and set the period with
683    /// [`set_magnetic_field_period`].
684    pub async fn get_magnetic_field(&mut self) -> Result<MagneticField, TinkerforgeError> {
685        let payload = [0; 0];
686
687        #[allow(unused_variables)]
688        let result = self.device.get(u8::from(ImuBrickFunction::GetMagneticField), &payload).await?;
689        Ok(MagneticField::from_le_byte_slice(result.body()))
690    }
691
692    /// Returns the calibrated angular velocity from the gyroscope for the
693    /// x, y and z axis in °/14.375s (you have to divide by 14.375 to
694    /// get the value in °/s).
695    ///
696    /// If you want to get the angular velocity periodically, it is recommended
697    /// to use the [`get_angular_velocity_callback_receiver`] receiver and set the period with
698    /// [`set_angular_velocity_period`].
699    pub async fn get_angular_velocity(&mut self) -> Result<AngularVelocity, TinkerforgeError> {
700        let payload = [0; 0];
701
702        #[allow(unused_variables)]
703        let result = self.device.get(u8::from(ImuBrickFunction::GetAngularVelocity), &payload).await?;
704        Ok(AngularVelocity::from_le_byte_slice(result.body()))
705    }
706
707    /// Returns the data from [`get_acceleration`], [`get_magnetic_field`]
708    /// and [`get_angular_velocity`] as well as the temperature of the IMU Brick.
709    ///
710    /// If you want to get the data periodically, it is recommended
711    /// to use the [`get_all_data_callback_receiver`] receiver and set the period with
712    /// [`set_all_data_period`].
713    pub async fn get_all_data(&mut self) -> Result<AllData, TinkerforgeError> {
714        let payload = [0; 0];
715
716        #[allow(unused_variables)]
717        let result = self.device.get(u8::from(ImuBrickFunction::GetAllData), &payload).await?;
718        Ok(AllData::from_le_byte_slice(result.body()))
719    }
720
721    /// Returns the current orientation (roll, pitch, yaw) of the IMU Brick as Euler
722    /// angles. Note that Euler angles always experience a
723    /// [gimbal lock](https://en.wikipedia.org/wiki/Gimbal_lock)__.
724    ///
725    /// We recommend that you use quaternions instead.
726    ///
727    /// The order to sequence in which the orientation values should be applied is
728    /// roll, yaw, pitch.
729    ///
730    /// If you want to get the orientation periodically, it is recommended
731    /// to use the [`get_orientation_callback_receiver`] receiver and set the period with
732    /// [`set_orientation_period`].
733    pub async fn get_orientation(&mut self) -> Result<Orientation, TinkerforgeError> {
734        let payload = [0; 0];
735
736        #[allow(unused_variables)]
737        let result = self.device.get(u8::from(ImuBrickFunction::GetOrientation), &payload).await?;
738        Ok(Orientation::from_le_byte_slice(result.body()))
739    }
740
741    /// Returns the current orientation (x, y, z, w) of the IMU as
742    /// [quaternions](https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation)__.
743    ///
744    /// You can go from quaternions to Euler angles with the following formula::
745    ///
746    ///  xAngle = atan2(2*y*w - 2*x*z, 1 - 2*y*y - 2*z*z)
747    ///  yAngle = atan2(2*x*w - 2*y*z, 1 - 2*x*x - 2*z*z)
748    ///  zAngle =  asin(2*x*y + 2*z*w)
749    ///
750    /// This process is not reversible, because of the
751    /// [gimbal lock](https://en.wikipedia.org/wiki/Gimbal_lock)__.
752    ///
753    /// It is also possible to calculate independent angles. You can calculate
754    /// yaw, pitch and roll in a right-handed vehicle coordinate system according to
755    /// DIN70000 with::
756    ///
757    ///  yaw   =  atan2(2*x*y + 2*w*z, w*w + x*x - y*y - z*z)
758    ///  pitch = -asin(2*w*y - 2*x*z)
759    ///  roll  = -atan2(2*y*z + 2*w*x, -w*w + x*x + y*y - z*z))
760    ///
761    /// Converting the quaternions to an OpenGL transformation matrix is
762    /// possible with the following formula::
763    ///
764    ///  matrix = [[1 - 2*(y*y + z*z),     2*(x*y - w*z),     2*(x*z + w*y), 0],
765    ///            [    2*(x*y + w*z), 1 - 2*(x*x + z*z),     2*(y*z - w*x), 0],
766    ///            [    2*(x*z - w*y),     2*(y*z + w*x), 1 - 2*(x*x + y*y), 0],
767    ///            [                0,                 0,                 0, 1]]
768    ///
769    /// If you want to get the quaternions periodically, it is recommended
770    /// to use the [`get_quaternion_callback_receiver`] receiver and set the period with
771    /// [`set_quaternion_period`].
772    pub async fn get_quaternion(&mut self) -> Result<Quaternion, TinkerforgeError> {
773        let payload = [0; 0];
774
775        #[allow(unused_variables)]
776        let result = self.device.get(u8::from(ImuBrickFunction::GetQuaternion), &payload).await?;
777        Ok(Quaternion::from_le_byte_slice(result.body()))
778    }
779
780    /// Returns the temperature of the IMU Brick.
781    pub async fn get_imu_temperature(&mut self) -> Result<i16, TinkerforgeError> {
782        let payload = [0; 0];
783
784        #[allow(unused_variables)]
785        let result = self.device.get(u8::from(ImuBrickFunction::GetImuTemperature), &payload).await?;
786        Ok(i16::from_le_byte_slice(result.body()))
787    }
788
789    /// Turns the orientation and direction LEDs of the IMU Brick on.
790    pub async fn leds_on(&mut self) -> Result<(), TinkerforgeError> {
791        let payload = [0; 0];
792
793        #[allow(unused_variables)]
794        let result = self.device.set(u8::from(ImuBrickFunction::LedsOn), &payload).await?;
795        Ok(())
796    }
797
798    /// Turns the orientation and direction LEDs of the IMU Brick off.
799    pub async fn leds_off(&mut self) -> Result<(), TinkerforgeError> {
800        let payload = [0; 0];
801
802        #[allow(unused_variables)]
803        let result = self.device.set(u8::from(ImuBrickFunction::LedsOff), &payload).await?;
804        Ok(())
805    }
806
807    /// Returns *true* if the orientation and direction LEDs of the IMU Brick
808    /// are on, *false* otherwise.
809    pub async fn are_leds_on(&mut self) -> Result<bool, TinkerforgeError> {
810        let payload = [0; 0];
811
812        #[allow(unused_variables)]
813        let result = self.device.get(u8::from(ImuBrickFunction::AreLedsOn), &payload).await?;
814        Ok(bool::from_le_byte_slice(result.body()))
815    }
816
817    /// Not implemented yet.
818    pub async fn set_acceleration_range(&mut self, range: u8) -> Result<(), TinkerforgeError> {
819        let mut payload = [0; 1];
820        range.write_to_slice(&mut payload[0..1]);
821
822        #[allow(unused_variables)]
823        let result = self.device.set(u8::from(ImuBrickFunction::SetAccelerationRange), &payload).await?;
824        Ok(())
825    }
826
827    /// Not implemented yet.
828    pub async fn get_acceleration_range(&mut self) -> Result<u8, TinkerforgeError> {
829        let payload = [0; 0];
830
831        #[allow(unused_variables)]
832        let result = self.device.get(u8::from(ImuBrickFunction::GetAccelerationRange), &payload).await?;
833        Ok(u8::from_le_byte_slice(result.body()))
834    }
835
836    /// Not implemented yet.
837    pub async fn set_magnetometer_range(&mut self, range: u8) -> Result<(), TinkerforgeError> {
838        let mut payload = [0; 1];
839        range.write_to_slice(&mut payload[0..1]);
840
841        #[allow(unused_variables)]
842        let result = self.device.set(u8::from(ImuBrickFunction::SetMagnetometerRange), &payload).await?;
843        Ok(())
844    }
845
846    /// Not implemented yet.
847    pub async fn get_magnetometer_range(&mut self) -> Result<u8, TinkerforgeError> {
848        let payload = [0; 0];
849
850        #[allow(unused_variables)]
851        let result = self.device.get(u8::from(ImuBrickFunction::GetMagnetometerRange), &payload).await?;
852        Ok(u8::from_le_byte_slice(result.body()))
853    }
854
855    /// Sets the convergence speed of the IMU Brick. The convergence speed
856    /// determines how the different sensor measurements are fused.
857    ///
858    /// If the orientation of the IMU Brick is off by 10° and the convergence speed is
859    /// set to 20°/s, it will take 0.5s until the orientation is corrected. However,
860    /// if the correct orientation is reached and the convergence speed is too high,
861    /// the orientation will fluctuate with the fluctuations of the accelerometer and
862    /// the magnetometer.
863    ///
864    /// If you set the convergence speed to 0, practically only the gyroscope is used
865    /// to calculate the orientation. This gives very smooth movements, but errors of the
866    /// gyroscope will not be corrected. If you set the convergence speed to something
867    /// above 500, practically only the magnetometer and the accelerometer are used to
868    /// calculate the orientation. In this case the movements are abrupt and the values
869    /// will fluctuate, but there won't be any errors that accumulate over time.
870    ///
871    /// In an application with high angular velocities, we recommend a high convergence
872    /// speed, so the errors of the gyroscope can be corrected fast. In applications with
873    /// only slow movements we recommend a low convergence speed. You can change the
874    /// convergence speed on the fly. So it is possible (and recommended) to increase
875    /// the convergence speed before an abrupt movement and decrease it afterwards
876    /// again.
877    ///
878    /// You might want to play around with the convergence speed in the Brick Viewer to
879    /// get a feeling for a good value for your application.
880    pub async fn set_convergence_speed(&mut self, speed: u16) -> Result<(), TinkerforgeError> {
881        let mut payload = [0; 2];
882        speed.write_to_slice(&mut payload[0..2]);
883
884        #[allow(unused_variables)]
885        let result = self.device.set(u8::from(ImuBrickFunction::SetConvergenceSpeed), &payload).await?;
886        Ok(())
887    }
888
889    /// Returns the convergence speed as set by [`set_convergence_speed`].
890    pub async fn get_convergence_speed(&mut self) -> Result<u16, TinkerforgeError> {
891        let payload = [0; 0];
892
893        #[allow(unused_variables)]
894        let result = self.device.get(u8::from(ImuBrickFunction::GetConvergenceSpeed), &payload).await?;
895        Ok(u16::from_le_byte_slice(result.body()))
896    }
897
898    /// There are several different types that can be calibrated:
899    ///
900    ///  Type| Description| Values
901    ///  --- | --- | ---
902    ///  0|    Accelerometer Gain| ``[mul x| mul y| mul z| div x| div y| div z| 0| 0| 0| 0]``
903    ///  1|    Accelerometer Bias| ``[bias x| bias y| bias z| 0| 0| 0| 0| 0| 0| 0]``
904    ///  2|    Magnetometer Gain|  ``[mul x| mul y| mul z| div x| div y| div z| 0| 0| 0| 0]``
905    ///  3|    Magnetometer Bias|  ``[bias x| bias y| bias z| 0| 0| 0| 0| 0| 0| 0]``
906    ///  4|    Gyroscope Gain|     ``[mul x| mul y| mul z| div x| div y| div z| 0| 0| 0| 0]``
907    ///  5|    Gyroscope Bias|     ``[bias xl| bias yl| bias zl| temp l| bias xh| bias yh| bias zh| temp h| 0| 0]``
908    ///
909    /// The calibration via gain and bias is done with the following formula::
910    ///
911    ///  new_value = (bias + orig_value) * gain_mul / gain_div
912    ///
913    /// If you really want to write your own calibration software, please keep
914    /// in mind that you first have to undo the old calibration (set bias to 0 and
915    /// gain to 1/1) and that you have to average over several thousand values
916    /// to obtain a usable result in the end.
917    ///
918    /// The gyroscope bias is highly dependent on the temperature, so you have to
919    /// calibrate the bias two times with different temperatures. The values ``xl``,
920    /// ``yl``, ``zl`` and ``temp l`` are the bias for ``x``, ``y``, ``z`` and the
921    /// corresponding temperature for a low temperature. The values ``xh``, ``yh``,
922    /// ``zh`` and ``temp h`` are the same for a high temperatures. The temperature
923    /// difference should be at least 5°C. If you have a temperature where the
924    /// IMU Brick is mostly used, you should use this temperature for one of the
925    /// sampling points.
926    ///
927    /// # Note
928    ///  We highly recommend that you use the Brick Viewer to calibrate your
929    ///  IMU Brick.
930    ///
931    /// Associated constants:
932    /// * IMU_BRICK_CALIBRATION_TYPE_ACCELEROMETER_GAIN
933    ///	* IMU_BRICK_CALIBRATION_TYPE_ACCELEROMETER_BIAS
934    ///	* IMU_BRICK_CALIBRATION_TYPE_MAGNETOMETER_GAIN
935    ///	* IMU_BRICK_CALIBRATION_TYPE_MAGNETOMETER_BIAS
936    ///	* IMU_BRICK_CALIBRATION_TYPE_GYROSCOPE_GAIN
937    ///	* IMU_BRICK_CALIBRATION_TYPE_GYROSCOPE_BIAS
938    pub async fn set_calibration(&mut self, typ: u8, data: &[i16; 10]) -> Result<(), TinkerforgeError> {
939        let mut payload = [0; 21];
940        typ.write_to_slice(&mut payload[0..1]);
941        data.write_to_slice(&mut payload[1..21]);
942
943        #[allow(unused_variables)]
944        let result = self.device.set(u8::from(ImuBrickFunction::SetCalibration), &payload).await?;
945        Ok(())
946    }
947
948    /// Returns the calibration for a given type as set by [`set_calibration`].
949    ///
950    /// Associated constants:
951    /// * IMU_BRICK_CALIBRATION_TYPE_ACCELEROMETER_GAIN
952    ///	* IMU_BRICK_CALIBRATION_TYPE_ACCELEROMETER_BIAS
953    ///	* IMU_BRICK_CALIBRATION_TYPE_MAGNETOMETER_GAIN
954    ///	* IMU_BRICK_CALIBRATION_TYPE_MAGNETOMETER_BIAS
955    ///	* IMU_BRICK_CALIBRATION_TYPE_GYROSCOPE_GAIN
956    ///	* IMU_BRICK_CALIBRATION_TYPE_GYROSCOPE_BIAS
957    pub async fn get_calibration(&mut self, typ: u8) -> Result<Box<[i16; 10]>, TinkerforgeError> {
958        let mut payload = [0; 1];
959        typ.write_to_slice(&mut payload[0..1]);
960
961        #[allow(unused_variables)]
962        let result = self.device.get(u8::from(ImuBrickFunction::GetCalibration), &payload).await?;
963        Ok(Box::<[i16; 10]>::from_le_byte_slice(result.body()))
964    }
965
966    /// Sets the period with which the [`get_acceleration_callback_receiver`] receiver is triggered
967    /// periodically. A value of 0 turns the receiver off.
968    pub async fn set_acceleration_period(&mut self, period: u32) -> Result<(), TinkerforgeError> {
969        let mut payload = [0; 4];
970        period.write_to_slice(&mut payload[0..4]);
971
972        #[allow(unused_variables)]
973        let result = self.device.set(u8::from(ImuBrickFunction::SetAccelerationPeriod), &payload).await?;
974        Ok(())
975    }
976
977    /// Returns the period as set by [`set_acceleration_period`].
978    pub async fn get_acceleration_period(&mut self) -> Result<u32, TinkerforgeError> {
979        let payload = [0; 0];
980
981        #[allow(unused_variables)]
982        let result = self.device.get(u8::from(ImuBrickFunction::GetAccelerationPeriod), &payload).await?;
983        Ok(u32::from_le_byte_slice(result.body()))
984    }
985
986    /// Sets the period with which the [`get_magnetic_field_callback_receiver`] receiver is
987    /// triggered periodically. A value of 0 turns the receiver off.
988    pub async fn set_magnetic_field_period(&mut self, period: u32) -> Result<(), TinkerforgeError> {
989        let mut payload = [0; 4];
990        period.write_to_slice(&mut payload[0..4]);
991
992        #[allow(unused_variables)]
993        let result = self.device.set(u8::from(ImuBrickFunction::SetMagneticFieldPeriod), &payload).await?;
994        Ok(())
995    }
996
997    /// Returns the period as set by [`set_magnetic_field_period`].
998    pub async fn get_magnetic_field_period(&mut self) -> Result<u32, TinkerforgeError> {
999        let payload = [0; 0];
1000
1001        #[allow(unused_variables)]
1002        let result = self.device.get(u8::from(ImuBrickFunction::GetMagneticFieldPeriod), &payload).await?;
1003        Ok(u32::from_le_byte_slice(result.body()))
1004    }
1005
1006    /// Sets the period with which the [`get_angular_velocity_callback_receiver`] receiver is
1007    /// triggered periodically. A value of 0 turns the receiver off.
1008    pub async fn set_angular_velocity_period(&mut self, period: u32) -> Result<(), TinkerforgeError> {
1009        let mut payload = [0; 4];
1010        period.write_to_slice(&mut payload[0..4]);
1011
1012        #[allow(unused_variables)]
1013        let result = self.device.set(u8::from(ImuBrickFunction::SetAngularVelocityPeriod), &payload).await?;
1014        Ok(())
1015    }
1016
1017    /// Returns the period as set by [`set_angular_velocity_period`].
1018    pub async fn get_angular_velocity_period(&mut self) -> Result<u32, TinkerforgeError> {
1019        let payload = [0; 0];
1020
1021        #[allow(unused_variables)]
1022        let result = self.device.get(u8::from(ImuBrickFunction::GetAngularVelocityPeriod), &payload).await?;
1023        Ok(u32::from_le_byte_slice(result.body()))
1024    }
1025
1026    /// Sets the period with which the [`get_all_data_callback_receiver`] receiver is triggered
1027    /// periodically. A value of 0 turns the receiver off.
1028    pub async fn set_all_data_period(&mut self, period: u32) -> Result<(), TinkerforgeError> {
1029        let mut payload = [0; 4];
1030        period.write_to_slice(&mut payload[0..4]);
1031
1032        #[allow(unused_variables)]
1033        let result = self.device.set(u8::from(ImuBrickFunction::SetAllDataPeriod), &payload).await?;
1034        Ok(())
1035    }
1036
1037    /// Returns the period as set by [`set_all_data_period`].
1038    pub async fn get_all_data_period(&mut self) -> Result<u32, TinkerforgeError> {
1039        let payload = [0; 0];
1040
1041        #[allow(unused_variables)]
1042        let result = self.device.get(u8::from(ImuBrickFunction::GetAllDataPeriod), &payload).await?;
1043        Ok(u32::from_le_byte_slice(result.body()))
1044    }
1045
1046    /// Sets the period with which the [`get_orientation_callback_receiver`] receiver is triggered
1047    /// periodically. A value of 0 turns the receiver off.
1048    pub async fn set_orientation_period(&mut self, period: u32) -> Result<(), TinkerforgeError> {
1049        let mut payload = [0; 4];
1050        period.write_to_slice(&mut payload[0..4]);
1051
1052        #[allow(unused_variables)]
1053        let result = self.device.set(u8::from(ImuBrickFunction::SetOrientationPeriod), &payload).await?;
1054        Ok(())
1055    }
1056
1057    /// Returns the period as set by [`set_orientation_period`].
1058    pub async fn get_orientation_period(&mut self) -> Result<u32, TinkerforgeError> {
1059        let payload = [0; 0];
1060
1061        #[allow(unused_variables)]
1062        let result = self.device.get(u8::from(ImuBrickFunction::GetOrientationPeriod), &payload).await?;
1063        Ok(u32::from_le_byte_slice(result.body()))
1064    }
1065
1066    /// Sets the period with which the [`get_quaternion_callback_receiver`] receiver is triggered
1067    /// periodically. A value of 0 turns the receiver off.
1068    pub async fn set_quaternion_period(&mut self, period: u32) -> Result<(), TinkerforgeError> {
1069        let mut payload = [0; 4];
1070        period.write_to_slice(&mut payload[0..4]);
1071
1072        #[allow(unused_variables)]
1073        let result = self.device.set(u8::from(ImuBrickFunction::SetQuaternionPeriod), &payload).await?;
1074        Ok(())
1075    }
1076
1077    /// Returns the period as set by [`set_quaternion_period`].
1078    pub async fn get_quaternion_period(&mut self) -> Result<u32, TinkerforgeError> {
1079        let payload = [0; 0];
1080
1081        #[allow(unused_variables)]
1082        let result = self.device.get(u8::from(ImuBrickFunction::GetQuaternionPeriod), &payload).await?;
1083        Ok(u32::from_le_byte_slice(result.body()))
1084    }
1085
1086    /// Turns the orientation calculation of the IMU Brick on.
1087    ///
1088    /// As default the calculation is on.
1089    ///
1090    ///
1091    /// .. versionadded:: 2.0.2$nbsp;(Firmware)
1092    pub async fn orientation_calculation_on(&mut self) -> Result<(), TinkerforgeError> {
1093        let payload = [0; 0];
1094
1095        #[allow(unused_variables)]
1096        let result = self.device.set(u8::from(ImuBrickFunction::OrientationCalculationOn), &payload).await?;
1097        Ok(())
1098    }
1099
1100    /// Turns the orientation calculation of the IMU Brick off.
1101    ///
1102    /// If the calculation is off, [`get_orientation`] will return
1103    /// the last calculated value until the calculation is turned on again.
1104    ///
1105    /// The trigonometric functions that are needed to calculate the orientation
1106    /// are very expensive. We recommend to turn the orientation calculation
1107    /// off if the orientation is not needed, to free calculation time for the
1108    /// sensor fusion algorithm.
1109    ///
1110    /// As default the calculation is on.
1111    ///
1112    ///
1113    /// .. versionadded:: 2.0.2$nbsp;(Firmware)
1114    pub async fn orientation_calculation_off(&mut self) -> Result<(), TinkerforgeError> {
1115        let payload = [0; 0];
1116
1117        #[allow(unused_variables)]
1118        let result = self.device.set(u8::from(ImuBrickFunction::OrientationCalculationOff), &payload).await?;
1119        Ok(())
1120    }
1121
1122    /// Returns *true* if the orientation calculation of the IMU Brick
1123    /// is on, *false* otherwise.
1124    ///
1125    ///
1126    /// .. versionadded:: 2.0.2$nbsp;(Firmware)
1127    pub async fn is_orientation_calculation_on(&mut self) -> Result<bool, TinkerforgeError> {
1128        let payload = [0; 0];
1129
1130        #[allow(unused_variables)]
1131        let result = self.device.get(u8::from(ImuBrickFunction::IsOrientationCalculationOn), &payload).await?;
1132        Ok(bool::from_le_byte_slice(result.body()))
1133    }
1134
1135    /// The SPITF protocol can be used with a dynamic baudrate. If the dynamic baudrate is
1136    /// enabled, the Brick will try to adapt the baudrate for the communication
1137    /// between Bricks and Bricklets according to the amount of data that is transferred.
1138    ///
1139    /// The baudrate will be increased exponentially if lots of data is sent/received and
1140    /// decreased linearly if little data is sent/received.
1141    ///
1142    /// This lowers the baudrate in applications where little data is transferred (e.g.
1143    /// a weather station) and increases the robustness. If there is lots of data to transfer
1144    /// (e.g. Thermal Imaging Bricklet) it automatically increases the baudrate as needed.
1145    ///
1146    /// In cases where some data has to transferred as fast as possible every few seconds
1147    /// (e.g. RS485 Bricklet with a high baudrate but small payload) you may want to turn
1148    /// the dynamic baudrate off to get the highest possible performance.
1149    ///
1150    /// The maximum value of the baudrate can be set per port with the function
1151    /// [`set_spitfp_baudrate`]. If the dynamic baudrate is disabled, the baudrate
1152    /// as set by [`set_spitfp_baudrate`] will be used statically.
1153    ///
1154    ///
1155    /// .. versionadded:: 2.3.5$nbsp;(Firmware)
1156    pub async fn set_spitfp_baudrate_config(
1157        &mut self,
1158        enable_dynamic_baudrate: bool,
1159        minimum_dynamic_baudrate: u32,
1160    ) -> Result<(), TinkerforgeError> {
1161        let mut payload = [0; 5];
1162        enable_dynamic_baudrate.write_to_slice(&mut payload[0..1]);
1163        minimum_dynamic_baudrate.write_to_slice(&mut payload[1..5]);
1164
1165        #[allow(unused_variables)]
1166        let result = self.device.set(u8::from(ImuBrickFunction::SetSpitfpBaudrateConfig), &payload).await?;
1167        Ok(())
1168    }
1169
1170    /// Returns the baudrate config, see [`set_spitfp_baudrate_config`].
1171    ///
1172    ///
1173    /// .. versionadded:: 2.3.5$nbsp;(Firmware)
1174    pub async fn get_spitfp_baudrate_config(&mut self) -> Result<SpitfpBaudrateConfig, TinkerforgeError> {
1175        let payload = [0; 0];
1176
1177        #[allow(unused_variables)]
1178        let result = self.device.get(u8::from(ImuBrickFunction::GetSpitfpBaudrateConfig), &payload).await?;
1179        Ok(SpitfpBaudrateConfig::from_le_byte_slice(result.body()))
1180    }
1181
1182    /// Returns the timeout count for the different communication methods.
1183    ///
1184    /// The methods 0-2 are available for all Bricks, 3-7 only for Master Bricks.
1185    ///
1186    /// This function is mostly used for debugging during development, in normal operation
1187    /// the counters should nearly always stay at 0.
1188    ///
1189    ///
1190    /// .. versionadded:: 2.3.3$nbsp;(Firmware)
1191    ///
1192    /// Associated constants:
1193    /// * IMU_BRICK_COMMUNICATION_METHOD_NONE
1194    ///	* IMU_BRICK_COMMUNICATION_METHOD_USB
1195    ///	* IMU_BRICK_COMMUNICATION_METHOD_SPI_STACK
1196    ///	* IMU_BRICK_COMMUNICATION_METHOD_CHIBI
1197    ///	* IMU_BRICK_COMMUNICATION_METHOD_RS485
1198    ///	* IMU_BRICK_COMMUNICATION_METHOD_WIFI
1199    ///	* IMU_BRICK_COMMUNICATION_METHOD_ETHERNET
1200    ///	* IMU_BRICK_COMMUNICATION_METHOD_WIFI_V2
1201    pub async fn get_send_timeout_count(&mut self, communication_method: u8) -> Result<u32, TinkerforgeError> {
1202        let mut payload = [0; 1];
1203        communication_method.write_to_slice(&mut payload[0..1]);
1204
1205        #[allow(unused_variables)]
1206        let result = self.device.get(u8::from(ImuBrickFunction::GetSendTimeoutCount), &payload).await?;
1207        Ok(u32::from_le_byte_slice(result.body()))
1208    }
1209
1210    /// Sets the baudrate for a specific Bricklet port.
1211    ///
1212    /// If you want to increase the throughput of Bricklets you can increase
1213    /// the baudrate. If you get a high error count because of high
1214    /// interference (see [`get_spitfp_error_count`]) you can decrease the
1215    /// baudrate.
1216    ///
1217    /// If the dynamic baudrate feature is enabled, the baudrate set by this
1218    /// function corresponds to the maximum baudrate (see [`set_spitfp_baudrate_config`]).
1219    ///
1220    /// Regulatory testing is done with the default baudrate. If CE compatibility
1221    /// or similar is necessary in your applications we recommend to not change
1222    /// the baudrate.
1223    ///
1224    ///
1225    /// .. versionadded:: 2.3.3$nbsp;(Firmware)
1226    pub async fn set_spitfp_baudrate(&mut self, bricklet_port: char, baudrate: u32) -> Result<(), TinkerforgeError> {
1227        let mut payload = [0; 5];
1228        bricklet_port.write_to_slice(&mut payload[0..1]);
1229        baudrate.write_to_slice(&mut payload[1..5]);
1230
1231        #[allow(unused_variables)]
1232        let result = self.device.set(u8::from(ImuBrickFunction::SetSpitfpBaudrate), &payload).await?;
1233        Ok(())
1234    }
1235
1236    /// Returns the baudrate for a given Bricklet port, see [`set_spitfp_baudrate`].
1237    ///
1238    ///
1239    /// .. versionadded:: 2.3.3$nbsp;(Firmware)
1240    pub async fn get_spitfp_baudrate(&mut self, bricklet_port: char) -> Result<u32, TinkerforgeError> {
1241        let mut payload = [0; 1];
1242        bricklet_port.write_to_slice(&mut payload[0..1]);
1243
1244        #[allow(unused_variables)]
1245        let result = self.device.get(u8::from(ImuBrickFunction::GetSpitfpBaudrate), &payload).await?;
1246        Ok(u32::from_le_byte_slice(result.body()))
1247    }
1248
1249    /// Returns the error count for the communication between Brick and Bricklet.
1250    ///
1251    /// The errors are divided into
1252    ///
1253    /// * ACK checksum errors,
1254    /// * message checksum errors,
1255    /// * framing errors and
1256    /// * overflow errors.
1257    ///
1258    /// The errors counts are for errors that occur on the Brick side. All
1259    /// Bricklets have a similar function that returns the errors on the Bricklet side.
1260    ///
1261    ///
1262    /// .. versionadded:: 2.3.3$nbsp;(Firmware)
1263    pub async fn get_spitfp_error_count(&mut self, bricklet_port: char) -> Result<SpitfpErrorCount, TinkerforgeError> {
1264        let mut payload = [0; 1];
1265        bricklet_port.write_to_slice(&mut payload[0..1]);
1266
1267        #[allow(unused_variables)]
1268        let result = self.device.get(u8::from(ImuBrickFunction::GetSpitfpErrorCount), &payload).await?;
1269        Ok(SpitfpErrorCount::from_le_byte_slice(result.body()))
1270    }
1271
1272    /// Enables the status LED.
1273    ///
1274    /// The status LED is the blue LED next to the USB connector. If enabled is is
1275    /// on and it flickers if data is transfered. If disabled it is always off.
1276    ///
1277    /// The default state is enabled.
1278    ///
1279    ///
1280    /// .. versionadded:: 2.3.1$nbsp;(Firmware)
1281    pub async fn enable_status_led(&mut self) -> Result<(), TinkerforgeError> {
1282        let payload = [0; 0];
1283
1284        #[allow(unused_variables)]
1285        let result = self.device.set(u8::from(ImuBrickFunction::EnableStatusLed), &payload).await?;
1286        Ok(())
1287    }
1288
1289    /// Disables the status LED.
1290    ///
1291    /// The status LED is the blue LED next to the USB connector. If enabled is is
1292    /// on and it flickers if data is transfered. If disabled it is always off.
1293    ///
1294    /// The default state is enabled.
1295    ///
1296    ///
1297    /// .. versionadded:: 2.3.1$nbsp;(Firmware)
1298    pub async fn disable_status_led(&mut self) -> Result<(), TinkerforgeError> {
1299        let payload = [0; 0];
1300
1301        #[allow(unused_variables)]
1302        let result = self.device.set(u8::from(ImuBrickFunction::DisableStatusLed), &payload).await?;
1303        Ok(())
1304    }
1305
1306    /// Returns *true* if the status LED is enabled, *false* otherwise.
1307    ///
1308    ///
1309    /// .. versionadded:: 2.3.1$nbsp;(Firmware)
1310    pub async fn is_status_led_enabled(&mut self) -> Result<bool, TinkerforgeError> {
1311        let payload = [0; 0];
1312
1313        #[allow(unused_variables)]
1314        let result = self.device.get(u8::from(ImuBrickFunction::IsStatusLedEnabled), &payload).await?;
1315        Ok(bool::from_le_byte_slice(result.body()))
1316    }
1317
1318    /// Returns the firmware and protocol version and the name of the Bricklet for a
1319    /// given port.
1320    ///
1321    /// This functions sole purpose is to allow automatic flashing of v1.x.y Bricklet
1322    /// plugins.
1323    pub async fn get_protocol1_bricklet_name(&mut self, port: char) -> Result<Protocol1BrickletName, TinkerforgeError> {
1324        let mut payload = [0; 1];
1325        port.write_to_slice(&mut payload[0..1]);
1326
1327        #[allow(unused_variables)]
1328        let result = self.device.get(u8::from(ImuBrickFunction::GetProtocol1BrickletName), &payload).await?;
1329        Ok(Protocol1BrickletName::from_le_byte_slice(result.body()))
1330    }
1331
1332    /// Returns the temperature as measured inside the microcontroller. The
1333    /// value returned is not the ambient temperature!
1334    ///
1335    /// The temperature is only proportional to the real temperature and it has an
1336    /// accuracy of ±15%. Practically it is only useful as an indicator for
1337    /// temperature changes.
1338    pub async fn get_chip_temperature(&mut self) -> Result<i16, TinkerforgeError> {
1339        let payload = [0; 0];
1340
1341        #[allow(unused_variables)]
1342        let result = self.device.get(u8::from(ImuBrickFunction::GetChipTemperature), &payload).await?;
1343        Ok(i16::from_le_byte_slice(result.body()))
1344    }
1345
1346    /// Calling this function will reset the Brick. Calling this function
1347    /// on a Brick inside of a stack will reset the whole stack.
1348    ///
1349    /// After a reset you have to create new device objects,
1350    /// calling functions on the existing ones will result in
1351    /// undefined behavior!
1352    pub async fn reset(&mut self) -> Result<(), TinkerforgeError> {
1353        let payload = [0; 0];
1354
1355        #[allow(unused_variables)]
1356        let result = self.device.set(u8::from(ImuBrickFunction::Reset), &payload).await?;
1357        Ok(())
1358    }
1359
1360    /// Writes 32 bytes of firmware to the bricklet attached at the given port.
1361    /// The bytes are written to the position offset * 32.
1362    ///
1363    /// This function is used by Brick Viewer during flashing. It should not be
1364    /// necessary to call it in a normal user program.
1365    pub async fn write_bricklet_plugin(&mut self, port: char, offset: u8, chunk: &[u8; 32]) -> Result<(), TinkerforgeError> {
1366        let mut payload = [0; 34];
1367        port.write_to_slice(&mut payload[0..1]);
1368        offset.write_to_slice(&mut payload[1..2]);
1369        chunk.write_to_slice(&mut payload[2..34]);
1370
1371        #[allow(unused_variables)]
1372        let result = self.device.set(u8::from(ImuBrickFunction::WriteBrickletPlugin), &payload).await?;
1373        Ok(())
1374    }
1375
1376    /// Reads 32 bytes of firmware from the bricklet attached at the given port.
1377    /// The bytes are read starting at the position offset * 32.
1378    ///
1379    /// This function is used by Brick Viewer during flashing. It should not be
1380    /// necessary to call it in a normal user program.
1381    pub async fn read_bricklet_plugin(&mut self, port: char, offset: u8) -> Result<Box<[u8; 32]>, TinkerforgeError> {
1382        let mut payload = [0; 2];
1383        port.write_to_slice(&mut payload[0..1]);
1384        offset.write_to_slice(&mut payload[1..2]);
1385
1386        #[allow(unused_variables)]
1387        let result = self.device.get(u8::from(ImuBrickFunction::ReadBrickletPlugin), &payload).await?;
1388        Ok(Box::<[u8; 32]>::from_le_byte_slice(result.body()))
1389    }
1390
1391    /// Returns the UID, the UID where the Brick is connected to,
1392    /// the position, the hardware and firmware version as well as the
1393    /// device identifier.
1394    ///
1395    /// The position is the position in the stack from '0' (bottom) to '8' (top).
1396    ///
1397    /// The device identifier numbers can be found [here](device_identifier).
1398    /// |device_identifier_constant|
1399    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
1400        let payload = [0; 0];
1401
1402        #[allow(unused_variables)]
1403        let result = self.device.get(u8::from(ImuBrickFunction::GetIdentity), &payload).await?;
1404        Ok(Identity::from_le_byte_slice(result.body()))
1405    }
1406}