Embedded System - Arduino

 

 

 

 

Sensor Basic - DHT

 

In this tutorial, I will show you how to operate a Digital Humitity Temperature sensor. This sensor measure the Humidity and Temperature, and output them as a digital data.. meaning the output signal is digital (not Analog). To be honest, I wanted to buy a analog sensor and thought this is an analog sensor outputting a analog signal. But I couldn't confirm it because it didn't have any detailed specification sheet in the package when I bought it. Anyway, even though this was not exactly what I wanted at first but experience was not bad.

By googling afterwards, I saw some module that looks very similar to this but outputting analog signal. So if possible, do some investigation before you buy it and make it sure what you ordered (or what you picked up at the store) is exactly whata you wanted.

 

The connection I made with the module is as follows. Since it outputs the digital signal, I connected the S pin (digital output pin) to one of the digital pin (Pin 2 in this tutorial) as shown below.

 

 

Now it is time to try programming. However, the programming would not be as straightfoward as you might think. You need to read a digital value using a single line. So you might guess the sensor would use a kind of serial communication method to read the data. Implementing a signal communication protocol is quite a huge task if you need to implment it on your own. However, most of these sensor module provide a library by which you can read the value with a very simple command without implementing the serial communication protocol on your own. However, most of these module does not come out with the software library when you buy it. You have to get it from the internet. However, when I was searching the documents and youTube about this type of sensor, I saw a little bit of variations on most of those materials. I think you may make it work with any of those variation but you may need a lot of troubleshooting or tweaking the code if it is not completely fit for your sensor module.  In my case, the package of the module has a web site of the company printed on it and I found a document and sample code as shown below (This code/document would not work with yours since your module is not exactly same as mine. But you may get the proper code/document for yours if you do the same search as I did. One thing to keep in mind is that buy any module that at least web site information of the module maker. If possible, make it sure first that they provide proper document and library before you buy it).

From the module maker's website, I downloaded the document and library code as indicated below,

 

https://osepp.com/electronic-modules/sensor-modules/63-humidity-temperature-sensor

Then I downloaded the sample code and unzipped it (You can unzip it in any location). If you go examples folder you would see files and folders as shown below. In this tutorial, I used the example 'dht11_test' and in the folder you would see an example Arduino sketch file.

 

Next you need to copy the dht.h and dht.c files into the example folder you want to use and modify the source code as indicated below. dht.h and dht.c files are special library file written in c code that is required to operate the DHT sensor module. You may put these two files in Arudion library folder instead of copying into the example folder.. but it didn't work (creating compilation error) in my case. So I decided to copy these files directly into the example folder and it worked.

 

 

Also, depending on the serial port configuration with your PC, you may need to change the following line as well. In my PC, I set COM port baud rate to be 9600. So I changed the code as below.

    Serial.begin(9600);

Then I hope everything is set OK and run the code. I got the result as shown below.

 

 

 

Just for your reference I put the full Arduino code from the example folder that I used. As you see here, I am not the Author of the code. Please give the credit to the Author commented here for his work.

 

//

//    FILE: dht11_test.ino

//  AUTHOR: Rob Tillaart

// VERSION: 0.1.00

// PURPOSE: DHT library test sketch for DHT11 && Arduino

//     URL:

//

// Released to the public domain

//

 

#include "dht.h"

 

dht DHT;

 

#define DHT11_PIN 2

 

void setup()

{

  Serial.begin(9600);

  Serial.println("DHT TEST PROGRAM ");

  Serial.print("LIBRARY VERSION: ");

  Serial.println(DHT_LIB_VERSION);

  Serial.println();

  Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");

}

 

void loop()

{

  // READ DATA

  Serial.print("DHT11, \t");

  int chk = DHT.read11(DHT11_PIN);

  switch (chk)

  {

    case DHTLIB_OK:  

        Serial.print("OK,\t");

        break;

    case DHTLIB_ERROR_CHECKSUM:

        Serial.print("Checksum error,\t");

        break;

    case DHTLIB_ERROR_TIMEOUT:

        Serial.print("Time out error,\t");

        break;

    default:

        Serial.print("Unknown error,\t");

        break;

  }

  // DISPLAY DATA

  Serial.print(DHT.humidity, 1);

  Serial.print(",\t");

  Serial.println(DHT.temperature, 1);

 

  delay(2000);

}

//

// END OF FILE

//

 

If your interest is just to connect a sensor to Arduino board and use it, what I described above would be all that you need. However, if your purpose is more to learn about the technical details of how these works. I would recommend to look into the details of C library code for the sensor module. Just by looking into the c code, it would be hard to understand the logics of the code. You need to understand the technical details of the module or chip on the module. Following is the technical data sheet for the chips used in this module :

http://osepp.com/wp-content/uploads/2015/04/DHT11-Technical-Data-Sheet-Translated-Version.pdf

 

I tried to show some correlation between some important source code block and timing diagram described in the specficiation document as below.

 

 

Just for your reference I put the full Arduino code from the example folder that I used. As you see here, I am not the Author of the code. Please give the credit to the Author commented here for his work.

//

//    FILE: dht.cpp

//  AUTHOR: Rob Tillaart

// VERSION: 0.1.13

// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino

//     URL: http://arduino.cc/playground/Main/DHTLib

//

/....

//

// inspired by DHT11 library

//

// Released to the public domain

//

 

#include "dht.h"

 

/////////////////////////////////////////////////////

//

// PUBLIC

//

 

// return values:

// DHTLIB_OK

// DHTLIB_ERROR_CHECKSUM

// DHTLIB_ERROR_TIMEOUT

int dht::read11(uint8_t pin)

{

    // READ VALUES

    int rv = _readSensor(pin, DHTLIB_DHT11_WAKEUP);

    if (rv != DHTLIB_OK)

    {

        humidity    = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered?

        temperature = DHTLIB_INVALID_VALUE; // invalid value

        return rv;

    }

 

    // CONVERT AND STORE

    humidity    = bits[0];  // bits[1] == 0;

    temperature = bits[2];  // bits[3] == 0;

 

    // TEST CHECKSUM

    // bits[1] && bits[3] both 0

    uint8_t sum = bits[0] + bits[2];

    if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM;

 

    return DHTLIB_OK;

}

 

 

// return values:

// DHTLIB_OK

// DHTLIB_ERROR_CHECKSUM

// DHTLIB_ERROR_TIMEOUT

int dht::read(uint8_t pin)

{

    // READ VALUES

    int rv = _readSensor(pin, DHTLIB_DHT_WAKEUP);

    if (rv != DHTLIB_OK)

    {

        humidity    = DHTLIB_INVALID_VALUE;  // invalid value, or is NaN prefered?

        temperature = DHTLIB_INVALID_VALUE;  // invalid value

        return rv; // propagate error value

    }

 

    // CONVERT AND STORE

    humidity = word(bits[0], bits[1]) * 0.1;

    temperature = word(bits[2] & 0x7F, bits[3]) * 0.1;

    if (bits[2] & 0x80)  // negative temperature

    {

        temperature = -temperature;

    }

 

    // TEST CHECKSUM

    uint8_t sum = bits[0] + bits[1] + bits[2] + bits[3];

    if (bits[4] != sum)

    {

        return DHTLIB_ERROR_CHECKSUM;

    }

    return DHTLIB_OK;

}

 

/////////////////////////////////////////////////////

//

// PRIVATE

//

 

// return values:

// DHTLIB_OK

// DHTLIB_ERROR_TIMEOUT

int dht::_readSensor(uint8_t pin, uint8_t wakeupDelay)

{

    // INIT BUFFERVAR TO RECEIVE DATA

    uint8_t mask = 128;

    uint8_t idx = 0;

 

    // EMPTY BUFFER

    for (uint8_t i = 0; i < 5; i++) bits[i] = 0;

 

    // REQUEST SAMPLE

    pinMode(pin, OUTPUT);

    digitalWrite(pin, LOW);

    delay(wakeupDelay);

    digitalWrite(pin, HIGH);

    delayMicroseconds(40);

    pinMode(pin, INPUT);

 

    // GET ACKNOWLEDGE or TIMEOUT

    uint16_t loopCnt = DHTLIB_TIMEOUT;

    while(digitalRead(pin) == LOW)

    {

        if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;

    }

 

    loopCnt = DHTLIB_TIMEOUT;

    while(digitalRead(pin) == HIGH)

    {

        if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;

    }

 

    // READ THE OUTPUT - 40 BITS => 5 BYTES

    for (uint8_t i = 40; i != 0; i--)

    {

        loopCnt = DHTLIB_TIMEOUT;

        while(digitalRead(pin) == LOW)

        {

            if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;

        }

 

        uint32_t t = micros();

 

        loopCnt = DHTLIB_TIMEOUT;

        while(digitalRead(pin) == HIGH)

        {

            if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;

        }

 

        if ((micros() - t) > 40)

        {

            bits[idx] |= mask;

        }

        mask >>= 1;

        if (mask == 0)   // next byte?

        {

            mask = 128;

            idx++;

        }

    }

    pinMode(pin, OUTPUT);

    digitalWrite(pin, HIGH);

 

    return DHTLIB_OK;

}

 

 

//    FILE: dht.h

//  AUTHOR: Rob Tillaart

// VERSION: 0.1.13

// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino

//     URL: http://arduino.cc/playground/Main/DHTLib

//

// HISTORY:

// see dht.cpp file

//

 

#ifndef dht_h

#define dht_h

 

#if ARDUINO < 100

#include <WProgram.h>

#else

#include <Arduino.h>

#endif

 

#define DHT_LIB_VERSION "0.1.13"

 

#define DHTLIB_OK                0

#define DHTLIB_ERROR_CHECKSUM   -1

#define DHTLIB_ERROR_TIMEOUT    -2

#define DHTLIB_INVALID_VALUE    -999

 

#define DHTLIB_DHT11_WAKEUP     18

#define DHTLIB_DHT_WAKEUP       1

 

// max timeout is 100usec.

// For a 16Mhz proc that is max 1600 clock cycles

// loops using TIMEOUT use at least 4 clock cycli

// so 100 us takes max 400 loops

// so by dividing F_CPU by 40000 we "fail" as fast as possible

#define DHTLIB_TIMEOUT (F_CPU/40000)

 

class dht

{

public:

    // return values:

    // DHTLIB_OK

    // DHTLIB_ERROR_CHECKSUM

    // DHTLIB_ERROR_TIMEOUT

    int read11(uint8_t pin);

    int read(uint8_t pin);

 

    inline int read21(uint8_t pin) { return read(pin); };

    inline int read22(uint8_t pin) { return read(pin); };

    inline int read33(uint8_t pin) { return read(pin); };

    inline int read44(uint8_t pin) { return read(pin); };

 

    double humidity;

    double temperature;

 

private:

    uint8_t bits[5];  // buffer to receive data

    int _readSensor(uint8_t pin, uint8_t wakeupDelay);

};

#endif

//

// END OF FILE

//