EthicsComputerCourses
Join training +91 90532 10052

Temperature & Humidity Sensors

IoT & Arduino · Lesson 17 of 29 Intermediate 6 min read Updated

By the end of this lesson you will be able to read temperature and humidity from a DHT22 sensor, handle failed readings properly, convert an analog temperature sensor's voltage into degrees, and choose a better sensor when accuracy matters. Your board will finally measure something about the real world.

Temperature and humidity matter everywhere in India: a mushroom farm in Himachal, a pharmacy cold box, a server room, or just deciding whether to switch on the cooler in a Jaipur summer.

Two kinds of sensors

Humidity is the amount of water vapour in the air. Relative humidity (RH), given as a percentage, compares it with the most the air could hold at that temperature. Mumbai in the monsoon can sit near 90% RH; Jaisalmer in summer can drop below 20%.

SensorMeasuresOutputRange and accuracy (datasheet, typical)Notes
DHT11Temperature, humidityDigital, one data wire0 to 50 °C (±2 °C), 20 to 90% RH (±5%)Cheap, slow, low accuracy
DHT22 (AM2302)Temperature, humidityDigital, one data wire-40 to 80 °C (±0.5 °C), 0 to 100% RH (±2 to 5%)Better; read at most every 2 s
TMP36Temperature onlyAnalog voltage-40 to 125 °C, about ±2 °CNeeds only analogRead()
BME280, SHT31, SHT4xTemperature, humidity (BME280 also pressure)I2CMore accurateUse with the I2C lessons

Accuracy figures vary between manufacturers and clones, so read the datasheet for your exact part. Cheap DHT clones in particular may not meet the original specification.

Step 1: Wire a DHT22 module

Most kits sell the DHT22 on a small module with three pins and a pull-up resistor already fitted.

PartPinConnects to
DHT22 module+ (VCC)Arduino 5V (use 3.3V on an ESP32)
DHT22 moduleOUT (data)Arduino D4
DHT22 module- (GND)Arduino GND

If you have the bare 4-pin sensor instead, add a 10 kΩ resistor from the data pin to VCC, and leave the third pin unconnected. Check the pin order in your sensor's datasheet; it is printed facing the grille side.

Step 2: Install the library

The DHT sensors use a timing-based protocol on one wire. Writing it yourself is hard, so use a library:

  1. Open the Library Manager.
  2. Search for DHT sensor library and install the one by Adafruit.
  3. When asked, choose Install all to also install its dependency, Adafruit Unified Sensor.

Step 3: Read the sensor

C++
#include <DHT.h>

const int DHT_PIN = 4;
DHT dht(DHT_PIN, DHT22);              // use DHT11 here for a DHT11

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

void loop() {
  delay(2000);                         // the DHT22 needs 2 s between reads
  float humidity = dht.readHumidity();
  float tempC = dht.readTemperature(); // Celsius by default

  if (isnan(humidity) || isnan(tempC)) {
    Serial.println("Sensor read failed, check wiring");
    return;                            // skip this pass, try again
  }

  Serial.print("Temp: ");
  Serial.print(tempC, 1);
  Serial.print(" C  Humidity: ");
  Serial.print(humidity, 0);
  Serial.println(" %");
}

In a room in Pune on a monsoon afternoon, you might see something like:

Output
Temp: 28.6 C  Humidity: 74 %
Temp: 28.6 C  Humidity: 74 %
Temp: 28.7 C  Humidity: 75 %

These are example readings; yours depend on your room. Breathe gently on the sensor and the humidity should rise within a few seconds.

isnan() means "is not a number". When the library cannot read the sensor (loose wire, wrong pin, wrong type), it returns a special value called NaN instead of a temperature. Always check for it. Otherwise, your code may switch on a fan because of a reading that does not exist.

return inside loop() ends this pass early. loop() then simply starts again.

Step 4: Turn readings into decisions

Numbers are only useful when they lead to a decision. Keep the decision logic in its own function so you can test it with fixed values before trusting it with real ones:

C++
const char* comfort(float tempC, float humidity) {
  if (tempC >= 32 && humidity >= 60) return "hot and humid: turn on the fan";
  if (tempC >= 32) return "hot and dry: drink water";
  if (tempC < 18) return "cool";
  return "comfortable";
}

void setup() {
  Serial.begin(9600);
  while (!Serial && millis() < 3000) { }
  const float temps[] = {34.5, 35.0, 26.0, 15.5};
  const float hums[]  = {72, 30, 55, 80};
  for (int i = 0; i < 4; i++) {
    Serial.print(temps[i], 1);
    Serial.print(" C, ");
    Serial.print(hums[i], 0);
    Serial.print(" % -> ");
    Serial.println(comfort(temps[i], hums[i]));
  }
}

void loop() {
}
Output
34.5 C, 72 % -> hot and humid: turn on the fan
35.0 C, 30 % -> hot and dry: drink water
26.0 C, 55 % -> comfortable
15.5 C, 80 % -> cool

The order of the if checks matters. The most specific case (hot and humid) comes first; otherwise "hot and dry" would catch every hot reading. The thresholds here are only examples; choose your own for your project.

An analog sensor: TMP36

The TMP36 is a three-legged chip that outputs a voltage: 500 mV at 0 °C, rising 10 mV for every degree. So:

temperature in °C = (millivolts − 500) ÷ 10

PartPinConnects to
TMP36 (flat side facing you)Left5V
TMP36MiddleA1
TMP36RightGND

Getting the pins backwards makes a TMP36 hot quickly, so double-check against the datasheet before powering on, and unplug immediately if it warms up.

This sketch tests the conversion on fixed ADC readings:

C++
float tmp36Celsius(int raw) {
  float millivolts = raw * 5000.0 / 1023.0;   // 5 V UNO, 10-bit ADC
  return (millivolts - 500.0) / 10.0;
}

void setup() {
  Serial.begin(9600);
  while (!Serial && millis() < 3000) { }
  const int samples[] = {123, 153, 164, 205};
  for (int i = 0; i < 4; i++) {
    Serial.print("raw ");
    Serial.print(samples[i]);
    Serial.print(" -> ");
    Serial.print(tmp36Celsius(samples[i]), 1);
    Serial.println(" C");
  }
}

void loop() {
}
Output
raw 123 -> 10.1 C
raw 153 -> 24.8 C
raw 164 -> 30.2 C
raw 205 -> 50.2 C

For the live sensor, call tmp36Celsius(analogRead(A1)) in loop(). Each ADC step is about 4.9 mV, which is about half a degree, so averaging several readings (from Analog Input) helps.

Common mistakes

  • Reading a DHT22 too often. Reads faster than every 2 s may return old values or NaN.
  • Wrong sensor type in code. DHT11 in code with a DHT22 connected gives nonsense.
  • Not checking isnan(). Failed reads become decisions based on nothing.
  • Bare DHT sensor without a pull-up. Add 10 kΩ from data to VCC, or use a module.
  • Trusting cheap sensors for critical uses. For medicine storage or labs, use calibrated sensors.

Key points

  • DHT11 and DHT22 send temperature and humidity digitally on one data wire; DHT22 is more accurate.
  • Use the Adafruit DHT sensor library: dht.begin(), readTemperature(), readHumidity().
  • Check readings with isnan() and wait about 2 s between DHT22 reads.
  • TMP36: °C = (millivolts − 500) ÷ 10, read with analogRead().
  • Test decision logic with fixed values before connecting it to real sensors.

Exercise

Write a function fanSpeed(float tempC) that returns a PWM value: 0 below 28 °C, 128 from 28 °C up to (but not including) 33 °C, and 255 at 33 °C and above. Test it with 25.0, 28.0, 32.9 and 33.0, printing each result.

Show solution
C++
int fanSpeed(float tempC) {
  if (tempC >= 33.0) return 255;
  if (tempC >= 28.0) return 128;
  return 0;
}

void setup() {
  Serial.begin(9600);
  while (!Serial && millis() < 3000) { }
  const float tests[] = {25.0, 28.0, 32.9, 33.0};
  for (int i = 0; i < 4; i++) {
    Serial.print(tests[i], 1);
    Serial.print(" C -> fan PWM ");
    Serial.println(fanSpeed(tests[i]));
  }
}

void loop() {
}
Output
25.0 C -> fan PWM 0
28.0 C -> fan PWM 128
32.9 C -> fan PWM 128
33.0 C -> fan PWM 255

Testing the exact edges (28.0 and 33.0) and just below an edge (32.9) catches mistakes between > and >=.

Quick Quiz

1. What does isnan(tempC) check?

2. How often should you read a DHT22?

3. A TMP36 outputs 750 mV. What is the temperature?

4. Why test decision functions with fixed values first?

Learn IoT & Arduino with a mentor

Free lessons get you started. Our IoT & Embedded Systems training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call