Skip to main content
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
deleted 363 characters in body; edited title
Source Link
ocrdu
  • 1.8k
  • 3
  • 12
  • 24

DHT22 sensor reading code interpretesinterprets 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 °C0°C, this code returns inadequate values in the range from -3200 to -3300 (most often the values range around -3275). When using ana 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.

// "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 mcsms 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;
    }
}

The only fix I found looks really silly and it does not work, the values doesn'tdon't drop below zero.

// The temperature is a 16 bit signed integer, 10 times the actual value in degrees Celsius
int16_t temperatureTimesTen = (int16_t)((receivedDHTData[2] << 8) | receivedDHTData[3]);
float temperature = (float)(temperatureTimesTen) * 0.1f;

// The maximum possible temperature for an DHT22 is 80 degrees Celsius
if (temperature > 80) temperature = temperature - 3276.7f;

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.

// "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;
    }
}

The only fix I found looks really silly and it does not work, the values doesn't drop below zero.

//The temperature is a 16 bit signed integer, 10 times the actual value in degrees Celsius
int16_t temperatureTimesTen = (int16_t)((receivedDHTData[2] << 8) | receivedDHTData[3]);
float temperature = (float)(temperatureTimesTen) * 0.1f;

//The maximum possible temperature for an DHT22 is 80 degrees Celsius
if (temperature > 80) temperature = temperature - 3276.7f;

DHT22 sensor reading code interprets negative values weirdly

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 a 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.

// "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 ms 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;
  }
}

The only fix I found looks really silly and it does not work, the values don't drop below zero.

// The temperature is a 16 bit signed integer, 10 times the actual value in degrees Celsius
int16_t temperatureTimesTen = (int16_t)((receivedDHTData[2] << 8) | receivedDHTData[3]);
float temperature = (float)(temperatureTimesTen) * 0.1f;

// The maximum possible temperature for an DHT22 is 80 degrees Celsius
if (temperature > 80) temperature = temperature - 3276.7f;
Bumped by Community user
Bumped by Community user
addi
Source Link
Starter
  • 153
  • 2
  • 13

The only fix I found looks really silly and it does not work, the values doesn't drop below zero.

//The temperature is a 16 bit signed integer, 10 times the actual value in degrees Celsius
int16_t temperatureTimesTen = (int16_t)((receivedDHTData[2] << 8) | receivedDHTData[3]);
float temperature = (float)(temperatureTimesTen) * 0.1f;

//The maximum possible temperature for an DHT22 is 80 degrees Celsius
if (temperature > 80) temperature = temperature - 3276.7f;

The only fix I found looks really silly and it does not work, the values doesn't drop below zero.

//The temperature is a 16 bit signed integer, 10 times the actual value in degrees Celsius
int16_t temperatureTimesTen = (int16_t)((receivedDHTData[2] << 8) | receivedDHTData[3]);
float temperature = (float)(temperatureTimesTen) * 0.1f;

//The maximum possible temperature for an DHT22 is 80 degrees Celsius
if (temperature > 80) temperature = temperature - 3276.7f;
more tags
Link
Starter
  • 153
  • 2
  • 13
Source Link
Starter
  • 153
  • 2
  • 13
Loading