Skip to main content

m5stack_core/io/
ow_temp.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2use embassy_time::{Duration, Ticker};
3use esp_hal::{gpio::AnyPin, peripherals::RMT};
4
5use crate::driver::ds18b20::{Ds18b20Driver, Error};
6
7pub struct OnewireResources<'a> {
8    pub rmt: RMT<'a>,
9    pub pin: AnyPin<'a>,
10}
11
12impl OnewireResources<'static> {
13    pub fn into_driver(self) -> Result<Ds18b20Driver, Error> {
14        Ds18b20Driver::new(self.rmt, self.pin)
15    }
16}
17
18const TEMP_LOOP_TIME_MS: u64 = 3000;
19
20/// 3s ticker, reads all sensors, calls on_temperatures with slice of (address, temp).
21pub async fn ow_loop(resources: OnewireResources<'static>, on_temperatures: fn(&[(u64, f32)])) {
22    let Ok(mut ow) = resources.into_driver() else {
23        error!("failed to init OneWire bus - pull-up resistor present?");
24        return;
25    };
26
27    let mut ticker = Ticker::every(Duration::from_millis(TEMP_LOOP_TIME_MS));
28    loop {
29        debug!("reading temperatures");
30        let Ok(temperatures) = ow.read_all_temperatures().await else {
31            error!("Error while accessing OneWire bus, terminating task");
32            return;
33        };
34
35        let mut buf: heapless::Vec<(u64, f32), 2> = heapless::Vec::new();
36        for (addr, temp) in temperatures {
37            debug!("temperature of {}C from sensor 0x{:x}", temp, addr.0);
38            if buf.push((addr.0, temp)).is_err() {
39                warn!("more than 2 sensors, ignoring extras");
40                break;
41            }
42        }
43        on_temperatures(buf.as_slice());
44        ticker.next().await;
45    }
46}