The first reading
Three wires, one library from the Library Manager, and a dozen lines. The constructor has to say DHT11: nothing on the wire tells the library which sensor is there, and the wrong word prints numbers or nothing instead of an error.
Wire it
Pick your board and the drawing names the pins.
GND to GND, VCC to the supply your board's pins run at, DATA to a free digital pin. NC gets nothing: it is connected to nothing on the board.
VCC is the one that is not free choice. The 10 kΩ resistor on the board ties DATA to VCC, so the data line idles at whatever you feed VCC. On an ESP32, an ESP32-S3 or a Pico that has to be 3V3; on an Uno, 5V. 3.3 V or 5 V is the reason.
Install the library
Tools → Manage Libraries, search DHT sensor library, install Adafruit's.
When the IDE offers Adafruit Unified Sensor as well, say yes: the library
lists it as a dependency and will not compile without it.
The two lines that matter
#define DHT_TYPE DHT11
DHT dht(DHT_PIN, DHT_TYPE);The type is not detected. The library sends the start pulse for the type you name and decodes the answer the same way. Name DHT22 and a DHT11 either never wakes, because the pulse is too short, or answers and is decoded as the other sensor: 23 °C prints as 589. The start and the answer and forty bits and a checksum show both.
The delay(1000) in setup() is from the datasheet: send the DHT11 nothing
for one second after power-up, while it settles.
What to expect
A line every two seconds, in whole numbers:
23 C 51 %
23 C 51 %
24 C 50 %The sketch prints no decimals because the DHT11 sends none. Now and then a
line says read failed. The bits are timed by counting, so a disturbed read is
thrown away rather than guessed at, and readHumidity() and
readTemperature() return nan. nan compares false against everything,
itself included, so isnan() is the only test for it.
The two calls cost one exchange, not two: the library keeps the last five bytes for two seconds, so the second call decodes them again without touching the wire. How often you may ask is what that costs.
In MicroPython
MicroPython has a DHT11 driver built in on the ESP32, the ESP32-S3 and the
Pico. measure() raises OSError when nothing answers, and a plain
Exception when the checksum fails, so catch both.
import dht, machine, time
# The pin DATA is wired to. ESP32: 18. ESP32-S3: 4. Pico: 2.
sensor = dht.DHT11(machine.Pin(4))
time.sleep(1) # nothing for 1 s after power-up
while True:
try:
sensor.measure()
print(sensor.temperature(), "C ", sensor.humidity(), "%")
except Exception: # OSError: no answer; Exception: bad checksum
print("read failed")
time.sleep(2)The code
Prints the temperature and the humidity every two seconds. Set DHT_PIN to the pin you wired DATA to. DHT_TYPE stays DHT11 for the TK38.
/*
DHT11 - the first reading TK38 / /p/tk38
Wiring. Count from the square pad on the TinkerBlock board, sensor
up, header at the bottom:
GND -> GND
VCC -> 3V3 on an ESP32, ESP32-S3 or Pico; 5V on an Uno
NC -> nothing (connected to nothing on the board)
DATA -> D2 on an Uno, GPIO 18 on an ESP32, GPIO 4 on an
ESP32-S3, GP2 on a Raspberry Pi Pico
Arduino IDE
Tools > Board your board, e.g. ESP32S3 Dev Module
Tools > Port the one that appears when you plug in
Tools > USB CDC On Boot Enabled (ESP32-S3 only)
Library Manager: "DHT sensor library" by Adafruit. Say yes when
it offers Adafruit Unified Sensor: it will not compile without.
*/
#include <DHT.h>
// The pin DATA is wired to.
// Uno: 2. ESP32: 18. ESP32-S3: 4. Pico: 2.
#define DHT_PIN 2
#define DHT_TYPE DHT11 // the TK38 is a DHT11
DHT dht(DHT_PIN, DHT_TYPE);
void setup() {
Serial.begin(115200);
dht.begin();
delay(1000); // the datasheet: nothing for 1 s after power-up
}
void loop() {
// Humidity first, then temperature. Both come out of one
// reading: the library keeps the bytes for two seconds.
float humidity = dht.readHumidity();
float celsius = dht.readTemperature();
// A failed read returns nan, never an error. Check every time.
if (isnan(humidity) || isnan(celsius)) {
Serial.println("read failed");
} else {
Serial.print(celsius, 0);
Serial.print(" C ");
Serial.print(humidity, 0);
Serial.println(" %");
}
delay(2000); // the library answers from memory inside 2 s
}If every line says read failed, nothing answered: check GND and VCC first, then that DHT_PIN matches the wire, counting from the square pad. If it prints numbers in the hundreds, the wiring is fine and DHT_TYPE says DHT22. Both are in when every reading is nan.
When it does not work
The library is not installed. Search the Library Manager for "DHT sensor library" and install Adafruit's; several other libraries have DHT in the name and none has the same functions. Accept Adafruit Unified Sensor with it.
Nothing answered on the wire. In order: is GND connected, is VCC on a rail that is powered, and is DATA on the pin DHT_PIN names? Then count again from the square pad. The third pin is connected to nothing, so one position out looks exactly like a dead sensor.
The wiring is right and DHT_TYPE says DHT22. The DHT11's bytes arrived and passed their checksum, then were decoded as a DHT22's. Change the line to DHT11. The back of the board says TK38 DHT11.
That is the serial port rather than the sensor. Set the Serial Monitor to 115200 baud, pick the right port under Tools, and on an ESP32-S3 set USB CDC On Boot to Enabled and upload again.
You can, and the old Lonely Binary tutorial did, but its README now opens "This library is no longer maintained". Adafruit's is maintained, works on AVR as well as the ESP boards, and is what every sketch in this handbook uses.
The supply pin decides what the data pin idles at, and that is the one wiring mistake with a cost.
3.3 V or 5 V →Edit this page — content/books/dht11/the-first-reading.mdx
Questions about this product
See what other owners have asked, and read their solutions.
DHT11 Temperature and Humidity Sensor
Loading discussions…
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.