Home CodeMicropython A Raspberry Pi Pico and KY-015 Temperature Sensor

A Raspberry Pi Pico and KY-015 Temperature Sensor

by rp2040guy71

In this article, we connect a KY-015 Temperature Sensor to a Raspberry Pi Pico, any Rp2040 type board will be suitable. We actually tested this with a Cytron Maker Pi Pico

We will use Micropython for these examples but of course you can use the Arduino IDE as well if you have Raspberry Pi Pico support enabled

The KY-015 is a DHT11 temperature and humidity sensor with an integrated 1k ohm resistor.  The onboard DHT11 uses an internal capacitive humidity sensor and thermistor to determine environment conditions, and digital I/O integrated circuit for creating the serialized digital output.

DHT11 output calibrated digital signal. It utilizes exclusive digital-signal-collecting-technique and humidity sensing technology, assuring its reliability and stability. Its sensing elements is connected with 8-bit single-chip computer.
Every sensor of this model is temperature compensated and calibrated in accurate calibration chamber and the calibration-coefficient is saved in OTP memory.

Later sensors use I2C, one drawback is that the device is slow – you need sleeps/delays between readings,

  • Operating Voltage: 3.3V to 5V
  • Current Consumption: 1.5mA
  • Temperature Measurement Range: 32ºF to 122ºF( 0ºC to 50ºC)
  • Temperature Measurement Accuracy: ±2ºC
  • Temperature Measurement Resolution: 1ºC
  • Humidity Measurement Range: 20% to 90% RH
  • Humidity Measurement Resolution: ±5% RH
  • Digital Out Signal Transmission Range:
  • Dimensions: .75in X 1.77in (2cm x 4.5cm)


The sensor looks like this

Parts Required

You can connect to the module using dupont style jumper wire.

Name Link
Raspberry Pi Pico
37 in one sensor kit
Connecting cables



3v3 +


Code Examples

Basic example – this requires a file called dht.py and the n the example code. These are in the link underneath


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()



from machine import Pin
import utime as time
from dht import DHT11, InvalidChecksum
while True:
    pin = Pin(27, Pin.OUT, Pin.PULL_DOWN)
    sensor = DHT11(pin)
    t  = (sensor.temperature)
    h = (sensor.humidity)
    print("Temperature: {}".format(sensor.temperature))
    print("Humidity: {}".format(sensor.humidity))


REPL Output

Temperature: 19.2
Humidity: 48.0
Temperature: 19.2
Humidity: 48.0
Temperature: 19.3
Humidity: 48.0
Temperature: 19.5
Humidity: 48.0
Temperature: 19.3
Humidity: 49.0
Temperature: 19.7
Humidity: 50.0




You may also like

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More