Skip to main content
2 of 4
more tags
Starter
  • 153
  • 2
  • 13

DHT22 sensor reading code interpretes negative values weirdly (Common problem)

The following code reads the DHT22 temperature and humidity values, assuming the pin value as the sensor's host pin. When the temperature drops below 0 °C, this code returns inadequate values in the range from -3200 to -3300 (most often the values range around -3275). When using an popular Adafruit library, the values are also incorrect. The code was not written by me, it originates from here, but the comments in the source are in Russian.

The problem is quite common, but there was no adequate solution provided in any case. It was mentioned in the Adafruit library issues quite a few times (here, here and here (related)), and on other websites. People even reported this issue on DHT11 and DHT21 sensors.

// "DHTLif.h"

#pragma once
#include <Arduino.h>
#include <Firmata.h>


uint64_t readingTime;


void DHTt(const uint8_t pin) {
    if ((millis() - readingTime) > 2000) {
        unsigned char receivedDHTData[5];
        float temperature, humidity;

        #define DHT_PORT PORTD
        #define DHT_DDR DDRD
        #define DHT_PIN PIND
        #define DHT_BIT pin
        int count = 32;
        unsigned char i, j;

        ReLoad: //Restarting point for error handling
        //=============MCU send START
        DHT_DDR |= (1 << DHT_BIT); //exit
        DHT_PORT &= ~(1 << DHT_BIT); //the pin's level is low, set it to high and wake up the sensor
        delay(18); //18 ms delay from the docs
        DHT_PORT |= (1 << DHT_BIT); //set the pin's level to low
        DHT_DDR &= ~(1 << DHT_BIT); //the pin as exit

        //=============Initialize DHT
        delayMicroseconds(50); //delay from the docs
        if (DHT_PIN & (1 << DHT_BIT)) { //DHT must return 0
            if (count != 0) {
                goto ReLoad;
                count--;
            } else {
                //send initialization error message
                Firmata.sendString("ERR;DHTt;INIT");
                return;
            }
        }

        delayMicroseconds(80);
        if (!(DHT_PIN & (1 << DHT_BIT))) { //the bus must be set to 0 after 80 ms
            if (count != 0) {
                goto ReLoad;
                count--;
            } else {
                //send weird behaviour error message
                Firmata.sendString("ERR;DHTt;BHVR");
                return;
            }
        }

        //===============Receive 40 bits of data
        while (DHT_PIN & (1 << DHT_BIT)); //wait until the bus is set to 1
        for (j = 0; j < 5; j++) { //loop for 0-4 bytes
            receivedDHTData[j] = 0;
            for (i = 0; i < 8; i++) { //receive bits and pack them into bytes
                while (!(DHT_PIN & (1 << DHT_BIT))); //wait until the bus is set to 0
                delayMicroseconds(30); //30 mcs delay from the docs
                if (DHT_PIN & (1 << DHT_BIT)) //if the pin is 1 after the delay,
                    receivedDHTData[j] |= 1 << (7 - i); //set the i'th bit to 1
                while (DHT_PIN & (1 << DHT_BIT)); //wait until the bus is set to 0
            }
        }

        if ((unsigned char)(receivedDHTData[0] + receivedDHTData[1] +
                receivedDHTData[2] + receivedDHTData[3]) != receivedDHTData[4]) { //checksum
            Firmata.sendString("ERR;DHTt;CHSM");
            return;
        }

        temperature = (receivedDHTData[3] * 0.1) + ((receivedDHTData[2] & 0b01111111) * 25.6); //calculating temperature for DHT22
        if (receivedDHTData[2] & 0b10000000) temperature *= -1; //if the temperature is negative
        humidity = (receivedDHTData[1] * 0.1) + (receivedDHTData[0] * 25.6); //calculating humidity for DHT22

        //form the final message
        char result[32], catres[8];
        readingTime = millis();
        strcpy(result, "OK;DHTt;");

        dtostrf(temperature, 5, 2, catres);
        strcat(result, catres);
        strcat(result, ";");

        dtostrf(humidity, 5, 2, catres);
        strcat(result, catres);

        Firmata.sendString(result);
        return;
    }
}
Starter
  • 153
  • 2
  • 13