DHT11 and DHT22 temperature/humidity sensors are very common in Arduino, ESP8266, ESP32, RP2040 and beginner electronics projects. They are inexpensive, easy to connect, and supported by many Arduino libraries.
They are also famous for producing confusing errors. A sketch may compile correctly, the sensor may be wired correctly at first glance, but the serial monitor only shows NaN, 0, strange values, or readings that work once and then fail.
In many cases, the sensor is not defective. The problem is usually timing, wiring, missing pull-up resistor, unstable power, wrong pin number, reading too often, cable length, or using the wrong sensor type in the code.
Typical Symptoms
- The serial monitor shows NaN instead of temperature or humidity.
- The sensor returns 0 or impossible values.
- The first reading works, but later readings fail.
- Readings work on Arduino Uno but fail on ESP32 or ESP8266.
- The sensor works with short wires but fails with longer wires.
- The values jump around without a clear reason.
- The sketch works with one DHT module but not another.
What NaN Means
NaN means “Not a Number.” In a DHT sensor project, it usually means the library did not receive a valid reading from the sensor.
This can happen when:
- The sensor did not answer.
- The data timing was wrong.
- The checksum failed.
- The pin number in the sketch is wrong.
- The sensor is read too often.
- The signal line is noisy or floating.
NaN is not usually a math problem in the sketch. It is usually a communication problem between the microcontroller and the DHT sensor.
First Check: DHT11 and DHT22 Are Not the Same
DHT11 and DHT22 sensors use a similar one-wire-style data signal, but the library must know which sensor type is connected.
If the sketch is configured for the wrong type, readings may fail or produce wrong values.
#define DHTTYPE DHT22
or:
#define DHTTYPE DHT11
Make sure this setting matches the actual sensor.
| Sensor | Typical Use | Important Note |
|---|---|---|
| DHT11 | Low-cost basic temperature/humidity sensing | Lower accuracy and smaller measurement range |
| DHT22 / AM2302 | Better hobby-grade temperature/humidity sensing | More accurate than DHT11, but still timing-sensitive |
| DHT module board | Sensor mounted on a small PCB | Often includes pull-up resistor already |
| Bare DHT sensor | Raw 3-pin or 4-pin sensor body | Usually needs external pull-up resistor |
Common Cause: Missing Pull-Up Resistor
The DHT data line needs a pull-up resistor. Many small DHT module boards already include one. Bare DHT sensors usually do not.
A typical pull-up value is around 4.7kΩ to 10kΩ from the data pin to VCC.
Without a pull-up resistor, the data signal may float. The microcontroller may then receive random bits, invalid checksums, or no valid response at all.
- If you use a 3-pin DHT module board, the pull-up may already be included.
- If you use a bare DHT11 or DHT22 sensor, add an external pull-up.
- For longer wires, a stronger pull-up such as 4.7kΩ may be more reliable than 10kΩ.
Common Cause: Wrong Pin Number in the Sketch
Pin numbering can be confusing, especially on ESP8266 and ESP32 boards.
For example, a board may label a pin as D4, but the actual GPIO number may be different. Some libraries expect the GPIO number, not the printed board label.
Check whether your sketch uses the correct pin definition.
#define DHTPIN 2
On some boards, this may mean GPIO2. On others, the printed pin label may not match the number you think it does.
When troubleshooting, check the exact pinout for your board and use a known-safe GPIO pin.
Common Cause: Reading the Sensor Too Often
DHT sensors are slow. They should not be read continuously as fast as the microcontroller can run.
If the sensor is read too often, it may return failed readings or repeated old data.
- DHT11 should usually not be read more than about once per second.
- DHT22 should usually not be read more than about once every two seconds.
- For stable projects, reading every 3 to 10 seconds is often better.
A common beginner mistake is placing the DHT read command inside a fast loop without enough delay or timing control.
void loop() {
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
delay(2000); // Important for DHT22
}
Common Cause: Long Wires
DHT sensors use timing-sensitive digital communication. Long wires can distort the signal and pick up electrical noise.
Long DHT wires are especially likely to cause problems when:
- The wire is thin or unshielded.
- The cable runs near motors, relays, LED strips or power wiring.
- The pull-up resistor is too weak.
- The sensor is powered from a noisy supply.
- The microcontroller uses 3.3V logic and the signal margin is small.
For troubleshooting, test the sensor with short wires first. If it works with short wires but not long wires, the sensor and code are probably fine.
Common Cause: Weak or Noisy Power
DHT sensors do not need a lot of current, but they still need stable power and ground. A noisy supply can cause failed readings.
Check for:
- Loose breadboard contacts.
- Weak USB power.
- Bad ground connection.
- Sensor powered from a pin that is not a real power output.
- Relay, motor or LED current sharing the same weak supply path.
A small capacitor between VCC and GND near the sensor can help in noisy environments, but it does not replace correct wiring.
Common Cause: 3.3V vs 5V Operation
DHT11 and DHT22 sensors are often used at either 3.3V or 5V, depending on the module and controller. But the signal level and pull-up voltage must be compatible with the microcontroller.
For ESP32, ESP8266, RP2040 and most modern boards, the GPIO pins are 3.3V logic. Do not pull the data line up to 5V unless the microcontroller pin is 5V tolerant or proper level shifting is used.
- With ESP32 or ESP8266, power the DHT module from 3.3V if the module works reliably at 3.3V.
- If the DHT module must be powered from 5V, make sure the data signal is safe for the controller.
- For classic 5V Arduino boards, 5V operation is usually straightforward.
Common Cause: Using a Bad GPIO Pin
Some microcontroller pins have special functions during boot, programming or startup. This is especially important on ESP8266 and ESP32 boards.
If a DHT sensor is connected to a boot strapping pin, the pull-up resistor or sensor behavior may affect booting. The project may fail to start, reset strangely, or upload unreliably.
For ESP32 and ESP8266 projects, use a normal GPIO pin that is safe for general input use. Avoid pins that are used for flash memory, USB, boot mode or board-specific functions.
Common Cause: Interrupts and Timing Conflicts
DHT communication is timing-sensitive. Some libraries temporarily disable interrupts or rely on accurate timing. Other code running in the project can interfere.
Problems are more likely when the project also uses:
- NeoPixel / WS2812B LED strips.
- SoftwareSerial.
- Servo timing.
- Fast interrupt routines.
- Heavy WiFi activity on ESP8266 or ESP32.
- Blocking code that delays sensor reads in strange ways.
If the DHT works in a simple test sketch but fails in the full project, the problem is probably not wiring. Something in the full sketch may be interfering with timing.
Common Cause: Sensor Is Too Close to Heat Sources
Wrong readings are not always communication errors. Sometimes the sensor measures exactly what it is exposed to.
A DHT sensor placed near a voltage regulator, ESP32 module, display backlight, power resistor or enclosure wall heated by sunlight may report higher temperatures than expected.
Humidity readings can also be affected by poor airflow, condensation, dust, or being mounted too close to warm electronics.
Common Cause: Cheap or Damaged Sensor
DHT sensors are low-cost parts and quality can vary. Some modules are damaged by wrong wiring, static discharge, moisture, overheating, or physical stress.
A sensor may be defective if:
- It never works with a simple test sketch.
- It gets unusually hot.
- It works only when touched or moved.
- It always returns the same impossible value.
- Another identical sensor works with the same wiring and sketch.
Simple DHT22 Test Sketch
When troubleshooting, use the simplest possible sketch first. Do not test the sensor for the first time inside a large project.
#include <DHT.h>
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(115200);
dht.begin();
Serial.println("DHT test started");
}
void loop() {
delay(2000);
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor");
return;
}
Serial.print("Humidity: ");
Serial.print(humidity);
Serial.print(" % Temperature: ");
Serial.print(temperature);
Serial.println(" C");
}
For DHT11, change the sensor type:
#define DHTTYPE DHT11
Recommended Troubleshooting Steps
- Use a simple DHT test sketch, not the full project.
- Confirm whether the sensor is DHT11, DHT22 or AM2302.
- Set the correct sensor type in the code.
- Confirm the correct GPIO pin number.
- Add a 4.7kΩ to 10kΩ pull-up resistor if using a bare sensor.
- Read DHT22 no faster than every 2 seconds.
- Use short wires during testing.
- Check VCC and GND directly at the sensor.
- Try a different GPIO pin.
- Test another sensor if available.
Quick Diagnostic Table
| Symptom | Likely Cause | First Thing to Try |
|---|---|---|
| Always NaN | Wrong pin, wrong sensor type, missing pull-up | Check pin number and DHTTYPE |
| Works once, then fails | Reading too often | Increase delay between readings |
| Works with short wires only | Signal quality or weak pull-up | Use shorter wires or stronger pull-up |
| Works alone, fails in full project | Timing conflict or noisy power | Disable other timing-sensitive code temporarily |
| Temperature too high | Sensor heated by nearby electronics | Move sensor away from regulator, ESP module or display |
| Random values | Loose wiring, noise, bad sensor | Rebuild wiring and test with short leads |
DHT Sensors Are Not Precision Instruments
DHT11 and DHT22 sensors are useful for simple projects, but they are not ideal for precision measurement, fast response, or harsh environments.
For more reliable temperature and humidity sensing, modern I2C sensors such as AHT20, SHT30, SHT31 or BME280-style modules are often easier to use. They avoid the timing-sensitive DHT signal and communicate over standard I2C.
This is one reason why many modular systems and newer sensor boards prefer I2C sensors instead of DHT-style one-wire timing sensors.
CANABLOX Practical Note
CANABLOX focuses heavily on I2C modules because they are easier to connect, scan, combine and troubleshoot than timing-sensitive single-wire sensors. With an I2C temperature/humidity module, the wiring is standardized and the sensor address can be detected with a scanner.
If a project needs reliable environmental sensing, an I2C sensor module is often a better long-term choice than a DHT11 or DHT22, especially when several modules are used together.
Conclusion
If a DHT11 or DHT22 sensor returns NaN, zero or random values, start with the basics: correct sensor type, correct pin, pull-up resistor, stable power, short wires and enough delay between readings.
Most DHT problems are caused by timing or wiring, not by complicated code. Test the sensor alone with a simple sketch first. Once it works reliably by itself, add it back into the full project.
For new designs where reliability matters, consider using a modern I2C temperature/humidity sensor instead. It will usually be easier to connect, easier to scan and easier to troubleshoot.
