Jan Zumwalt
Published © GPL3+

Pinguino DHT11, 15, 22 Sensor

DHT11, 15, 22 Temperature and Humidity.

BeginnerProtip1,107
Pinguino DHT11, 15, 22 Sensor

Things used in this project

Hardware components

DHT11 Temperature & Humidity Sensor (4 pins)
DHT11 Temperature & Humidity Sensor (4 pins)
×1
DHT22 Temperature Sensor
DHT22 Temperature Sensor
×1
dht 15
×1
Pinguino compatable microcontroller
×1

Story

Read more

Code

Code snippet #1

Plain text
/*-----------------------------------------------------
author:  Jan Zumwalt
date:    2016.01.14
build:   tested on Olimex Pic32 Micro using Pinguino.cc IDE
description: 
  This is an adaptation of several Arduino programs. It will
  read a DHT temperature/humidity sensor. Tested with a dht_11, 
  but should work with dht_15 and dht_22. This example makes 
  no special demands on hardware, so should work with any 
  Pinguino board.
Note: Attempts to load this program as a library have failed.
      Expect an update once the problem is solved.
-----------------------------------------------------*/

const int dht_success        = 0;  // read success
const int dht_notconnected   = 1;  // dht not found
const int dht_checksumfailed = 2;  // dht data error

// define the structure to hold the returned data.
// this will only be filled out on a successful reading.
  
struct dht_data { // define dht register structure
  int int_humidity;
  int dec_humidity;
  int int_temperature;
  int dec_temperature;
  int checksum;
  int status; // 0=success, 1=not connected, 2=chksum error, 3=other
};

struct dht_data dht_register;        // Declare dht_register of type dht_data 

/* ---------------------------------------------------------------

  dhtReadByte() reads one byte using proprietary 1-wire protocol.

  Bits appear from the sensor as:

           Digital 0              Digital 1
  Vcc        ____                 ________
            |    |               |   ^    |
  Gnd   ____|    |__v__      ____|        |__
        50us 27us            50us  70us

  To read, wait for the input to switch from LOW to HIGH
  and wait for 35 microseconds.  At this point, a 0 digit will
  be at the or the low point for the next bit or mid-point of 
  the digital 1 signal,  This is looped 8 times.

  Bits are clocked in from bit 7 to bit 0.

  ---------------------------------------------------------------  */

int dhtReadByte(dhtPin)  {
  int i,rbyte = 0;
  pinMode(dhtPin,INPUT);  // Set the DHT_ pin as input
  for (i=0 ; i < 8 ; i++) {
    while(digitalRead(dhtPin) == LOW); // Wait for input to switch to HIGH
    delayMicroseconds(35); // Wait for digital 1 mid-point.
    if (digitalRead(dhtPin) == HIGH) {  //  We have a digital 1
      rbyte |= 1 << (7 - i); // Save the bit.
      while(digitalRead(dhtPin) == HIGH); // wait for HIGH to LOW switch (~ 35us).
    } // end if
  } // end for
  return rbyte;
}    


/* ----------------------------------------------------------------

  DHT_read() takes a reading from the DHT sensor and returns a success status.

  To take a reading we first send out a start signal and check for a response.  
  The timings are as follows:

          Request           Response from DHT
         from MPU     |< 40us><    80us   >< 40us>|
  Vcc    _      ______|              _____________|
          |    |      |             |      ^      |
  Gnd     |____|      |______|______|             |__
           20ms  30us      80us          80us    

  First set DHT pin to be an output, then drive output 
  LOW for 20us, then HIGH for 30us.

  Once the start signal has been sent, we must change the DHT pin 
  to be an input and wait 40us for the first mid-point, then 80us 
  for the second mid-point, followed by a 40us wait for the actual 
  data to start.  

  If the two mid-points do not read as a zero followed by a one, 
  then the DHT is not present on the pin and the DHT_NOTCONNECTED 
  status is returned.

  Once checks are successful, we store five bytes from DHT as follows:

  Byte 1: The integer part of the humidity reading.
  Byte 2: The decimal part of the humidity reading (Always 0 on DHT).
  Byte 3: The integer part of the temperature reading.
  Byte 4: The decimal part of the temperature reading (Always 0 on DHT).
  Byte 5: Checksum data

  The checksum is the sum of the lower 8 bits of bytes 1-4.

  Data can be displayed as (Integer part).(Decimal part)
  For simple calculations, only the integer part is typically required.

 -------------------------------------------------------------------  */
void dhtRead(dhtPin) {
    int c,chk1,chk2 = 0;
    int DHT_Array[5]; // local array to hold the 5 DHT_ bytes.
    pinMode(dhtPin, OUTPUT); // Set DHT_ pin as output.
    digitalWrite(dhtPin, LOW); // Drive DHT_ pin LOW to commence start signal
    delay(20); // Wait for 20 miliseconds
    digitalWrite(dhtPin,HIGH); // Drive DHT_ pin HIGH
    delayMicroseconds(30); // Wait 30 microseconds
    pinMode(dhtPin, INPUT); // Start signal sent, now change DHT_ pin to input.
    
    delayMicroseconds(40); // Wait 40us for mid-point of first response bit.
    chk1 = digitalRead(dhtPin); // Read bit.  Should be a zero.
    delayMicroseconds(80); // Wait 80us for the mid-point of the second bit.
    chk2 = digitalRead(dhtPin); // Read bit.  Should be a one.
    delayMicroseconds(40); // Wait 40us for end of response signal.
    
    if ((chk1 == 0) && (chk2 == 1)) { // If the response code is valid....
      for (c = 0 ; c < 5 ; c++) {
        DHT_Array[c] = dhtReadByte(dhtPin); // Read five bytes from DHT_
      }
        
      //  checksum is the sum of the lower 8 bits of bytes 1-4.
      if (DHT_Array[4] == ((DHT_Array[0] + DHT_Array[1] + DHT_Array[2] + DHT_Array[3]) & 0xFF)) {
      
        // Checksum passed, so place data into the DHT_register structure
        dht_register.int_humidity = DHT_Array[0];    // integer humidity
        dht_register.dec_humidity = DHT_Array[1];    // decimal humidity (0 on DHT11)
        dht_register.int_temperature = DHT_Array[2]; // integer temperature
        dht_register.dec_temperature = DHT_Array[3]; // decimal temperature (0 on DHT11)
        dht_register.checksum = DHT_Array[4];        // checksum result
        dht_register.status =  dht_success;          // success status
        return;                          // return success code.
      } else {
         dht_register.status = dht_notconnected;          // success status
        return;                     //  Sensor data corrupted.
      } // end if  
      
    } else {
      dht_register.status = dht_checksumfailed;          // success status
      return;                     // No DHT detected.
    } // end if  
}

/* +--------------------------------------------------------------------------+
   |                              Main Program                                |
   +--------------------------------------------------------------------------+  */
   
  float fahrenheit = 0;
  const int dhtPin  = 15; // pin to sensor data line
  
void setup() {
  CDC.printf("\r\nreading dht_ sensor on pin %d.\r\n", dhtPin);
}

void setup() {
  CDC.printf("\r\nreading dht sensor on pin %d.\r\n", dhtPin);
  pinMode(USERLED,OUTPUT);
}

void loop() {
  fahrenheit = (dht_register.int_temperature + (dht_register.dec_temperature/100)) * 1.8 + 32.0; 
  toggle(USERLED);                                  // blink the led
  delay(2000);                                      // min read is once per sec
  toggle(USERLED);                                  // so read every 4 secs
  delay(2000);                                      // to reduce errors
  dhtRead(dhtPin);
  
  if (dht_register.status == dht_success )   { // check status for read success
    CDC.printf("  humidity: %d.%d%%\r\n  temp:     %d.%dC  (%fF)\r\n\r\n", 
    dht_register.int_humidity, 
    dht_register.dec_humidity, 
    dht_register.int_temperature, 
    dht_register.dec_temperature,
    fahrenheit);
  } else if (dht_register.status == dht_notconnected)   {
     CDC.printf("DHT sensor not found on pin(%d).\r\n", dhtPin);  
  } else if (dht_register.status == dht_checksumfailed)   {
     CDC.printf("Bad checksum, may need 10k resistor data to Vcc.\r\n", dhtPin);  
  } else {
     CDC.printf("Unknown DHT sensor error.\r\n");
  } // end if
}   // end loop

 

Code snippet #2

Plain text
/*-----------------------------------------------------
author:  Jan Zumwalt
date:    2016.01.14
build:   tested on Olimex Pic32 Micro using Pinguino.cc IDE
description: 
  This is an adaptation of several Arduino programs. It will
  read a DHT temperature/humidity sensor. Tested with a dht_11, 
  but should work with dht_15 and dht_22. This example makes 
  no special demands on hardware, so should work with any 
  Pinguino board.
Note: Attempts to load this program as a library have failed.
      Expect an update once the problem is solved.
-----------------------------------------------------*/

const int dht_success        = 0;  // read success
const int dht_notconnected   = 1;  // dht not found
const int dht_checksumfailed = 2;  // dht data error

// define the structure to hold the returned data.
// this will only be filled out on a successful reading.
  
struct dht_data { // define dht register structure
  int int_humidity;
  int dec_humidity;
  int int_temperature;
  int dec_temperature;
  int checksum;
  int status; // 0=success, 1=not connected, 2=chksum error, 3=other
};

struct dht_data dht_register;        // Declare dht_register of type dht_data 

/* ---------------------------------------------------------------

  dhtReadByte() reads one byte using proprietary 1-wire protocol.

  Bits appear from the sensor as:

           Digital 0              Digital 1
  Vcc        ____                 ________
            |    |               |   ^    |
  Gnd   ____|    |__v__      ____|        |__
        50us 27us            50us  70us

  To read, wait for the input to switch from LOW to HIGH
  and wait for 35 microseconds.  At this point, a 0 digit will
  be at the or the low point for the next bit or mid-point of 
  the digital 1 signal,  This is looped 8 times.

  Bits are clocked in from bit 7 to bit 0.

  ---------------------------------------------------------------  */

int dhtReadByte(dhtPin)  {
  int i,rbyte = 0;
  pinMode(dhtPin,INPUT);  // Set the DHT_ pin as input
  for (i=0 ; i < 8 ; i++) {
    while(digitalRead(dhtPin) == LOW); // Wait for input to switch to HIGH
    delayMicroseconds(35); // Wait for digital 1 mid-point.
    if (digitalRead(dhtPin) == HIGH) {  //  We have a digital 1
      rbyte |= 1 << (7 - i); // Save the bit.
      while(digitalRead(dhtPin) == HIGH); // wait for HIGH to LOW switch (~ 35us).
    } // end if
  } // end for
  return rbyte;
}    


/* ----------------------------------------------------------------

  DHT_read() takes a reading from the DHT sensor and returns a success status.

  To take a reading we first send out a start signal and check for a response.  
  The timings are as follows:

          Request           Response from DHT
         from MPU     |< 40us><    80us   >< 40us>|
  Vcc    _      ______|              _____________|
          |    |      |             |      ^      |
  Gnd     |____|      |______|______|             |__
           20ms  30us      80us          80us    

  First set DHT pin to be an output, then drive output 
  LOW for 20us, then HIGH for 30us.

  Once the start signal has been sent, we must change the DHT pin 
  to be an input and wait 40us for the first mid-point, then 80us 
  for the second mid-point, followed by a 40us wait for the actual 
  data to start.  

  If the two mid-points do not read as a zero followed by a one, 
  then the DHT is not present on the pin and the DHT_NOTCONNECTED 
  status is returned.

  Once checks are successful, we store five bytes from DHT as follows:

  Byte 1: The integer part of the humidity reading.
  Byte 2: The decimal part of the humidity reading (Always 0 on DHT).
  Byte 3: The integer part of the temperature reading.
  Byte 4: The decimal part of the temperature reading (Always 0 on DHT).
  Byte 5: Checksum data

  The checksum is the sum of the lower 8 bits of bytes 1-4.

  Data can be displayed as (Integer part).(Decimal part)
  For simple calculations, only the integer part is typically required.

 -------------------------------------------------------------------  */
void dhtRead(dhtPin) {
    int c,chk1,chk2 = 0;
    int DHT_Array[5]; // local array to hold the 5 DHT_ bytes.
    pinMode(dhtPin, OUTPUT); // Set DHT_ pin as output.
    digitalWrite(dhtPin, LOW); // Drive DHT_ pin LOW to commence start signal
    delay(20); // Wait for 20 miliseconds
    digitalWrite(dhtPin,HIGH); // Drive DHT_ pin HIGH
    delayMicroseconds(30); // Wait 30 microseconds
    pinMode(dhtPin, INPUT); // Start signal sent, now change DHT_ pin to input.
    
    delayMicroseconds(40); // Wait 40us for mid-point of first response bit.
    chk1 = digitalRead(dhtPin); // Read bit.  Should be a zero.
    delayMicroseconds(80); // Wait 80us for the mid-point of the second bit.
    chk2 = digitalRead(dhtPin); // Read bit.  Should be a one.
    delayMicroseconds(40); // Wait 40us for end of response signal.
    
    if ((chk1 == 0) && (chk2 == 1)) { // If the response code is valid....
      for (c = 0 ; c < 5 ; c++) {
        DHT_Array[c] = dhtReadByte(dhtPin); // Read five bytes from DHT_
      }
        
      //  checksum is the sum of the lower 8 bits of bytes 1-4.
      if (DHT_Array[4] == ((DHT_Array[0] + DHT_Array[1] + DHT_Array[2] + DHT_Array[3]) & 0xFF)) {
      
        // Checksum passed, so place data into the DHT_register structure
        dht_register.int_humidity = DHT_Array[0];    // integer humidity
        dht_register.dec_humidity = DHT_Array[1];    // decimal humidity (0 on DHT11)
        dht_register.int_temperature = DHT_Array[2]; // integer temperature
        dht_register.dec_temperature = DHT_Array[3]; // decimal temperature (0 on DHT11)
        dht_register.checksum = DHT_Array[4];        // checksum result
        dht_register.status =  dht_success;          // success status
        return;                          // return success code.
      } else {
         dht_register.status = dht_notconnected;          // success status
        return;                     //  Sensor data corrupted.
      } // end if  
      
    } else {
      dht_register.status = dht_checksumfailed;          // success status
      return;                     // No DHT detected.
    } // end if  
}

/* +--------------------------------------------------------------------------+
   |                              Main Program                                |
   +--------------------------------------------------------------------------+  */
   
  float fahrenheit = 0;
  const int dhtPin  = 15; // pin to sensor data line
  
void setup() {
  CDC.printf("\r\nreading dht_ sensor on pin %d.\r\n", dhtPin);
}

void setup() {
  CDC.printf("\r\nreading dht sensor on pin %d.\r\n", dhtPin);
  pinMode(USERLED,OUTPUT);
}

void loop() {
  fahrenheit = (dht_register.int_temperature + (dht_register.dec_temperature/100)) * 1.8 + 32.0; 
  toggle(USERLED);                                  // blink the led
  delay(2000);                                      // min read is once per sec
  toggle(USERLED);                                  // so read every 4 secs
  delay(2000);                                      // to reduce errors
  dhtRead(dhtPin);
  
  if (dht_register.status == dht_success )   { // check status for read success
    CDC.printf("  humidity: %d.%d%%\r\n  temp:     %d.%dC  (%fF)\r\n\r\n", 
    dht_register.int_humidity, 
    dht_register.dec_humidity, 
    dht_register.int_temperature, 
    dht_register.dec_temperature,
    fahrenheit);
  } else if (dht_register.status == dht_notconnected)   {
     CDC.printf("DHT sensor not found on pin(%d).\r\n", dhtPin);  
  } else if (dht_register.status == dht_checksumfailed)   {
     CDC.printf("Bad checksum, may need 10k resistor data to Vcc.\r\n", dhtPin);  
  } else {
     CDC.printf("Unknown DHT sensor error.\r\n");
  } // end if
}   // end loop

 

Credits

Jan Zumwalt

Jan Zumwalt

9 projects • 14 followers
Retired aerospace engineer, aviation pilot, mechanic

Comments