ESP32/Wires on the board/23. One-wire sensor timing
No board required

This one is about the wire, not the chip. Nothing below changes with the board you picked, which is why the chip and language switches are not on it. They come back on the ESP32 pages this one sits underneath.

Wires on the board · 23 of 81

One-wire sensor timing

A DHT11 or DHT22 sends forty bits down a single data wire, and the value of each bit is how long the line stays high — twenty-six microseconds for a zero, seventy for a one. There is no clock, no address and no error reporting, which is why this sensor is both the easiest to wire and the fussiest to read.

/esp32/one-wire-sensor-timing · any board · 8 min read

Step through the exchange. Every step is the same wire, changing hands.

One wire, one direction at a time
your pin is driving
idle
idle, high. The pull-up resistor holds the line high. Nobody is talking, and that is the resting state — a one-wire sensor is silent until you ask.
Measure a high pulse yourself27 µs
27 µs is a 0. Comfortably under the 50 µs line. Forty of these make five bytes: humidity, temperature, and a checksum that catches the reading where one pulse got mistimed.

One wire, two owners

The line idles high, held there by a pull-up resistor — usually already on the module. Your pin is an input, doing nothing.

To ask for a reading you make the pin an output and pull the line low for a millisecond or more. Then you let go, switch back to input, and from that moment the sensor is driving the same wire. It answers with a low, then a high, then forty bits, then releases the line and goes quiet for at least two seconds.

Nothing in that sequence is negotiated. Both ends simply agree, in advance, what the timings mean. That is what makes it cheap and what makes it brittle.

The bit is the pulse width

Every data bit starts with a 50 µs low that carries no information at all. What follows is either a short high (26–28 µs) or a long one (70 µs). Your code times that high pulse and compares it with about 50 µs. That comparison is the entire decoder.

Why this is fragile. Fifty microseconds is roughly four hundred instructions on an ESP32. If anything interrupts you mid-bit — Wi-Fi, a timer, another library — your measurement is long, the bit flips, and the reading is wrong. The five-byte checksum catches it and your library reports a failed read, which is the "sometimes it returns NaN" everybody meets.

What actually goes wrong

Reading too often. A DHT22 needs two seconds between reads, a DHT11 one. Ask sooner and it returns the previous sample or nothing at all.

No pull-up. Bare sensors need a 4.7 kΩ or 10 kΩ resistor from data to 3V3. Most modules already have one; a three-pin board almost certainly does, a four-pin bare sensor does not.

Long wires. Beyond about 20 cm the edges soften and the pulse widths blur. This protocol has no error correction, only detection — you find out by getting nothing.

Sharing the pin. One sensor per pin. There is no address, so two DHTs on one wire both answer at once and neither can be understood.

Use the library

#include <DHT.h>
#define DHTPIN  4

DHT dht(DHTPIN, DHT22);

void setup() {
  Serial.begin(115200);
  dht.begin();
}

void loop() {
  float t = dht.readTemperature();
  float h = dht.readHumidity();
  if (isnan(t) || isnan(h)) Serial.println("bad read");   // expect a few
  else Serial.printf("%.1f C  %.1f %%\n", t, h);
  delay(2000);                                            // the minimum
}

Timing this by hand is a good exercise and a bad plan: the library already disables interrupts around the critical section and retries. Checking for nan is not optional — a few failed reads per hundred is normal, not a fault.

The name collision

This is not the same thing as 1-Wire with a capital W. Dallas 1-Wire is a real bus with 64-bit addresses and many devices on one line, and it is the next page. The DHT just happens to use one wire, which is a description, not a protocol.

Edit this page — content/esp32/one-wire-sensor-timing.mdx

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse ESP32 on the forum