MicroPython Driver for DHT12 Sensor
Contents
Introduction
This a MicroPython driver written specifically for the BBC micro:bit that will work with the DHT12 relative humidity and ambient temperature sensor.
This sensor's only user options are to read relative humidity and temperature. The sensor also returns a validation checksum with this data. This driver provides methods to do exactly this for the user's MicroPython program.
The DHT12 sensor is discussed in some detail here.


The DHT12 is probably now out of production but can still be found (early 2025). The sensor is encased in a tough (probably) ABS plastic casing with four pins exposed. The pins have 2.54mm spacing making this device breadboard friendly.
Connecting the DHT12
The DHT12 communicates via I2C. It also has a 1-wire interface that is backwardly compatible with the older DHT11. This driver does't cater for the 1-wire interface. It's written to exclusively communicate with the sensor via I2C.
Care must be taken when inserting the DHT12 module into a breadboard. The pins are quite thin and bend quite easily. Place the pins over the holes in the breadboard and just wriggle the sensor gently to insert.
Use Fig 1 above as a guide to locating the correct pins on the sensor. The micro:bit and the DHT12 must be connected as follows:
micro:bit | DHT12 |
---|---|
3.3V | VDD |
GND | GND |
Pin 19 | SCL |
Pin 20 | SDA |
This utilises the standard I2C pins of the micro:bit. No external pullup resistors are required as the micro:bit's I2C pins have internal pullups that nicely do the job of keeping SCL and SDA in a HIGH state when the bus is idle.
Driver Overview
The driver code can be:
- Copied from this webpage onto the clipboard then pasted into the MicroPython editor e.g. the Mu Editor. It should be saved as fc_dht12.py - OR -
- Download as a zip file using the link. Unzip the file and save it as fc_dht12.py into the default directory where the MicroPython editor e.g. Mu Editor saves python code files.
After saving the fc_dht12.py file to the computer it should be copied to the small filesystem on the micro:bit. The examples on this page will not work if this step is omitted. Any MicroPython editor that recognises the micro:bit will have an option to do this.
The Mu Editor is recommended for its simplicity. It provides a Files button on the toolbar for just this purpose.
Class constructorThe driver is implemented as a class. The first thing to do is call the constructor. This provides an instance of the class.
Syntax:
instance = DHT12()
Example
from fc_dht12 import *
my_sensor = DHT12()
The constructor has no arguments. The I2C address for the DHT12 is 0x5C. This is fixed and cannot be changed.
This assumes that the file fc_dht12.py has been successfully copied to the micro:bit's filesystem as described above.
Methods and FunctionsThe driver provides three methods and one function that:
- Read(), T(), RH() : Methods to read the relative humidity and ambient temperature.
- CtoF() : Function to convert °C to °F.
Reading Temperature and Humidity
There are three methods that return the humidity and/or temperature.
Read()
Returns a tuple containing three values:
[0] is relative humidity in %RH,
[1] is temperature in °C
[2] is the result of comparing the sensor
checksum with the calculated checksum.
A value of True indicates a high
data confidence.
Relative humidity and temperature are
returned with a precision of one decimal.
RH()
Returns relative humidity in %RH
The result is returned as an integer.
T()
Returns temperature in °C
Example:
# Test the DHT12 MicroPython
# driver for the micro:bit.
from fc_dht12 import *
from microbit import sleep
dht12 = DHT12()
x = 1
# Test every method of the driver 5 times.
while (x < 6):
# Do full sensor read.
print(dht12.Read())
# Get only humidity
rh = dht12.RH()
# Get only temperature
# Convert to fahrenheit
Ctemp = dht12.T()
Ftemp = CtoF(Ctemp)
# Report humidity
# Report temperature (C and F).
print('RH =', rh,
', C =', Ctemp,
', F =', Ftemp, '\n')
# Wait 10 minutes before next readings.
x += 1
if (x != 6):
sleep(600000)
Sample Output:
[13.3, 25.2, True]
RH = 13 , C = 25.2 , F = 77.4
[13.4, 25.2, True]
RH = 15 , C = 25.6 , F = 78.1
[13.4, 25.5, True]
RH = 16 , C = 25.8 , F = 78.4
[15.9, 25.7, True]
RH = 15 , C = 26.1 , F = 79.0
[14.6, 26.2, True]
RH = 15 , C = 26.0 , F = 78.8
Note:
The datasheet advises that no more than one reading should be made per two seconds. Attempting to push the DHT12 much harder will often cause MicroPython to throw an OSError exception because there is no response from the sensor on the I2C bus.
The driver incorporates exception catching code to prevent this from occurring.
Enjoy!
DHT12 Driver Code for micro:bit
Download as zip file
'''
DHT12 (humidity and temperature sensors)
MicroPython driver for micro:bit
AUTHOR: fredscave.com
DATE : 2025/01
VERSION : 1.00
'''
from microbit import i2c, sleep
ADDR = 0x5C
CMD_MEASURE = bytes([0x00])
def CtoF(Ctemp):
return round((Ctemp * 9/5) +32, 1)
class DHT12():
def __init__(self):
self.data = [None] * 3
def Read(self):
attempt = 1
while (attempt < 4):
try:
i2c.write(ADDR, CMD_MEASURE)
sleep(10)
buf = i2c.read(ADDR, 5)
except:
attempt += 1
sleep(1000)
else:
self.data[0] = DHT12._convertRH(buf)
self.data[1] = DHT12._convertT(buf)
self.data[2] = DHT12._checksum(buf)
return self.data
self.data[0] = self.data[1] = None
self.data[2] = False
return self.data
def T(self):
self.Read()
return self.data[1]
def RH(self):
self.Read()
return int(self.data[0] + 0.5)
@staticmethod
def _convertRH(buf):
RH = buf[0] + buf[1]/10
return (RH)
@staticmethod
def _convertT(buf):
T = (buf[2] & 0b01111111) + buf[3]/10
if buf[3] & 0b10000000:
T = -T
return T
@staticmethod
def _checksum(buf):
return buf[0]+buf[1]+buf[2]+buf[3] == buf[4]
Example
This example will use two DHT12 sensors together on the same I2C bus. Two hundred humidity and temperature readings will be taken from each sensor. There will be a three second interval between each set of readings.
Average humidity and temperature will be calculated for each sensor across the two hundred readings.
An I2C multiplexer will be used to connect the two sensors to the I2C bus since each DHT12 has a fixed address. In this case the TCA9548A multiplexer will be used.
For simplicity the two DHT12 sensors will be referred to as (#1)DHT12 and (#2)DHT12.
Driver filesThe following driver module files need to be copied to the micro:bit's filesystem:
- DHT12 : fc_dht12.py
- TCA9548A : fc_tca9548a.py
- Connect TCA9548A, (#1)DHT12 and (#2)DHT12 power and ground pins to the micro:bit's 3.3V and GND pins respectively.
- TCA9548A: Connect SCL and SDA to micro:bit's pin19 and pin20 respectively.
- (#1)DHT12: Connect SCL and SDA pins to TCA9548A's SC1 and SD1 pins respectively.
- (#2)DHT12: Connect SCL and SDA pins to TCA9548A's SC2 and SD2 pins respectively.

Code:
# Two DHT12 humidity and temperature
# sensors will each be read (humidity
# and temperature) two hundred times
# with a three second wait period
# between each set of readings.
# When the all the readings have been
# taken, averages for each of the two
# sensors will be calculated and reported.
from fc_dht12 import *
from fc_tca9548a import *
from microbit import sleep
SAMPLES = 200
tca9548a = TCA9548A()
dht12_1 = DHT12()
dht12_2 = DHT12()
sum_RH1 = sum_T1 = sum_RH2 = sum_T2 = 0
for _ in range(SAMPLES):
# Read (#1)DHT12 sensor
tca9548a.OpenChannels(1)
reading = dht12_1.Read()
sum_RH1 += reading[0]
sum_T1 += reading[1]
tca9548a.CloseChannels(1)
# Read (#2)DHT12 sensor
tca9548a.OpenChannels(2)
reading = dht12_1.Read()
sum_RH2 += reading[0]
sum_T2 += reading[1]
tca9548a.CloseChannels(2)
# Wait 3 seconds
sleep(3000)
# Calculate averages
print('(#1)DHT12 average RH:', sum_RH1/SAMPLES)
print('(#1)DHT12 average T:', sum_T1/SAMPLES)
print('(#1)DHT12 average RH:', sum_RH2/SAMPLES)
print('(#1)DHT12 average T:', sum_T2/SAMPLES)
Output: (#1)DHT12 average RH: 40.802 (#1)DHT12 average T: 25.72602 (#1)DHT12 average RH: 48.36905 (#1)DHT12 average T: 26.31995Notes:
The temperatures between the two sensors are in reasonable agreement at 26°C.
However , in absolute terms, there is a discrepancy of more than 7 %RH between the two sensors. This is a case where an onboard heater (as more sophisticated sensors posses) could be useful. If heat was judicially applied the sensors might provide better results.
Ultimately, both of these sensors should be reconditioned. The product datasheet discusses a process for this.