Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

DHT11 and PIC code

Status
Not open for further replies.
Hi

DHT22
As far as I can tell they are much the same, the dht11 isn't as accurate as the DHT22. The one wire control seems to be identical.
 
Hello,
Please tell more about it!
I work in Pic micro mostly!
there is 40 bits, integral rh and other bits what they are for?

Communication Process: Serial Interface (Single-Wire Two-Way)
Single-bus data format is used for communication and synchronization between MCU and DHT11 sensor. One communication process is about 4ms.
Data consists of decimal and integral parts. A complete data transmission is 40bit, and the sensor sends higher data bit first.
Data format: 8bit integral RH data + 8bit decimal RH data + 8bit integral T data + 8bit decimal T data + 8bit check sum. If the data transmission is right, the check-sum should be the last 8bit of "8bit integral RH data + 8bit decimal RH data + 8bit integral T data + 8bit decimal T data".
 
OK, are you using Oshonsoft IDE? If so there isn't much difference between PIC and AVR versions of the program to read the DHT11/22.
I used Servoin to "catch" the positive going pulses with an 8 bit loop. Then I evaluated them for their length to see if they are 1 or 0, then worked out the Humidity/temperature.
I didn't use a 16 bit loop because Oshonsoft IDE doesn't seem to work with variables in the bit location for a Word. I.e. Word.j = x(j). Whereas Byte.j = x(j) does work.
I didn't bother with the check sum, that's only of importance where temperature/humidity is in a critical location, if it fails a warning can be given.

Do you want to work it out for yourself, or do you want me to list my program?
 
OK here it is, I also have a lcd version. If you want this I will upload it but without the comments included in the 7 segment LED version.

To make sense of this you will need the datasheets for DHT11/22 and Max7219/7221 as a reference. I'm assuming you know enough about the PIC micro you want to use, if not you will need the datasheet for that too.

Update May 7:
I have now completed the hardware for this project and as a result have noticed an error in the code.
Dewpoint units and tens were the wrong way around when sent to the 7 segment LED using SPI send.
The comment after each was correct so use this as a guide to fix it if you want to use 7Seg+Hum+Temp
After checking this I also made some changes to tidy up the code, there is now a subroutine for "tens" and "units".
Also if dewpoint is positive or Zero, a "d" is placed before the dewpoint temperature. d for dewpoint.
I tried t for temperature but it doesn't look right on the 7 segment.
LED test on and off duration increased to 250ms.
The 7 segment displays are wired differently to the ready built one I used to for initial testing. The latest version 7seg+Temp+Hum reflects this.
If you want to use the code, it may be necessary to change the LED Digit to suit your hardware.
LED codes changed to hex, making it easier to understand. E.g. 0x01 = d1, 0x08 = d8 etc

The data collection and processing from the sensor works perfectly.

Addon May12
If you are planning to use this program for dewpoint indication, read on.
The formula I used to calculate dew point is the simplest one I could find. Because Oshonsoft cannot easily handle Negative (-) numbers I did not do anything about it, working on the theory that if it's - temperature I'll need my dew heaters on!
I've just done a few experiments and there is an easy fix to the formula
After the line that calculates "dew" i.e. dew = tempin - ((100 - humin) / 5)
add
If sign = 0x01 Then dew = tempin + ((100 - humin) / 5)
It produces a reasonably accurate result.

Addon 16/9/2015
The formula I used to calculate dewpoint must be different to the one I used online.
As a result incorrect negative dewpoints were being displayed @ about 17C
I put the formula Td = T - ((100 - RH)/5.) into a spread sheet.
These settings (used to calculate when the dew point is negative with a positive air temp) solved the problem.
If humin > 50 And tempin < 10 Then hsign = 0x01
If humin > 60 And tempin < 7 Then hsign = 0x01
If humin > 70 And tempin < 5 Then hsign = 0x01
If humin > 80 And tempin < 3 Then hsign = 0x01
If humin > 90 And tempin < 1 Then hsign = 0x01
Update 30/11/16
I've just built an auto dew heater which also uses this code. Now that it's very cold I noticed some odd behaviour at low ambient (0 to 2C) causing the heaters to be switched off! After checking the code I realised that the problem was when ambient was less than ((100 - RH)/5.) The result should be negative dew point but negative values need to be handled separately.
The humin/tempin table above doesn't work.
Placing this code between the 2 formulae for dewpoint so far seems to solve the problem.

check = ((100 - humin) / 5)
If tempin < check Then
signd = 0x01
dew = ((100 - humin) / 5) - tempin
Endif


Remove the Humin/Tempin table
 

Attachments

  • 7Seg+Hum+Temp.bas
    4.4 KB · Views: 377
  • 7Seg+Temp+Hum.bas
    4.6 KB · Views: 336
Last edited:
How it is working i have book of pic16f877a ..
40 bits data right?


Last time I looked you were coding in C, so don't know why you are struggling with a Basic project.

If you simply google on "dht11 with Pic micro" there are lots of dht11 projects written in C with good explantions of how it works; here's just 3 I found straight away.
http://embedded-lab.com/blog/?p=4333
**broken link removed**
**broken link removed**
 
Last time I looked you were coding in C, so don't know why you are struggling with a Basic project.

If you simply google on "dht11 with Pic micro" there are lots of dht11 projects written in C with good explantions of how it works; here's just 3 I found straight away.
http://embedded-lab.com/blog/?p=4333
**broken link removed**
**broken link removed**
Here is the code want to display on 7 segment

C:
bit Data at RA0_bit;
sbit DataDir at TRISA0_bit;
char message1[] = "Temp = 00.0 C";
char message2[] = "RH   = 00.0 %";
unsigned short TOUT = 0, CheckSum, i;
unsigned short T_Byte1, T_Byte2, RH_Byte1, RH_Byte2;
void StartSignal(){
  DataDir = 0;     // Data port is output
  Data    = 0;
  Delay_ms(25);    // Low for at least 18us
  Data    = 1;
  Delay_us(30);    // High for 20-40 us
  DataDir = 1;     // Data port is input
}
unsigned short CheckResponse(){
  TOUT = 0;
  TMR2 = 0;
  T2CON.TMR2ON = 1;      // Start TMR2 while waiting for sensor response
  while(!Data &amp;&amp; !TOUT); // If there's no response within 256us, the Timer2 overflows
  if (TOUT) return 0;    // and exit
  else {
   TMR2 = 0;
   while(Data &amp;&amp; !TOUT);
   if (TOUT) return 0;
   else {
    T2CON.TMR2ON = 0;
    return 1;
   }
  }
}
unsigned short ReadByte(){
  unsigned short num = 0, t;
  DataDir = 1;
  for (i=0; i&lt;8; i++){
   while(!Data);
   TMR2 = 0;
   T2CON.TMR2ON = 1;  // Start TMR2 from 0 when a low to high data pulse
   while(Data);       // is detected, and wait until it falls low again.
   T2CON.TMR2ON = 0;  // Stop the TMR2 when the data pulse falls low.
   if(TMR2 &gt; 40) num |= 1&lt;&lt;(7-i);  // If time &gt; 40us, Data is 1
  }
  return num;
}
void interrupt(){
  if(PIR1.TMR2IF){
   TOUT = 1;
   T2CON.TMR2ON = 0; // stop timer
   PIR1.TMR2IF  = 0; // Clear TMR0 interrupt flag
  }
}
void main() {
  unsigned short check;
  TRISB = 0b00000000;
  PORTB = 0;
  TRISA = 0b00100001;
  CMCON = 7;
  INTCON.GIE = 1;    //Enable global interrupt
  INTCON.PEIE = 1;   //Enable peripheral interrupt
  // Configure Timer2 module
  PIE1.TMR2IE = 1;  // Enable Timer2 interrupt
  T2CON = 0;        // Prescaler 1:1, and Timer2 is off initially
  PIR1.TMR2IF =0;   // Clear TMR INT Flag bit
  TMR2 = 0;
  Lcd_Init();
  Lcd_Cmd(_Lcd_Clear);
  Lcd_Cmd(_LCD_CURSOR_OFF);
  do {
    Delay_ms(1000);
    StartSignal();
    check = CheckResponse();
    if (!check) {
     Lcd_Cmd(_Lcd_Clear);
     Lcd_Out(1, 1, "No response");
     Lcd_Out(2, 1, "from the sensor");
    }
    else{
     RH_Byte1 = ReadByte();
     RH_Byte2 = ReadByte();
     T_Byte1 = ReadByte();
     T_Byte2 = ReadByte();
     CheckSum = ReadByte();
     // Check for error in Data reception
     if (CheckSum == ((RH_Byte1 + RH_Byte2 + T_Byte1 + T_Byte2) &amp; 0xFF))
     {
      message1[7]  = T_Byte1/10 + 48;
      message1[8]  = T_Byte1%10 + 48;
      message1[10] = T_Byte2/10 + 48;
      message2[7]  = RH_Byte1/10 + 48;
      message2[8]  = RH_Byte1%10 + 48;
      message2[10] = RH_Byte2/10 + 48;
      message1[11] = 223;     // Degree symbol
      Lcd_Cmd(_Lcd_Clear);
      Lcd_Out(1, 1, message1);
      Lcd_Out(2, 1, message2);
      }
      else{
       Lcd_Cmd(_Lcd_Clear);
       Lcd_Out(1, 1, "Checksum Error!");
       Lcd_Out(2, 1, "Trying Again ...");
      }
    }
  }while(1);
}
 
Last time I looked you were coding in C, so don't know why you are struggling with a Basic project.

If you simply google on "dht11 with Pic micro" there are lots of dht11 projects written in C with good explantions of how it works; here's just 3 I found straight away.
http://embedded-lab.com/blog/?p=4333
**broken link removed**
**broken link removed**
Here is the code want to display on 7 segment .
Now lets talk about the signal conditions used by DHT11 for transmitting data. In order to send a bit of data, the sensor first pulls the line low for 50 μs and then raises it to high for 26-28 μs (for sending “0″), or for 70 μs (for sending “1”). So the width of the positive pulse carries information about 1 and 0.

At the end of the last transmitted bit, the sensor pulls the data line low for 50 μs and then releases it. It is now ready to receive another start signal from the MCU.


C:
bit Data at RA0_bit;
sbit DataDir at TRISA0_bit;
char message1[] = "Temp = 00.0 C";
char message2[] = "RH   = 00.0 %";
unsigned short TOUT = 0, CheckSum, i;
unsigned short T_Byte1, T_Byte2, RH_Byte1, RH_Byte2;
void StartSignal(){
  DataDir = 0;     // Data port is output
  Data    = 0;
  Delay_ms(25);    // Low for at least 18us
  Data    = 1;
  Delay_us(30);    // High for 20-40 us
  DataDir = 1;     // Data port is input
}
unsigned short CheckResponse(){
  TOUT = 0;
  TMR2 = 0;
  T2CON.TMR2ON = 1;      // Start TMR2 while waiting for sensor response
  while(!Data &amp;&amp; !TOUT); // If there's no response within 256us, the Timer2 overflows
  if (TOUT) return 0;    // and exit
  else {
   TMR2 = 0;
   while(Data &amp;&amp; !TOUT);
   if (TOUT) return 0;
   else {
    T2CON.TMR2ON = 0;
    return 1;
   }
  }
}
unsigned short ReadByte(){
  unsigned short num = 0, t;
  DataDir = 1;
  for (i=0; i&lt;8; i++){
   while(!Data);
   TMR2 = 0;
   T2CON.TMR2ON = 1;  // Start TMR2 from 0 when a low to high data pulse
   while(Data);       // is detected, and wait until it falls low again.
   T2CON.TMR2ON = 0;  // Stop the TMR2 when the data pulse falls low.
   if(TMR2 &gt; 40) num |= 1&lt;&lt;(7-i);  // If time &gt; 40us, Data is 1
  }
  return num;
}
void interrupt(){
  if(PIR1.TMR2IF){
   TOUT = 1;
   T2CON.TMR2ON = 0; // stop timer
   PIR1.TMR2IF  = 0; // Clear TMR0 interrupt flag
  }
}
void main() {
  unsigned short check;
  TRISB = 0b00000000;
  PORTB = 0;
  TRISA = 0b00100001;
  CMCON = 7;
  INTCON.GIE = 1;    //Enable global interrupt
  INTCON.PEIE = 1;   //Enable peripheral interrupt
  // Configure Timer2 module
  PIE1.TMR2IE = 1;  // Enable Timer2 interrupt
  T2CON = 0;        // Prescaler 1:1, and Timer2 is off initially
  PIR1.TMR2IF =0;   // Clear TMR INT Flag bit
  TMR2 = 0;
  Lcd_Init();
  Lcd_Cmd(_Lcd_Clear);
  Lcd_Cmd(_LCD_CURSOR_OFF);
  do {
    Delay_ms(1000);
    StartSignal();
    check = CheckResponse();
    if (!check) {
     Lcd_Cmd(_Lcd_Clear);
     Lcd_Out(1, 1, "No response");
     Lcd_Out(2, 1, "from the sensor");
    }
    else{
     RH_Byte1 = ReadByte();
     RH_Byte2 = ReadByte();
     T_Byte1 = ReadByte();
     T_Byte2 = ReadByte();
     CheckSum = ReadByte();
     // Check for error in Data reception
     if (CheckSum == ((RH_Byte1 + RH_Byte2 + T_Byte1 + T_Byte2) &amp; 0xFF))
     {
      message1[7]  = T_Byte1/10 + 48;
      message1[8]  = T_Byte1%10 + 48;
      message1[10] = T_Byte2/10 + 48;
      message2[7]  = RH_Byte1/10 + 48;
      message2[8]  = RH_Byte1%10 + 48;
      message2[10] = RH_Byte2/10 + 48;
      message1[11] = 223;     // Degree symbol
      Lcd_Cmd(_Lcd_Clear);
      Lcd_Out(1, 1, message1);
      Lcd_Out(2, 1, message2);
      }
      else{
       Lcd_Cmd(_Lcd_Clear);
       Lcd_Out(1, 1, "Checksum Error!");
       Lcd_Out(2, 1, "Trying Again ...");
      }
    }
  }while(1);
}
 
OK, are you using Oshonsoft IDE? If so there isn't much difference between PIC and AVR versions of the program to read the DHT11/22.
I used Servoin to "catch" the positive going pulses with an 8 bit loop. Then I evaluated them for their length to see if they are 1 or 0, then worked out the Humidity/temperature.
I didn't use a 16 bit loop because Oshonsoft IDE doesn't seem to work with variables in the bit location for a Word. I.e. Word.j = x(j). Whereas Byte.j = x(j) does work.
I didn't bother with the check sum, that's only of importance where temperature/humidity is in a critical location, if it fails a warning can be given.

Do you want to work it out for yourself, or do you want me to list my program?


Hello
I will do with oshon soft and intrsted indonating because without it u cant learn properly
 
Oshonsoft is mega cheap for what it provides... Vladimir has done a very good job and should charge a lot more for this software... 35 euro's for every licence..... Pic's, AVR's, Z80, 8085 with all the addons..... You'd be mad not to...
 
Status
Not open for further replies.

Latest threads

Back
Top