kellerkindt / onewire

OneWire bus implementation in Rust using embedded-hal
Apache License 2.0
35 stars 14 forks source link

Porting to avr-hal #15

Open fredfortier opened 2 years ago

fredfortier commented 2 years ago

I just want to read temperature from a DS18B20. If possible, I would prefer using avr-hal to interface with the board with this crate to interpret the readouts. Intuitively, I would start with this example: https://github.com/Rahix/avr-hal/blob/main/examples/arduino-uno/src/bin/uno-hc-sr04.rs and somehow port this section of your example:

let mut ds18b20 = DS18b20::new(device).unwrap();

// request sensor to measure temperature
let resolution = ds18b20.measure_temperature(&mut wire, &mut delay).unwrap();

// wait for compeltion, depends on resolution 
delay.delay_ms(resolution.time_ms());

// read temperature
let temperature = ds18b20.read_temperature(&mut wire, &mut delay).unwrap();

I assume the avr_hal and stm32f103xx_hal handle delay and reading from the pin similarly. If you think this isn't too complicated, I'd appreciate some pointers.

johnnynotsolucky commented 2 years ago

@fredfortier I have it working using avr-hal with

use arduino_hal::Delay;
use onewire::{Error as OneWireError, OneWire, DeviceSearch, ds18b20::{self, split_temp}, DS18B20};

let mut temp_sensor_pin = pins.d2.into_opendrain();
let mut onewire = OneWire::new(&mut temp_sensor_pin, false);
let mut delay = Delay::new();

if onewire.reset(&mut delay).is_err() {
    loop {
        // ..
    }
}

let mut search = DeviceSearch::new();

// I only have one sensor
let ds18b20: Option<DS18B20> = if let Some(device) = onewire.search_next(&mut search, &mut delay).unwrap() {
    match device.address[0] {
        ds18b20::FAMILY_CODE => {
            unsafe {
                // DS18B20::new() checks that the address[0] matches FAMILY_CODE, no need to
                // check it again.
                Some(DS18B20::new_forced(device))
            }
        },
        _ => {
            None
        },
    }
} else {
    None
};

match ds18b20 {
    Some(ds18b20) => {
        loop {
            // request sensor to measure temperature
            let resolution = ds18b20.measure_temperature(&mut onewire, &mut delay).unwrap();
            // wait for completion, depends on resolution
            arduino_hal::delay_ms(resolution.time_ms());
            // read temperature
            match ds18b20.read_temperature(&mut onewire, &mut delay) {
                Ok(measurement) => {
                    // (i16, i16)
                    let (temp, _fraction) = split_temp(measurement);
                    // ...
                },
                Err(_) => {
                    match e {
                        OneWireError::WireNotHigh => {},
                        OneWireError::CrcMismatch(x, y) => {},
                        OneWireError::FamilyCodeMismatch(x, y) => {},
                        OneWireError::Debug(Some(x)) => {},
                        OneWireError::Debug(None) => {},
                        OneWireError::PortError(_) => {},
                    }
                }
            }

            arduino_hal::delay_ms(500);
        }
    }
    None => {
        loop {
            // ..
        }
    }
}