dht22 shows check sum error

Discussion in 'Embedded Systems and Microcontrollers' started by mah, Feb 14, 2019.

  1. mah

    Thread Starter Senior Member

    Mar 15, 2010
    337
    3
    this code works well for dht22 but it shows checksum error in the range from 49-51%.
    Code (C):
    1. /*****************************************************
    2. Chip type               : ATmega8
    3. Program type            : Application
    4. AVR Core Clock frequency: 8,000000 MHz
    5. Memory model            : Small
    6. External RAM size       : 0
    7. Data Stack size         : 256
    8. *****************************************************/
    9.  
    10. #include <mega8.h>
    11. #include <stdint.h>
    12. #include <stdio.h>
    13. #include <delay.h>
    14. #include <stdlib.h>
    15.  
    16. #define DHT22       //define DHT22 or DHT11
    17. #define DHT_PORT        PORTD
    18. #define DHT_DDR         DDRD
    19. #define DHT_PIN         PIND
    20. #define DHT11_PIN 1
    21.  
    22.  
    23.  
    24. // Alphanumeric LCD Module functions
    25. #include <alcd.h>
    26. uint8_t c=0,I_RH,D_RH,I_Temp,D_Temp,CheckSum;
    27. int q;
    28.      float RH;
    29.    unsigned char data [5];
    30.  
    31. void Request()                /* Microcontroller send start pulse/request */
    32. {
    33.     DDRD |= (1<<DHT11_PIN);
    34.     PORTD &= ~(1<<DHT11_PIN);    /* set to low pin */
    35.     delay_ms(20);            /* wait for 20ms */
    36.     PORTD |= (1<<DHT11_PIN);    /* set to high pin */
    37. }
    38.  
    39. void Response()                /* receive response from DHT11 */
    40. {
    41.     DDRD &= ~(1<<DHT11_PIN);
    42.     while(PIND & (1<<DHT11_PIN));
    43.     while((PIND & (1<<DHT11_PIN))==0);
    44.     while(PIND & (1<<DHT11_PIN));
    45. }
    46.  
    47. uint8_t Receive_data()            /* receive data */
    48. {  
    49.     for (q=0; q<8; q++)
    50.     {
    51.         while((PIND & (1<<DHT11_PIN)) == 0);  /* check received bit 0 or 1 */
    52.         delay_us(30);
    53.         if(PIND & (1<<DHT11_PIN))/* if high pulse is greater than 30ms */
    54.         c = (c<<1)|(0x01);    /* then its logic HIGH */
    55.         else            /* otherwise its logic LOW */
    56.         c = (c<<1);
    57.         while(PIND & (1<<DHT11_PIN));
    58.     }
    59.     return c;
    60. }
    61.  
    62.  
    63. void main(void)
    64. {
    65. PORTB=0x00;
    66. DDRB=0xFF;
    67.  
    68. PORTC=0x00;
    69. DDRC=0x00;
    70.  
    71. PORTD=0x00;
    72. DDRD=0xFF;
    73.  
    74. lcd_init(16);
    75.  
    76. while (1)
    77.       {
    78.        Request();        /* send start pulse */
    79.         Response();        /* receive response */
    80.         I_RH=Receive_data();    /* store first eight bit in I_RH */
    81.         D_RH=Receive_data();    /* store next eight bit in D_RH */
    82.         I_Temp=Receive_data();    /* store next eight bit in I_Temp */
    83.         D_Temp=Receive_data();    /* store next eight bit in D_Temp */
    84.         CheckSum=Receive_data();/* store next eight bit in CheckSum */
    85.      
    86.         if ((I_RH + D_RH + I_Temp + D_Temp) != CheckSum)
    87.         {
    88.             lcd_gotoxy(0,1);
    89.             lcd_putsf("Error");
    90.         }
    91.      
    92.         else
    93.         {
    94.        
    95.      
    96.               lcd_gotoxy(0,0);
    97.             lcd_putsf("Humidity =");
    98.             lcd_gotoxy(0,10);
    99.  
    100.            #ifdef DHT22
    101.             RH= (float) I_RH * 256.0 + D_RH ;
    102.             RH=RH/10.0;
    103.          
    104.             #else
    105.             RH =  I_RH;
    106.              #endif
    107.              sprintf(data,"%.1f%%  ",RH);
    108.            lcd_puts(data);
    109.  
    110.  
    111.             }
    112.                 delay_ms(2000);
    113.  
    114.             }
    115. }
     
    Last edited by a moderator: Feb 14, 2019
  2. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    8,113
    2,008
    Do you have a decoupling capacitor at the sensor power pins?
    How long is the cable to the sensor and is it near anything that could interfere with the signals (mains cables, SMPS...)?
     
  3. mah

    Thread Starter Senior Member

    Mar 15, 2010
    337
    3
    I am talking about simulation in ISIS.
    note: dht11 works well with same code for every point
     
  4. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    8,113
    2,008
    Ah! Then you need someone who knows what ISIS is.
     
  5. mah

    Thread Starter Senior Member

    Mar 15, 2010
    337
    3
    I mean proteus, is there any error in programming
     
  6. jayanthd

    Active Member

    Jul 4, 2015
    902
    79
    Zip and attach your complete project files including Proteus file. I will have a look at it.
     
    mah likes this.
  7. Raymond Genovese

    Well-Known Member

    Mar 5, 2016
    1,643
    990
    I understand that it is a simulation. What happens when you increase delay_us(30); to 40-45?

    [​IMG]
     
  8. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    7,815
    3,716
    Here is what the wonderful datasheet says:

    M2303sendouthigherdatabitfirstly!

    DATA=8bitintegralRHdata+8bitdecimalRHdata+8bitintegralTdata+8bitdecimalTdata+8bitcheck-sum

    If the data transmission is right,check-sum should be the last 8 bit of "8 bit integral RH data+8 bit decimal RH data+8 bit integral Tdata+8bitdecimal Tdata"
    .

    Whatever that means. ;) Are you certain you are receiving data as you expect? Does Proteus have a logic analyzer? If so I would put tit on the output of the sensor.

    Why does it seem I am the only one that can't afford to by Proteus? ;)
     
  9. mah

    Thread Starter Senior Member

    Mar 15, 2010
    337
    3
     
  10. mah

    Thread Starter Senior Member

    Mar 15, 2010
    337
    3
    nothing changed
     
  11. Raymond Genovese

    Well-Known Member

    Mar 5, 2016
    1,643
    990
    Oh well, I gave it a shot. I have worked with them numerous times on different computers using C and asm. I don't particularly like them, but never had any real trouble with them. Never used them in a simulation though.
     
  12. mah

    Thread Starter Senior Member

    Mar 15, 2010
    337
    3
    any help?
     
  13. Raymond Genovese

    Well-Known Member

    Mar 5, 2016
    1,643
    990
    Code (C):
    1.  
    2.         I_RH=Receive_data();    /* store first eight bit in I_RH */
    3.         D_RH=Receive_data();    /* store next eight bit in D_RH */
    4.         I_Temp=Receive_data();    /* store next eight bit in I_Temp */
    5.         D_Temp=Receive_data();    /* store next eight bit in D_Temp */
    6.         CheckSum=Receive_data();/* store next eight bit in CheckSum */
    7.      
    8.         if ((I_RH + D_RH + I_Temp + D_Temp) != CheckSum)
    9.         {
    10.             lcd_gotoxy(0,1);
    11.             lcd_putsf("Error");
    12.         }
    13.    
    That is not the way I have done the checksum in C - I have done it this way and without errors:
    Code (C):
    1.  
    2. /*
    3.  5 bytes of DHT data are as follows:
    4.  [0] RH integral
    5.  [1] RH decimal
    6.  [2] Temp integral
    7.  [3] Temp decimal
    8.  [4] checksum is the sum of all four bytes AND 255
    9.  */
    10.     // checksum
    11.      if (((DHTdata[0] + DHTdata[1] + DHTdata[2] + DHTdata[3]) & 255)
    12.          != DHTdata[4]) {
    13.        QM_PRINTF("  *** BAD CRC! ***  \n");
    14.      } else {
    15.        QM_PRINTF("  OK  \n");
    16.      }
    17.  
     
  14. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    7,815
    3,716

    Yes but if you read the cryptic datasheet that does not appear how it is done.
     
  15. Raymond Genovese

    Well-Known Member

    Mar 5, 2016
    1,643
    990
    There are only two kinds of datasheets for the DHT22, bad and worse. But, the way I am calculating the checksum in the C code fragment that I posted above (as well as MPASM code that I have written) is, I believe the correct way and is also consistent with the datasheet...

    DHT22 send out higher data bit firstly! DATA=8 bit integral RH data+8 bit decimal RH data+8 bit integral T data+8 bit decimal T data+8 bit check-sumIf the data transmission is right, check-sum should be the last 8 bit of "8 bit integral RH data+8 bit decimal RHdata+8 bit integral T data+8 bit decimal T data". from https://www.sparkfun.com/datasheets/Sensors/Temperature/DHT22.pdf

    " check-sum should be the last 8 bit of "8 bit integral RH data+8 bit decimal RHdata+8 bit integral T data+8 bit decimal T data" that means:

    (DHTdata[0] + DHTdata[1] + DHTdata[2] + DHTdata[3]) & 255) will = DHTdata[4] IF the checksum is good.


    How are you reading it?

    Now, I don't know ISIS or Proteus from Shinola, but I am pretty sure that the way I am doing the checksum for these is correct - still, I could be wrong.

    edited to correct typos and non-existing tags
     
  16. mah

    Thread Starter Senior Member

    Mar 15, 2010
    337
    3
    but, how do you explain that the same code works with dht11 without errors?
     
  17. Ian Rogers

    Well-Known Member

    Dec 12, 2012
    644
    177
    I was playing with this I wrote a pic version just play with... There are slight timing differences between DHT11 and DHT22.

    Remember! ISIS is too rigorous for real time... Digital simulation will have errors... If you have an Arduino to hand, build it for real, It'll probably be fine.
    On ETO I said the pullup resistor needs to be digital... I stand by this.. I tested my version and it doesn't show any CRC errors.
     
  18. Raymond Genovese

    Well-Known Member

    Mar 5, 2016
    1,643
    990
    Because, as I recall, the DHT11 does not use a decimal. So, the bytes for temp decimal and humidity decimal are always 0. So, when you sum all 4 bytes, two are zero and as long as the Temp integral and hum integral do not add up to more than 255, you will not over run 255.

    So, the mistake of leaving out the & 255 in the way you were calculating:
    if ((I_RH + D_RH + I_Temp + D_Temp) != CheckSum)
    does not cause an error.

    With the DHT22, the decimal bytes get added and when your sum is greater that 255, you end up compaing that sum with the transmitted checksum byte and they are not equal and you get the error.

    - follow?
     
    Last edited: Feb 17, 2019
  19. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    8,113
    2,008
    But that shouldn't matter. All the values that are read and the checksum are declared to be uint8_t so '& 255' should make no difference.
     
  20. Raymond Genovese

    Well-Known Member

    Mar 5, 2016
    1,643
    990
    That is a valid point and I also saw that, but it does make a difference - apparently (the OP has not actually said one way or the other). Maybe there is some sinister promotion/demotion going on with a 16 bit value to an 8 bit value.

    I would like to know also. In the code that I have written, I also use uint8_t but I also use &255, as per the datasheet.

    I may actually go test it, well, maybe, after my coffee :) (amazing the excuses I can use to avoid doing other kinds of work).
     
Loading...