Closed xiaguangbo closed 7 months ago
Hi! I would suggest using the matrix channel (https://matrix.to/#/#esp-rs:matrix.org) for this kind of questions as they are not issues per se and not strictly related with the training. Also, more people could jump in to help you.
Hi! I would suggest using the matrix channel (https://matrix.to/#/#esp-rs:matrix.org) for this kind of questions as they are not issues per se and not strictly related with the training. Also, more people could jump in to help you.
ok
is ok
use embedded_hal::digital;
use esp_idf_svc::hal::delay;
use esp_idf_svc::hal::gpio;
use esp_idf_svc::hal::peripherals;
use esp_idf_svc::hal::uart;
use esp_idf_svc::hal::units;
use std::fmt::Write;
const CMD_SKIP: u8 = 0xcc;
const CMD_WRITE_REG: u8 = 0x4e;
const CMD_TEMP_START: u8 = 0x44;
const CMD_READ_REG: u8 = 0xbe;
fn main() {
// It is necessary to call this function once. Otherwise some patches to the runtime
// implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
esp_idf_svc::sys::link_patches();
// Bind the log crate to the ESP Logging facilities
esp_idf_svc::log::EspLogger::initialize_default();
log::info!("Hello, world!");
let peripherals = peripherals::Peripherals::take().unwrap();
// onewire
let mut onewire = gpio::PinDriver::input_output_od(peripherals.pins.gpio0).unwrap();
onewire.set_pull(gpio::Pull::Floating).unwrap(); // use external pull-up
// uart
let config = uart::config::Config::default().baudrate(units::Hertz(115_200));
let mut uart = uart::UartDriver::new(
peripherals.uart1,
peripherals.pins.gpio1,
peripherals.pins.gpio2,
Option::<gpio::AnyIOPin>::None,
Option::<gpio::AnyIOPin>::None,
&config,
)
.unwrap();
// delay
let delay = delay::Delay::new_default();
// ds18b20
// wait reset
while !onewire_reset(&mut onewire, &delay) {
delay::FreeRtos::delay_ms(1000);
}
// set accuracy
onewire_write_byte(&mut onewire, &delay, CMD_SKIP);
onewire_write_byte(&mut onewire, &delay, CMD_WRITE_REG);
onewire_write_byte(&mut onewire, &delay, 0xff);
onewire_write_byte(&mut onewire, &delay, 0x00);
onewire_write_byte(&mut onewire, &delay, 0x7f);
loop {
delay::FreeRtos::delay_ms(1000);
// ds18b20
// measurement temp
if !onewire_reset(&mut onewire, &delay) {
continue;
}
onewire_write_byte(&mut onewire, &delay, CMD_SKIP);
onewire_write_byte(&mut onewire, &delay, CMD_TEMP_START);
// read temp
if !onewire_reset(&mut onewire, &delay) {
continue;
}
onewire_write_byte(&mut onewire, &delay, CMD_SKIP);
onewire_write_byte(&mut onewire, &delay, CMD_READ_REG);
let temp_l = onewire_read_byte(&mut onewire, &delay);
let temp_h = onewire_read_byte(&mut onewire, &delay);
let temp = (((temp_h as i16) << 8 | (temp_l as i16)) as f64) * 0.0625;
log::info!("temp: {:.1}", temp);
// uart
writeln!(uart, "temp: {:.1}", temp).unwrap();
}
}
fn onewire_reset<T>(pin: &mut T, delay: &delay::Delay) -> bool
where
T: digital::InputPin + digital::OutputPin,
{
pin.set_low().unwrap();
delay.delay_us(600);
pin.set_high().unwrap();
delay.delay_us(80);
if pin.is_low().unwrap() {
log::info!("onewire: is exist");
delay.delay_us(900);
if pin.is_high().unwrap() {
log::info!("onewire: reset ok");
true
} else {
log::warn!("onewire: reset err");
false
}
} else {
log::warn!("onewire: reset err");
false
}
}
fn onewire_write_byte<T>(pin: &mut T, delay: &delay::Delay, mut byte: u8)
where
T: digital::InputPin + digital::OutputPin,
{
for _ in 0..8 {
let bit = byte & 0x01 != 0;
byte >>= 1;
if bit {
pin.set_low().unwrap();
delay.delay_us(5);
pin.set_high().unwrap();
delay.delay_us(90);
} else {
pin.set_low().unwrap();
delay.delay_us(90);
pin.set_high().unwrap();
delay.delay_us(5);
}
}
}
fn onewire_read_byte<T>(pin: &mut T, delay: &delay::Delay) -> u8
where
T: digital::InputPin + digital::OutputPin,
{
let mut byte: u8 = 0;
for _ in 0..8 {
byte >>= 1;
pin.set_low().unwrap();
delay.delay_us(5);
pin.set_high().unwrap();
delay.delay_us(5);
if pin.is_high().unwrap() {
byte |= 0x80;
}
delay.delay_us(60);
}
byte
}
My basic idea is to encapsulate a
onewire struct
and pass a decimal pin number to drive the corresponding pin. But how do you preserve the objects returned byPinDriver: : input_output_od
? I'm not gonna write this:now: