Skip to main content

automation_hat/
digital_input.rs

1//! Digital input control for Automation HAT boards.
2//!
3//! This module provides control for the digital input pins on Automation HAT boards.
4//! Digital inputs can read 5V signals and have indicator LEDs to show their current state.
5
6use crate::lights::LED;
7
8use embedded_hal::digital::InputPin;
9use linux_embedded_hal::{
10    CdevPin,
11    gpio_cdev::{Line, LineRequestFlags},
12};
13
14/// Controls a digital input on the Automation HAT.
15///
16/// Digital inputs can read 5V signals from external devices. When a 5V signal
17/// is detected, the input reads as high (true). Each input can have an associated
18/// LED that automatically indicates the input state.
19pub struct DigitalInput {
20    /// GPIO pin for the digital input
21    pin: CdevPin,
22    /// Optional LED indicator for this input
23    led: Option<LED>,
24    /// Whether the LED should automatically reflect input state
25    _auto_light: bool,
26}
27
28impl DigitalInput {
29    /// Creates a new digital input with automatic LED indication enabled.
30    ///
31    /// # Arguments
32    ///
33    /// * `line` - GPIO line connected to the digital input
34    /// * `led` - Optional LED indicator for this input
35    ///
36    /// # Returns
37    ///
38    /// A new `DigitalInput` instance with automatic LED indication enabled
39    pub fn new(line: Line, led: Option<LED>) -> Self {
40        let line = line
41            .request(LineRequestFlags::INPUT, 0, "AutomationHAT Rust SDK")
42            .unwrap();
43        let pin = CdevPin::new(line).unwrap();
44        DigitalInput {
45            pin,
46            led,
47            _auto_light: true,
48        }
49    }
50
51    /// Creates a new digital input with configurable LED indication.
52    ///
53    /// # Arguments
54    ///
55    /// * `line` - GPIO line connected to the digital input
56    /// * `led` - Optional LED indicator for this input
57    /// * `auto_light` - Whether the LED should automatically reflect the input state
58    ///
59    /// # Returns
60    ///
61    /// A new `DigitalInput` instance with the specified LED behavior
62    pub fn new_with_auto_light(line: Line, led: Option<LED>, auto_light: bool) -> Self {
63        let line = line
64            .request(LineRequestFlags::INPUT, 0, "AutomationHAT Rust SDK")
65            .unwrap();
66        let pin = CdevPin::new(line).unwrap();
67        DigitalInput {
68            pin,
69            led,
70            _auto_light: auto_light,
71        }
72    }
73
74    /// Reads the current state of the digital input.
75    ///
76    /// When auto_light is enabled and an LED is attached, this method will
77    /// also update the LED to reflect the current input state.
78    ///
79    /// # Returns
80    ///
81    /// * `Ok(true)` - If the input is high (5V signal detected)
82    /// * `Ok(false)` - If the input is low (no signal)
83    /// * `Err(String)` - If reading the input failed
84    pub fn read(&mut self) -> Result<bool, String> {
85        let value = self.pin.is_high().map_err(|e| e.to_string())?;
86        if self._auto_light && self.led.is_some() {
87            if let Err(e) = self.led.as_mut().unwrap().set_brightness(match value {
88                true => 1.0,
89                false => 0.0,
90            }) {
91                println!("Failed to update LED: {}", e);
92            }
93        }
94        Ok(value)
95    }
96}