Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Working with DHT22 with a ESP32 board always returns in an TIMEOUT #23

Closed
yudistrange opened this issue Jun 8, 2023 · 8 comments · Fixed by #25
Closed

Working with DHT22 with a ESP32 board always returns in an TIMEOUT #23

yudistrange opened this issue Jun 8, 2023 · 8 comments · Fixed by #25

Comments

@yudistrange
Copy link

What happened?

I am trying to get readings from a DHT22 sensor using my ESP32 dev board. The result is always a timeout.
The board and the sensor are working. I have verified that by flashing LuaRTOS and getting the sensor to respond back with the temperature / humidity readings.

I looked at the specification of the sensor and then your driver. It mostly makes sense. The timeouts are in the correct range as per the sensor specification. I also tried to implement the specification on my own, but still got the same result. I also forked your repo and increased the timeout, just to ensure that the sensor is not slow. I am also only using the --release tag for optimized binary as talked about in this issue

So I think I may be missing out on some initial setup - setting the pins to be pull-down / pull-up, some other configuration 🤷

Are you aware of any such initialization steps that must be performed for the sensor to work?
Here's my repo that's using your driver.

@yudistrange
Copy link
Author

I also used the wowki emulator for this, just to weed out any physical issues with the device.
The project can be found here. But the result is the same, TIMEOUT

@knightpp
Copy link

knightpp commented Jun 20, 2023

Reproducible on v0.2.1 and main branch. I use Wokwi emulator.

@klimaschkas
Copy link

For anyone coming along this issue, the solution is to use the GPIO pin in open drain mode:

let mut sensor = gpio::PinDriver::input_output_od(pin).unwrap();   // instead of input_output(pin).unwrap()

@michaelbeaumont
Copy link
Owner

Would love to hear whether that solves it for others. This may depend on exactly how the sensor is wired but I think open drain is in fact required for the DHT. It's mentioned/used in both the README and the example.

@Ziothh
Copy link

Ziothh commented Dec 8, 2023

I have a similar issue on my Raspberry Pi Pico H.

I'm new to embedded and tried multiple crates which keep responding with timeouts.
Previously used dht-pio, which hasn't tested the DHT11 yet so I discovered this crate.

Didn't find the rp2040_hal crate referencing configuring pins for open drain so I guessed that pins.gpio28.into_push_pull_output() would to the trick.

My Code

#![no_std]
#![no_main]

use rp_pico as bsp;

use bsp::{entry, hal::clocks::ClockSource};
use defmt::*;
use defmt_rtt as _;
use dht_sensor::DhtReading;
use embedded_hal::digital::v2::OutputPin;
use panic_probe as _;

use bsp::hal::{clocks::init_clocks_and_plls, pac, sio::Sio, watchdog::Watchdog};

#[entry]
fn main() -> ! {
    let mut pac = pac::Peripherals::take().unwrap();
    let mut watchdog = Watchdog::new(pac.WATCHDOG);
    let clocks = init_clocks_and_plls(
        rp_pico::XOSC_CRYSTAL_FREQ,
        pac.XOSC,
        pac.CLOCKS,
        pac.PLL_SYS,
        pac.PLL_USB,
        &mut pac.RESETS,
        &mut watchdog,
    )
    .ok()
    .unwrap();

    let sio = Sio::new(pac.SIO);
    let pins = rp_pico::Pins::new(
        pac.IO_BANK0,
        pac.PADS_BANK0,
        sio.gpio_bank0,
        &mut pac.RESETS,
    );

    let core = pac::CorePeripherals::take().unwrap();
    let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.get_freq().to_Hz());

    let mut dht11_pin = pins.gpio28.into_push_pull_output();
    match dht11_pin.set_high() {
        Ok(value) => info!("Set GPIO28 HIGH: {}", value),
        Err(err) => error!("Failed to set GPIO2 HIGH: {}", err),
    };

    loop {
        info!("Reading from DHT11");
        match dht_sensor::dht11::Reading::read(&mut delay, &mut dht11_pin) {
            Ok(data) => {
                debug!(
                    "Temp info:\nHumidity: {}\nTemperature: {}",
                    data.relative_humidity, data.temperature
                );
            }
            Err(error) => {
                match error {
                    dht_sensor::DhtError::Timeout => {
                        error!("Timeout");
                    }
                    dht_sensor::DhtError::PinError(_e) => error!("DHT PinError"),
                    dht_sensor::DhtError::ChecksumMismatch => error!("DHT ChecksumMismatch"),
                }
            }
        };

        delay.delay_ms(1000);
    }
}

My sensor setup

See Pico pin layout

Data: Green cable from DHT11 left pin to Pico pin 34 (GP28)
Power: Red cable from DHT11 middle pin to Pico pin 36 (3V out)
Ground: Black cable from DHT11 right pin to Pico pin 38 (GND)

IMG_1108

@michaelbeaumont
Copy link
Owner

@Ziothh can you try gpio::InOutPin as used in the rp2040 DHT example?

@Ziothh
Copy link

Ziothh commented Dec 8, 2023

@michaelbeaumont That works! Thanks for the quick response!

@SergioGasquez
Copy link

For reference, here is a working Wokwi project with ESP32: https://wokwi.com/projects/384087992261474305

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants