Both sensors side by side
The kit holds three of each, so wire a DHT22 and a DHT11 to the same board and print both. Two data pins, two DHT objects that differ by one word, and about 30 ms of every pass spent reading. Left running for an hour, it turns ±0.5 °C against ±2 °C from a line in a datasheet into two columns that visibly disagree.
Two pins, two objects
Two boards, two pins, nothing shared but power and ground. Neither knows the other is there.
There is no bus and nothing to share but power and ground. Two boards, two
data pins, two DHT objects, and neither sensor knows the other exists. The
type word in each constructor is the only thing telling the library which
start pulse to send down which pin and how to read what comes back.
What it costs is time. Each read holds the loop while it wakes the sensor and counts forty bits, with interrupts off for the counting. The DHT22's is about 7 ms; the DHT11's is about 25 ms, most of it the 20 ms start pulse the library holds to wake it. Every five seconds that is nothing. Every pass of a loop that also drives a display, it is noticeable.
What an hour shows
The DHT11 moves in steps. Its column sits on one whole degree, then jumps. The DHT22's moves in tenths, so a door opening can show in its column and not in the other.
The gap is not a constant. ±2 °C is a tolerance, not an offset: nothing in the DHT11's datasheet says its error at 15 °C is the one it has at 25 °C, so subtracting today's difference does not calibrate it.
The humidity disagrees more than the temperature. ±5 % against ±2 % is the larger difference of the two, and it is the one that matters once you compute anything from humidity: a comfort reading puts a number on it.
Mount them the same
The one way to make this experiment lie is to mount the two differently. A sensor plugged into the breadboard next to a warm board reads the board; one on long wires reads the room. The gap you then measure is your wiring.
Same height, same airflow, both clear of the board. How slowly it catches up is why a sensor near something warm does not settle late but settles wrong.
The code
Reads a DHT22 and a DHT11 on two pins and prints both and the difference, every five seconds, as comma-separated columns. The two objects differ only in the type word, which is also the only thing telling the library which sensor is on which pin.
/*
DHT22 beside DHT11 TK39 + TK38 / /p/dht
Wiring. Both boards, counting from the square pad, sensor side up,
header at the bottom:
GND -> GND
VCC -> 5V on an Uno; 3V3 on an ESP32, ESP32-S3 or Pico
NC -> nothing (unconnected on the board)
DATA -> DHT22 (white): D2 on an Uno, GPIO 18 on an ESP32,
GPIO 4 on an ESP32-S3, GP2 on a Pico
DHT11 (blue): D3 on an Uno, GPIO 19 on an ESP32,
GPIO 5 on an ESP32-S3, GP3 on a 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)
Tools > Manage Libraries DHT sensor library, by Adafruit.
Say yes to Adafruit Unified Sensor.
Mount the two the same: same height, same air, same distance from
the board. Otherwise you are measuring where they are.
*/
#include <DHT.h>
// Uno: 2 and 3. ESP32: 18 and 19. ESP32-S3: 4 and 5. Pico: 2 and 3.
#define PIN_22 4
#define PIN_11 5
// Nothing on the wire says which is which: the type word does.
DHT white(PIN_22, DHT22);
DHT blue(PIN_11, DHT11);
const unsigned long EVERY_MS = 5000;
unsigned long last = 0;
void setup() {
Serial.begin(115200);
white.begin();
blue.begin();
last = millis();
Serial.println("t22,rh22,t11,rh11,dT,dRH");
}
void loop() {
if (millis() - last < EVERY_MS) return;
last += EVERY_MS;
// About 7 ms for the DHT22, 25 ms for the DHT11: most of the
// DHT11's is its 20 ms start pulse.
float t22 = white.readTemperature(), h22 = white.readHumidity();
float t11 = blue.readTemperature(), h11 = blue.readHumidity();
if (isnan(t22) || isnan(h22) || isnan(t11) || isnan(h11)) {
Serial.println("read failed");
return;
}
Serial.print(t22, 1); Serial.print(",");
Serial.print(h22, 1); Serial.print(",");
Serial.print(t11, 1); Serial.print(",");
Serial.print(h11, 1); Serial.print(",");
Serial.print(t11 - t22, 1); Serial.print(",");
Serial.println(h11 - h22, 1);
}Expect them to disagree, and the DHT11 to move in whole steps. A steady gap of a degree or two is inside the DHT11's ±2 °C, and a humidity gap of several per cent is inside its ±5 %. The sketch compiles for an Uno and an ESP32-S3.
View on GitHub · blocks/tk39-dht22/arduino/dht22_beside_dht11/dht22_beside_dht11.ino @ v1.13When it does not work
Swap the two DATA wires without changing the sketch. If the fault follows the wire, it is the wire or the pin; if it stays with the board, check that board's constructor line. A DHT11 declared as a DHT22 usually never answers, because its start pulse is too short.
That is its resolution. It will read 22.0 for twenty minutes and then 23.0, while the DHT22 beside it walks up in tenths. Seeing the two side by side is most of the reason to build this.
Check they are mounted alike, same height and airflow and distance from the board, before blaming either. A sensor on the breadboard and one on 20 cm of wire are in different air. If they are alike, the DHT11's ±2 °C allows it.
No. The protocol has no addresses, so both would answer at once and the pulses would overlap into nonsense. Each sensor needs a data pin of its own; power and ground can be shared.
A dew point from the two numbers, and what ±2 % against ±5 % humidity does to it.
A comfort reading →Edit this page — content/books/dht22/both-sensors-side-by-side.mdx
Questions about this product
See what other owners have asked, and read their solutions.
This page covers several products. Choose yours to see the right 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.