PicoW + DHT11

Hi all,

I have a Pico running ‘pimoroni-picow-v1.19.1-micropython’, with a DHT11 connected as follows:

GND - GND (32)
VCC - 3V3 (30)

Installed dht.py from here

import array
import micropython
import utime
from machine import Pin
from micropython import const
class InvalidChecksum(Exception):
class InvalidPulseCount(Exception):
MAX_UNCHANGED = const(100)
MIN_INTERVAL_US = const(200000)
HIGH_LEVEL = const(50)
class DHT11:
    _temperature: float
    _humidity: float
    def __init__(self, pin):
        self._pin = pin
        self._last_measure = utime.ticks_us()
        self._temperature = -1
        self._humidity = -1
    def measure(self):
        current_ticks = utime.ticks_us()
        if utime.ticks_diff(current_ticks, self._last_measure) < MIN_INTERVAL_US and (
            self._temperature > -1 or self._humidity > -1
            # Less than a second since last read, which is too soon according
            # to the datasheet
        pulses = self._capture_pulses()
        buffer = self._convert_pulses_to_buffer(pulses)
        self._humidity = buffer[0] + buffer[1] / 10
        self._temperature = buffer[2] + buffer[3] / 10
        self._last_measure = utime.ticks_us()
    def humidity(self):
        return self._humidity
    def temperature(self):
        return self._temperature
    def _send_init_signal(self):
        self._pin.init(Pin.OUT, Pin.PULL_DOWN)
    def _capture_pulses(self):
        pin = self._pin
        pin.init(Pin.IN, Pin.PULL_UP)
        val = 1
        idx = 0
        transitions = bytearray(EXPECTED_PULSES)
        unchanged = 0
        timestamp = utime.ticks_us()
        while unchanged < MAX_UNCHANGED:
            if val != pin.value():
                if idx >= EXPECTED_PULSES:
                    raise InvalidPulseCount(
                        "Got more than {} pulses".format(EXPECTED_PULSES)
                now = utime.ticks_us()
                transitions[idx] = now - timestamp
                timestamp = now
                idx += 1
                val = 1 - val
                unchanged = 0
                unchanged += 1
        pin.init(Pin.OUT, Pin.PULL_DOWN)
        if idx != EXPECTED_PULSES:
            raise InvalidPulseCount(
                "Expected {} but got {} pulses".format(EXPECTED_PULSES, idx)
        return transitions[4:]
    def _convert_pulses_to_buffer(self, pulses):
        """Convert a list of 80 pulses into a 5 byte buffer
        The resulting 5 bytes in the buffer will be:
            0: Integral relative humidity data
            1: Decimal relative humidity data
            2: Integral temperature data
            3: Decimal temperature data
            4: Checksum
        # Convert the pulses to 40 bits
        binary = 0
        for idx in range(0, len(pulses), 2):
            binary = binary << 1 | int(pulses[idx] > HIGH_LEVEL)
        # Split into 5 bytes
        buffer = array.array("B")
        for shift in range(4, -1, -1):
            buffer.append(binary >> shift * 8 & 0xFF)
        return buffer
    def _verify_checksum(self, buffer):
        # Calculate checksum
        checksum = 0
        for buf in buffer[0:4]:
            checksum += buf
        if checksum & 0xFF != buffer[4]:
            raise InvalidChecksum()

Then I run this as main.py:

from machine import Pin, I2C
import utime as time
from dht import DHT11, InvalidChecksum

while True:
    pin = Pin(28, Pin.OUT, Pin.PULL_DOWN)
    sensor = DHT11(pin)
    t  = (sensor.temperature)
    h = (sensor.humidity)
    print("Temperature: {}".format(sensor.temperature))
    print("Humidity: {}".format(sensor.humidity))

My output is always:

Temperature: <bound_method>
Humidity: <bound_method>

I’ve tried mutiple pins and tried code from other DHT11 repos, all seem to give the same output after sensor.temperature is called.

I’ve googled “<bound_method>”, and very few results, none that indicate what I might be doing wrong. Any ideas? TIA

sensor.temperature is a method, you probably want the value, i.e. sensor.temperature().

Progress! thank you @bablokb.

Now I get:

Temperature: 0
Humidity: 0

Which is an actual value I suppose… can’t seem to get any actual readings though…

Very strange. Looking closer at the class, sensor.temperature is defined as a property, so it should behave like a method anyhow and the explicit parenthesis should not be necessary after all. Have you tried printing t and h?

Yep = all 0.0 values

the DHT11 is getting power (led is on) and the cables are the same when working from a RPi4 admittedly the code is not micropython.

Thanks for thoughts so far though, man.

With the caveat that I haven’t used one of these sensors:

pin = Pin(28, Pin.OUT, Pin.PULL_DOWN)

If that’s the data input pin for the sensor, shouldn’t it be a Pin.IN?

Thanks @hel I’m going to give that a go!

@hel unfortunately the change to Pin.IN didn’t work either.

I’m gonna bail on the idea, but thanks again!

You could add print-statements in the class, just to see what is going on.

1 Like