vexide_devices/adi/
light_sensor.rs

1//! ADI Light Sensor
2//!
3//! The Light Sensor measures the intensity of visible light with a photoresistor.
4//!
5//! # Hardware Overview
6//!
7//! Using a Cadmium Sulfoselenide photoconductive photocell (CdS), the light sensor
8//! is able to adjust its resistance based on the amount of visible light shining on it.
9//!
10//! The light sensor only measures light in the visible spectrum. It cannot detect
11//! infrared or ultraviolet sources.
12//!
13//! # Effective Range
14//!
15//! Effective range is dependent on both the intensity of the source and the surrounding
16//! environment. Darker ambient surroundings with a brighter source will result in a
17//! greater effective range.
18//!
19//! That being said, the sensor generally has a usable range of up to 6 feet, meaning it
20//! can distinguish a light source from the surrounding ambient light at up to six feet
21//! away. Measurements farther than this might cause the sensor to return inconclusive
22//! results or blend into the ambient light.
23
24use vex_sdk::vexDeviceAdiValueGet;
25
26use super::{analog, AdiDevice, AdiDeviceType, AdiPort, PortError};
27
28/// Light Sensor
29#[derive(Debug, Eq, PartialEq)]
30pub struct AdiLightSensor {
31    port: AdiPort,
32}
33
34impl AdiLightSensor {
35    /// Create a light sensor on the given [`AdiPort`].
36    ///
37    /// # Examples
38    ///
39    /// ```
40    /// use vexide::prelude::*;
41    ///
42    /// #[vexide::main]
43    /// async fn main(peripherals: Peripherals) {
44    ///     // Create a new light sensor on port 1
45    ///     let sensor = AdiLightSensor::new(peripherals.port_1);
46    ///
47    ///     // Get the brightness value
48    ///     println!("Brightness value: {:?}", sensor.brightness());
49    /// }
50    /// ```
51    #[must_use]
52    pub fn new(port: AdiPort) -> Self {
53        port.configure(AdiDeviceType::LightSensor);
54
55        Self { port }
56    }
57
58    /// Returns the brightness factor measured by the sensor. Higher numbers mean
59    /// a brighter light source.
60    ///
61    /// This is returned as a value in the interval [0.0, 1.0].
62    ///
63    /// # Errors
64    ///
65    /// - A [`PortError::Disconnected`] error is returned if an ADI expander device was required but not connected.
66    /// - A [`PortError::IncorrectDevice`] error is returned if an ADI expander device was required but
67    ///   something else was connected.
68    ///
69    /// # Examples
70    ///
71    /// ```
72    /// use vexide::prelude::*;
73    ///
74    /// #[vexide::main]
75    /// async fn main(peripherals: Peripherals) {
76    ///     // Create a new light sensor on port 1
77    ///     let sensor = AdiLightSensor::new(peripherals.port_1);
78    ///
79    ///     // Get the brightness value
80    ///     println!("Brightness value: {:?}", sensor.brightness());
81    /// }
82    /// ```
83    pub fn brightness(&self) -> Result<f64, PortError> {
84        Ok(f64::from(analog::ADC_MAX_VALUE - self.raw_brightness()?)
85            / f64::from(analog::ADC_MAX_VALUE))
86    }
87
88    /// Returns the 12-bit brightness reading of the sensor.
89    ///
90    /// This is a raw 12-bit value in the interval [0, 4095] representing the voltage level from
91    /// 0-5V measured by the V5 Brain's ADC.
92    ///
93    /// A low number (less voltage) represents a **brighter** light source.
94    ///
95    /// # Errors
96    ///
97    /// - A [`PortError::Disconnected`] error is returned if an ADI expander device was required but not connected.
98    /// - A [`PortError::IncorrectDevice`] error is returned if an ADI expander device was required but
99    ///   something else was connected.
100    ///
101    /// # Examples
102    ///
103    /// ```
104    /// use vexide::prelude::*;
105    ///
106    /// #[vexide::main]
107    /// async fn main(peripherals: Peripherals) {
108    ///     // Create a new light sensor on port 1
109    ///     let sensor = AdiLightSensor::new(peripherals.port_1);
110    ///
111    ///     // Get the brightness value
112    ///     println!("Raw 12-bit brightness value: {:?}", sensor.raw_brightness());
113    /// }
114    /// ```
115    pub fn raw_brightness(&self) -> Result<u16, PortError> {
116        self.port.validate_expander()?;
117
118        Ok(unsafe { vexDeviceAdiValueGet(self.port.device_handle(), self.port.index()) } as u16)
119    }
120}
121
122impl AdiDevice<1> for AdiLightSensor {
123    fn port_numbers(&self) -> [u8; 1] {
124        [self.port.number()]
125    }
126
127    fn expander_port_number(&self) -> Option<u8> {
128        self.port.expander_number()
129    }
130
131    fn device_type(&self) -> AdiDeviceType {
132        AdiDeviceType::LightSensor
133    }
134}