rustrum / dht-hal-drv

DHT11 DHT22 sensors platform agnostic driver based on embeded-hal
Other
4 stars 4 forks source link

Readings on STM32Discovery #2

Closed netzdoktor closed 4 years ago

netzdoktor commented 4 years ago

First of all, thank you for this crate (I especially like that it only relies on the embedded-hal and nothing else).

I'm trying to use your driver on a STM32Discovery. I have attempted both measurement strategies, but was not successful:

Open Drain

I cannot get the program properly typed. In your code you have the trait bound of InputPin + OutputPin. So far, I could not find a method in the stm32f3xx_hal that gives me a pin that is both at the same time. Though, there are into_open_drain_output methods that produce a Output<OpenDrain>. Would it be possible to adapt dht_read() to accept hal::gpio::OpenDrain?

Here is my code:

let dht_open_drain = gpiob.pb12
                          .into_open_drain_output(&mut gpiob.moder, 
                                                  &mut gpiob.otyper);
loop {
  let mut delay_fn = |d| delay.delay_us(d);
  // the next statement causes a compilation error as 
  // dht_open_drain does not implement Input
  let result = dht_read(DhtType::DHT22, &mut dht_open_drain, &mut delay_fn);
  match result {
    Ok(r) => {
      iprintln!(&mut cp.ITM.stim[0], "DHT {:?}!", r);
    }
    Err(e) => {
        iprintln!(&mut cp.ITM.stim[0], "ERR {:?}!", e);
    }
  }
}

Split Mode

For split mode, my code "works" as that it successfully prints the readings to ITM. What it does not is providing values that are non-zero. I have checked my DHT22 some time ago with a different another driver and a Raspi board, so I would assume the chip is intact.

let mut dht_pin: DhtHwPin = gpiob
    .pb12
    .into_floating_input(&mut gpiob.moder, &mut gpiob.pupdr);

loop {
    let mut delay_fn = |d| delay.delay_us(d);
    let mut pin_out = dht_pin.into_push_pull_output(&mut gpiob.moder, &mut gpiob.otyper);
    dht_split_init(&mut pin_out, &mut delay_fn).unwrap();
    let mut pin_in = pin_out.into_floating_input(&mut gpiob.moder, &mut gpiob.pupdr);
    let res = dht_split_read(DhtType::DHT22, &mut pin_in, &mut delay_fn);
    match res {
        Ok(r) => {
            iprintln!(&mut cp.ITM.stim[0], "DHT {:?}!", r);
        }
        Err(e) => {
            iprintln!(&mut cp.ITM.stim[0], "ERR {:?}!", e);
        }
    }
    dht_pin = pin_in;
    delay.delay_ms(2_000_u32);
}

Question

Do you have any ideas about 1) how the types can be changed to work with open drain pins from embedded-hal or 2) how to fix

Thanks in advance!

rumatoest commented 4 years ago

Hello. I will review your question in details later.

I'm not sure why it is not the case for you, but open drain pin should work. Look into my example https://github.com/rustrum/dht-hal-drv/blob/master/examples/stm32f103/src/main.rs

Looks like hal::gpio::OpenDrain is not part of embedded-hal and it does no have all required methods or traits. So it would not be usable in my case.

netzdoktor commented 4 years ago

Thanks for looking into that!

Actually I am closely following exactly the example you have linked. Maybe to illustrate this a bit further, here is my error message:

09:55:11 ➜ cargo run
   Compiling aux v0.1.0 (/.../dht/auxiliary)
error[E0277]: the trait bound `stm32f3xx_hal::gpio::gpiob::PB12<stm32f3xx_hal::gpio::Output<stm32f3xx_hal::gpio::OpenDrain>>: embedded_hal::digital::v1::InputPin` is not satisfied
   --> auxiliary/src/lib.rs:34:22
    |
34  |         let result = dht_read(DhtType::DHT22, &mut dht_open_drain, &mut delay_fn);
    |                      ^^^^^^^^ the trait `embedded_hal::digital::v1::InputPin` is not implemented for `stm32f3xx_hal::gpio::gpiob::PB12<stm32f3xx_hal::gpio::Output<stm32f3xx_hal::gpio::OpenDrain>>`
    | 
   ::: /.../registry/src/github.com-1ecc6299db9ec823/dht-hal-drv-0.2.1/src/lib.rs:179:13
    |
179 |     IO_PIN: InputPin + OutputPin,
    |             -------- required by this bound in `dht_hal_drv::dht_read`
    |
    = note: required because of the requirements on the impl of `embedded_hal::digital::v2::InputPin` for `stm32f3xx_hal::gpio::gpiob::PB12<stm32f3xx_hal::gpio::Output<stm32f3xx_hal::gpio::OpenDrain>>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `aux`.

To learn more, run the command again with --verbose.

Maybe I am a bit confused, but I thought the trait bounds where T: TraitA + TraitB is a intersection, i.e. a type T must implement both TraitA and TraitB at the same time.

In your example you are using this method and I don't understand how this can return an Output<OpenDrain> that also implements the InputPin trait.

netzdoktor commented 4 years ago

I just found your PR is ongoing, so I just subscribed to these and will look again into the split_read approach. Thank you again!

rumatoest commented 4 years ago

BTW it would not work on Stm32 in debug mode (zero readings of yours DHT). Looks like it can not measure time correctly with required granularity.