Prechádzať zdrojové kódy

:recycle: extracted temperature sensor handling into own structure

Felix Bytow 2 mesiacov pred
rodič
commit
00eae0d9ad
2 zmenil súbory, kde vykonal 73 pridanie a 26 odobranie
  1. 9 26
      src/main.rs
  2. 64 0
      src/temperature.rs

+ 9 - 26
src/main.rs

@@ -3,15 +3,17 @@
 
 pub mod button;
 pub mod buzzer;
+pub mod temperature;
 
 use crate::button::Button;
 use crate::buzzer::Buzzer;
+use crate::temperature::TemperatureSensor;
 use embassy_executor::Spawner;
-use embassy_futures::select::{Either3, select3};
+use embassy_futures::select::{select3, Either3};
+use embassy_rp::bind_interrupts;
 use embassy_rp::gpio::Pull;
-use embassy_rp::i2c::{Async, Config, I2c, InterruptHandler};
+use embassy_rp::i2c::{Config, I2c, InterruptHandler};
 use embassy_rp::peripherals::I2C1;
-use embassy_rp::{bind_interrupts, i2c};
 use {defmt_rtt as _, panic_probe as _};
 
 struct SideButtons<'a> {
@@ -24,23 +26,6 @@ bind_interrupts!(struct Irqs {
     I2C1_IRQ => InterruptHandler<I2C1>;
 });
 
-async fn get_temperature<'a>(i2c: &mut I2c<'a, I2C1, Async>) -> Result<(u8, u8), i2c::Error> {
-    let address = 0x68u16;
-    let begin_transaction = [0x0Eu8, 0x20u8];
-    let get_temp_high = [0x11u8];
-    let get_temp_low = [0x12u8];
-
-    let mut buffer: [u8; 1] = [0];
-    i2c.write_async(address, begin_transaction).await?;
-    i2c.write_async(address, get_temp_high).await?;
-    i2c.read_async(address, buffer.as_mut_slice()).await?;
-    let temp_high = buffer[0];
-    i2c.write_async(address, get_temp_low).await?;
-    i2c.read_async(address, buffer.as_mut_slice()).await?;
-    let temp_low = (buffer[0] >> 6) * 25; // truncate to 2 digits
-    Ok((temp_high, temp_low))
-}
-
 #[embassy_executor::main]
 async fn main(_spawner: Spawner) -> ! {
     let peripherals = embassy_rp::init(Default::default());
@@ -51,18 +36,16 @@ async fn main(_spawner: Spawner) -> ! {
         up: Button::new(peripherals.PIN_17, Pull::Up),
         down: Button::new(peripherals.PIN_15, Pull::Up),
     };
-    let mut i2c = I2c::new_async(
+    let i2c = I2c::new_async(
         peripherals.I2C1,
         peripherals.PIN_7,
         peripherals.PIN_6,
         Irqs,
         Config::default(),
     );
-    if let Ok((temp_high, temp_low)) = get_temperature(&mut i2c).await {
-        defmt::info!("Temperature: {}.{}°C", temp_high, temp_low);
-    } else {
-        defmt::warn!("Could not read temperature!");
-    }
+    let mut temp_sensor = TemperatureSensor::new(i2c);
+    let _ = temp_sensor.update_async().await;
+    defmt::info!("Temperature: {}", temp_sensor.get_value());
 
     loop {
         defmt::info!("Set-Function: {}", side_buttons.set_function.get_level());

+ 64 - 0
src/temperature.rs

@@ -0,0 +1,64 @@
+use defmt::{Format, Formatter, write};
+use embassy_rp::i2c::{Async, Error, I2c, Instance, Mode};
+
+const I2C_ADDRESS: u16 = 0x0068;
+
+#[derive(Clone, Copy, Eq, PartialEq)]
+pub enum Temperature {
+    Unknown,
+    Celsius { high: u8, low: u8 },
+}
+
+impl Format for Temperature {
+    fn format(&self, fmt: Formatter) {
+        match *self {
+            Temperature::Unknown => write!(fmt, "Unknown temperature"),
+            Temperature::Celsius { high, low } => {
+                write!(fmt, "{}.{}°C", high, low)
+            }
+        }
+    }
+}
+
+pub struct TemperatureSensor<'a, T: Instance, M: Mode> {
+    i2c: I2c<'a, T, M>,
+    value: Temperature,
+}
+
+impl<'a, T: Instance, M: Mode> TemperatureSensor<'a, T, M> {
+    pub fn new(i2c: I2c<'a, T, M>) -> Self {
+        TemperatureSensor {
+            i2c,
+            value: Temperature::Unknown,
+        }
+    }
+
+    pub fn get_value(&self) -> Temperature {
+        self.value
+    }
+}
+
+impl<'a, T: Instance> TemperatureSensor<'a, T, Async> {
+    pub async fn update_async(&mut self) -> Result<(), Error> {
+        let begin_transaction = [0x0Eu8, 0x20u8];
+        let get_temp_high = [0x11u8];
+        let get_temp_low = [0x12u8];
+        let mut buffer: [u8; 1] = [0];
+        self.i2c.write_async(I2C_ADDRESS, begin_transaction).await?;
+        self.i2c.write_async(I2C_ADDRESS, get_temp_high).await?;
+        self.i2c
+            .read_async(I2C_ADDRESS, buffer.as_mut_slice())
+            .await?;
+        let temp_high = buffer[0];
+        self.i2c.write_async(I2C_ADDRESS, get_temp_low).await?;
+        self.i2c
+            .read_async(I2C_ADDRESS, buffer.as_mut_slice())
+            .await?;
+        let temp_low = (buffer[0] >> 6) * 25; // truncate to 2 digits
+        self.value = Temperature::Celsius {
+            high: temp_high,
+            low: temp_low,
+        };
+        Ok(())
+    }
+}