tinkerforge_async/bindings/
lcd_16x2_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//! 16x2 character alphanumeric display with blue backlight.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/LCD16x2_Bricklet_Rust.html).
14#[allow(unused_imports)]
15use crate::{
16    base58::Uid, byte_converter::*, converting_receiver::BrickletError, device::*, error::TinkerforgeError,
17    ip_connection::async_io::AsyncIpConnection, low_level_traits::LowLevelRead,
18};
19#[allow(unused_imports)]
20use futures_core::Stream;
21#[allow(unused_imports)]
22use tokio_stream::StreamExt;
23pub enum Lcd16x2BrickletFunction {
24    WriteLine,
25    ClearDisplay,
26    BacklightOn,
27    BacklightOff,
28    IsBacklightOn,
29    SetConfig,
30    GetConfig,
31    IsButtonPressed,
32    SetCustomCharacter,
33    GetCustomCharacter,
34    GetIdentity,
35    CallbackButtonPressed,
36    CallbackButtonReleased,
37}
38impl From<Lcd16x2BrickletFunction> for u8 {
39    fn from(fun: Lcd16x2BrickletFunction) -> Self {
40        match fun {
41            Lcd16x2BrickletFunction::WriteLine => 1,
42            Lcd16x2BrickletFunction::ClearDisplay => 2,
43            Lcd16x2BrickletFunction::BacklightOn => 3,
44            Lcd16x2BrickletFunction::BacklightOff => 4,
45            Lcd16x2BrickletFunction::IsBacklightOn => 5,
46            Lcd16x2BrickletFunction::SetConfig => 6,
47            Lcd16x2BrickletFunction::GetConfig => 7,
48            Lcd16x2BrickletFunction::IsButtonPressed => 8,
49            Lcd16x2BrickletFunction::SetCustomCharacter => 11,
50            Lcd16x2BrickletFunction::GetCustomCharacter => 12,
51            Lcd16x2BrickletFunction::GetIdentity => 255,
52            Lcd16x2BrickletFunction::CallbackButtonPressed => 9,
53            Lcd16x2BrickletFunction::CallbackButtonReleased => 10,
54        }
55    }
56}
57
58#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
59pub struct Config {
60    pub cursor: bool,
61    pub blinking: bool,
62}
63impl FromByteSlice for Config {
64    fn bytes_expected() -> usize {
65        2
66    }
67    fn from_le_byte_slice(bytes: &[u8]) -> Config {
68        Config { cursor: <bool>::from_le_byte_slice(&bytes[0..1]), blinking: <bool>::from_le_byte_slice(&bytes[1..2]) }
69    }
70}
71
72#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
73pub struct Identity {
74    pub uid: String,
75    pub connected_uid: String,
76    pub position: char,
77    pub hardware_version: [u8; 3],
78    pub firmware_version: [u8; 3],
79    pub device_identifier: u16,
80}
81impl FromByteSlice for Identity {
82    fn bytes_expected() -> usize {
83        25
84    }
85    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
86        Identity {
87            uid: <String>::from_le_byte_slice(&bytes[0..8]),
88            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
89            position: <char>::from_le_byte_slice(&bytes[16..17]),
90            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
91            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
92            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
93        }
94    }
95}
96
97/// 16x2 character alphanumeric display with blue backlight
98#[derive(Clone)]
99pub struct Lcd16x2Bricklet {
100    device: Device,
101}
102impl Lcd16x2Bricklet {
103    pub const DEVICE_IDENTIFIER: u16 = 211;
104    pub const DEVICE_DISPLAY_NAME: &'static str = "LCD 16x2 Bricklet";
105    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
106    pub fn new(uid: Uid, connection: AsyncIpConnection) -> Lcd16x2Bricklet {
107        let mut result = Lcd16x2Bricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
108        result.device.response_expected[u8::from(Lcd16x2BrickletFunction::WriteLine) as usize] = ResponseExpectedFlag::False;
109        result.device.response_expected[u8::from(Lcd16x2BrickletFunction::ClearDisplay) as usize] = ResponseExpectedFlag::False;
110        result.device.response_expected[u8::from(Lcd16x2BrickletFunction::BacklightOn) as usize] = ResponseExpectedFlag::False;
111        result.device.response_expected[u8::from(Lcd16x2BrickletFunction::BacklightOff) as usize] = ResponseExpectedFlag::False;
112        result.device.response_expected[u8::from(Lcd16x2BrickletFunction::IsBacklightOn) as usize] = ResponseExpectedFlag::AlwaysTrue;
113        result.device.response_expected[u8::from(Lcd16x2BrickletFunction::SetConfig) as usize] = ResponseExpectedFlag::False;
114        result.device.response_expected[u8::from(Lcd16x2BrickletFunction::GetConfig) as usize] = ResponseExpectedFlag::AlwaysTrue;
115        result.device.response_expected[u8::from(Lcd16x2BrickletFunction::IsButtonPressed) as usize] = ResponseExpectedFlag::AlwaysTrue;
116        result.device.response_expected[u8::from(Lcd16x2BrickletFunction::SetCustomCharacter) as usize] = ResponseExpectedFlag::False;
117        result.device.response_expected[u8::from(Lcd16x2BrickletFunction::GetCustomCharacter) as usize] = ResponseExpectedFlag::AlwaysTrue;
118        result.device.response_expected[u8::from(Lcd16x2BrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
119        result
120    }
121
122    /// Returns the response expected flag for the function specified by the function ID parameter.
123    /// It is true if the function is expected to send a response, false otherwise.
124    ///
125    /// For getter functions this is enabled by default and cannot be disabled, because those
126    /// functions will always send a response. For callback configuration functions it is enabled
127    /// by default too, but can be disabled by [`set_response_expected`](crate::lcd_16x2_bricklet::Lcd16x2Bricklet::set_response_expected).
128    /// For setter functions it is disabled by default and can be enabled.
129    ///
130    /// Enabling the response expected flag for a setter function allows to detect timeouts
131    /// and other error conditions calls of this setter as well. The device will then send a response
132    /// for this purpose. If this flag is disabled for a setter function then no response is sent
133    /// and errors are silently ignored, because they cannot be detected.
134    ///
135    /// See [`set_response_expected`](crate::lcd_16x2_bricklet::Lcd16x2Bricklet::set_response_expected) for the list of function ID constants available for this function.
136    pub fn get_response_expected(&mut self, fun: Lcd16x2BrickletFunction) -> Result<bool, GetResponseExpectedError> {
137        self.device.get_response_expected(u8::from(fun))
138    }
139
140    /// Changes the response expected flag of the function specified by the function ID parameter.
141    /// This flag can only be changed for setter (default value: false) and callback configuration
142    /// functions (default value: true). For getter functions it is always enabled.
143    ///
144    /// Enabling the response expected flag for a setter function allows to detect timeouts and
145    /// other error conditions calls of this setter as well. The device will then send a response
146    /// for this purpose. If this flag is disabled for a setter function then no response is sent
147    /// and errors are silently ignored, because they cannot be detected.
148    pub fn set_response_expected(&mut self, fun: Lcd16x2BrickletFunction, response_expected: bool) -> Result<(), SetResponseExpectedError> {
149        self.device.set_response_expected(u8::from(fun), response_expected)
150    }
151
152    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
153    pub fn set_response_expected_all(&mut self, response_expected: bool) {
154        self.device.set_response_expected_all(response_expected)
155    }
156
157    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
158    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
159    pub fn get_api_version(&self) -> [u8; 3] {
160        self.device.api_version
161    }
162
163    /// This receiver is triggered when a button is pressed. The parameter is
164    /// the number of the button.
165    pub async fn get_button_pressed_callback_receiver(&mut self) -> impl Stream<Item = u8> {
166        self.device
167            .get_callback_receiver(u8::from(Lcd16x2BrickletFunction::CallbackButtonPressed))
168            .await
169            .map(|p| u8::from_le_byte_slice(p.body()))
170    }
171
172    /// This receiver is triggered when a button is released. The parameter is
173    /// the number of the button.
174    pub async fn get_button_released_callback_receiver(&mut self) -> impl Stream<Item = u8> {
175        self.device
176            .get_callback_receiver(u8::from(Lcd16x2BrickletFunction::CallbackButtonReleased))
177            .await
178            .map(|p| u8::from_le_byte_slice(p.body()))
179    }
180
181    /// Writes text to a specific line with a specific position.
182    /// The text can have a maximum of 16 characters.
183    ///
184    /// For example: (0, 5, Hello) will write *Hello* in the middle of the
185    /// first line of the display.
186    ///
187    /// The display uses a special charset that includes all ASCII characters except
188    /// backslash and tilde. The LCD charset also includes several other non-ASCII characters, see
189    /// the [charset specification](https://github.com/Tinkerforge/lcd-16x2-bricklet/raw/master/datasheets/standard_charset.pdf)__
190    /// for details. The Unicode example above shows how to specify non-ASCII characters
191    /// and how to translate from Unicode to the LCD charset.
192    pub async fn write_line(&mut self, line: u8, position: u8, text: String) -> Result<(), TinkerforgeError> {
193        let mut payload = [0; 18];
194        line.write_to_slice(&mut payload[0..1]);
195        position.write_to_slice(&mut payload[1..2]);
196        text.try_write_to_slice(16, &mut payload)?;
197
198        #[allow(unused_variables)]
199        let result = self.device.set(u8::from(Lcd16x2BrickletFunction::WriteLine), &payload).await?;
200        Ok(())
201    }
202
203    /// Deletes all characters from the display.
204    pub async fn clear_display(&mut self) -> Result<(), TinkerforgeError> {
205        let payload = [0; 0];
206
207        #[allow(unused_variables)]
208        let result = self.device.set(u8::from(Lcd16x2BrickletFunction::ClearDisplay), &payload).await?;
209        Ok(())
210    }
211
212    /// Turns the backlight on.
213    pub async fn backlight_on(&mut self) -> Result<(), TinkerforgeError> {
214        let payload = [0; 0];
215
216        #[allow(unused_variables)]
217        let result = self.device.set(u8::from(Lcd16x2BrickletFunction::BacklightOn), &payload).await?;
218        Ok(())
219    }
220
221    /// Turns the backlight off.
222    pub async fn backlight_off(&mut self) -> Result<(), TinkerforgeError> {
223        let payload = [0; 0];
224
225        #[allow(unused_variables)]
226        let result = self.device.set(u8::from(Lcd16x2BrickletFunction::BacklightOff), &payload).await?;
227        Ok(())
228    }
229
230    /// Returns *true* if the backlight is on and *false* otherwise.
231    pub async fn is_backlight_on(&mut self) -> Result<bool, TinkerforgeError> {
232        let payload = [0; 0];
233
234        #[allow(unused_variables)]
235        let result = self.device.get(u8::from(Lcd16x2BrickletFunction::IsBacklightOn), &payload).await?;
236        Ok(bool::from_le_byte_slice(result.body()))
237    }
238
239    /// Configures if the cursor (shown as _) should be visible and if it
240    /// should be blinking (shown as a blinking block). The cursor position
241    /// is one character behind the the last text written with
242    /// [`write_line`].
243    pub async fn set_config(&mut self, cursor: bool, blinking: bool) -> Result<(), TinkerforgeError> {
244        let mut payload = [0; 2];
245        cursor.write_to_slice(&mut payload[0..1]);
246        blinking.write_to_slice(&mut payload[1..2]);
247
248        #[allow(unused_variables)]
249        let result = self.device.set(u8::from(Lcd16x2BrickletFunction::SetConfig), &payload).await?;
250        Ok(())
251    }
252
253    /// Returns the configuration as set by [`set_config`].
254    pub async fn get_config(&mut self) -> Result<Config, TinkerforgeError> {
255        let payload = [0; 0];
256
257        #[allow(unused_variables)]
258        let result = self.device.get(u8::from(Lcd16x2BrickletFunction::GetConfig), &payload).await?;
259        Ok(Config::from_le_byte_slice(result.body()))
260    }
261
262    /// Returns *true* if the button is pressed.
263    ///
264    /// If you want to react on button presses and releases it is recommended to use the
265    /// [`get_button_pressed_callback_receiver`] and [`get_button_released_callback_receiver`] receivers.
266    pub async fn is_button_pressed(&mut self, button: u8) -> Result<bool, TinkerforgeError> {
267        let mut payload = [0; 1];
268        button.write_to_slice(&mut payload[0..1]);
269
270        #[allow(unused_variables)]
271        let result = self.device.get(u8::from(Lcd16x2BrickletFunction::IsButtonPressed), &payload).await?;
272        Ok(bool::from_le_byte_slice(result.body()))
273    }
274
275    /// The LCD 16x2 Bricklet can store up to 8 custom characters. The characters
276    /// consist of 5x8 pixels and can be addressed with the index 0-7. To describe
277    /// the pixels, the first 5 bits of 8 bytes are used. For example, to make
278    /// a custom character H, you should transfer the following:
279    ///
280    /// * ``character[0] = 0b00010001`` (decimal value 17)
281    /// * ``character[1] = 0b00010001`` (decimal value 17)
282    /// * ``character[2] = 0b00010001`` (decimal value 17)
283    /// * ``character[3] = 0b00011111`` (decimal value 31)
284    /// * ``character[4] = 0b00010001`` (decimal value 17)
285    /// * ``character[5] = 0b00010001`` (decimal value 17)
286    /// * ``character[6] = 0b00010001`` (decimal value 17)
287    /// * ``character[7] = 0b00000000`` (decimal value 0)
288    ///
289    /// The characters can later be written with [`write_line`] by using the
290    /// characters with the byte representation 8 (\\x08 or \\u0008) to 15
291    /// (\\x0F or \\u000F).
292    ///
293    /// You can play around with the custom characters in Brick Viewer since
294    /// version 2.0.1.
295    ///
296    /// Custom characters are stored by the LCD in RAM, so they have to be set
297    /// after each startup.
298    ///
299    ///
300    /// .. versionadded:: 2.0.1$nbsp;(Plugin)
301    pub async fn set_custom_character(&mut self, index: u8, character: &[u8; 8]) -> Result<(), TinkerforgeError> {
302        let mut payload = [0; 9];
303        index.write_to_slice(&mut payload[0..1]);
304        character.write_to_slice(&mut payload[1..9]);
305
306        #[allow(unused_variables)]
307        let result = self.device.set(u8::from(Lcd16x2BrickletFunction::SetCustomCharacter), &payload).await?;
308        Ok(())
309    }
310
311    /// Returns the custom character for a given index, as set with
312    /// [`set_custom_character`].
313    ///
314    ///
315    /// .. versionadded:: 2.0.1$nbsp;(Plugin)
316    pub async fn get_custom_character(&mut self, index: u8) -> Result<Box<[u8; 8]>, TinkerforgeError> {
317        let mut payload = [0; 1];
318        index.write_to_slice(&mut payload[0..1]);
319
320        #[allow(unused_variables)]
321        let result = self.device.get(u8::from(Lcd16x2BrickletFunction::GetCustomCharacter), &payload).await?;
322        Ok(Box::<[u8; 8]>::from_le_byte_slice(result.body()))
323    }
324
325    /// Returns the UID, the UID where the Bricklet is connected to,
326    /// the position, the hardware and firmware version as well as the
327    /// device identifier.
328    ///
329    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
330    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
331    /// position 'z'.
332    ///
333    /// The device identifier numbers can be found [here](device_identifier).
334    /// |device_identifier_constant|
335    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
336        let payload = [0; 0];
337
338        #[allow(unused_variables)]
339        let result = self.device.get(u8::from(Lcd16x2BrickletFunction::GetIdentity), &payload).await?;
340        Ok(Identity::from_le_byte_slice(result.body()))
341    }
342}