Dht22 programing

Status
Not open for further replies.

mah

Member
I used this code to read dht22 with atmega but it reads wrong valuea, could you tell me why
Code:
ATmega16_DHT11_Project_File.c
 *
 * http://www.electronicwings.com
 */

#include <avr/io.h>
#include <stdlib.h>
#include <stdio.h>
#include "LCD16x2_4bit.h"
#define DHT11_PIN 6
uint8_t c=0,I_RH,D_RH,I_Temp,D_Temp,CheckSum;

void Request()                /* Microcontroller send start pulse/request */
{
    DDRD |= (1<<DHT11_PIN);
    PORTD &= ~(1<<DHT11_PIN);    /* set to low pin */
    _delay_ms(20);            /* wait for 20ms */
    PORTD |= (1<<DHT11_PIN);    /* set to high pin */
}

void Response()                /* receive response from DHT11 */
{
    DDRD &= ~(1<<DHT11_PIN);
    while(PIND & (1<<DHT11_PIN));
    while((PIND & (1<<DHT11_PIN))==0);
    while(PIND & (1<<DHT11_PIN));
}

uint8_t Receive_data()            /* receive data */
{   
    for (int q=0; q<8; q++)
    {
        while((PIND & (1<<DHT11_PIN)) == 0);  /* check received bit 0 or 1 */
        _delay_us(30);
        if(PIND & (1<<DHT11_PIN))/* if high pulse is greater than 30ms */
        c = (c<<1)|(0x01);    /* then its logic HIGH */
        else            /* otherwise its logic LOW */
        c = (c<<1);
        while(PIND & (1<<DHT11_PIN));
    }
    return c;
}

int main(void)
{   
    char data[5];
    lcdinit();            /* Initialize LCD */
    lcd_clear();            /* Clear LCD */
    lcd_gotoxy(0,0);        /* Enter column and row position */
    lcd_print("Humidity =");
    lcd_gotoxy(0,1);
    lcd_print("Temp = ");
    
    while(1)
    {   
        Request();        /* send start pulse */
        Response();        /* receive response */
        I_RH=Receive_data();    /* store first eight bit in I_RH */
        D_RH=Receive_data();    /* store next eight bit in D_RH */
        I_Temp=Receive_data();    /* store next eight bit in I_Temp */
        D_Temp=Receive_data();    /* store next eight bit in D_Temp */
        CheckSum=Receive_data();/* store next eight bit in CheckSum */
        
        if ((I_RH + D_RH + I_Temp + D_Temp) != CheckSum)
        {
            lcd_gotoxy(0,0);
            lcd_print("Error");
        }
        
        else
        {   
            itoa(I_RH,data,10);
            lcd_gotoxy(11,0);
            lcd_print(data);
            lcd_print(".");
            
            itoa(D_RH,data,10);
            lcd_print(data);
            lcd_print("%");

            itoa(I_Temp,data,10);
            lcd_gotoxy(6,1);
            lcd_print(data);
            lcd_print(".");
            
            itoa(D_Temp,data,10);
            lcd_print(data);
            lcddata(0xDF);
            lcd_print("C ");
            
            itoa(CheckSum,data,10);
            lcd_print(data);
            lcd_print(" ");
        }
                
    _delay_ms(10);
    }   
}
 
Try the shift Before the test.. The way you read the device you are left with only 7 bits with a 0 in LSBit and the MSBit shifted out..
C:
uint8_t Receive_data()            /* receive data */
{ 
   c=0;
    for (int q=0; q<8; q++)
    {
       c<<=1;
        while((PIND & (1<<DHT11_PIN)) == 0);  /* check received bit 0 or 1 */
        _delay_us(30);
        if(PIND & (1<<DHT11_PIN))/* if high pulse is greater than 30ms */
        c +=1;    /* then its logic HIGH */

        while(PIND & (1<<DHT11_PIN));
    }
    return c;
}
Now you have all the bits..
 
It should still work the way the OP is doing it so it must be something else.
What is it saying on the LCD?

Mike.
 
If it is any help here is the code I use to read a DHT22. (This is on a PIC12F1840 using the internal 4Mhz oscillator.) Even if you don't follow the code the comments on the timing may help. I have had no problems using this timing.

Code:
;*Read DHT22
;* Result in DHT_Data  (5 bytes.)
;*
;*****************************************************************************  
;
     
Read_DHT:

; make data pin  output

       SELBANK 1               ; SET BANK 1        2 uS
    BCF    TRISA,2        ; Set DHT_Pin as output  1 uS
       SELBANK 0               ; SET BANK 0        2 uS

    BCF    DHT22_Pin            ; set it low for 18ms

; delay 6 ms
        movlw   LOW DELAY_6MS            ; Delay for 6 milliseconds  Normal value used
        movwf   param1                  ; 
        movlw   HIGH DELAY_6MS              ;  Normal value used
        movwf   param2                  ; 
        call    delay_cycles            ; 


; Set data line high for 30 us
    BSF    DHT22_Pin            ; 

; delay for 30 us
    movlw 0x09            ; 1 uS
    movwf Del_Count            ; 1 uS
Del_30us
    decfsz Del_Count, f        ; 1 uS while looping, 2 uS on exit
    goto Del_30us            ; 2 uS
    NOP

; Init bit counter
        MOVLW   D'40'
        MOVWF   bitcnt



; DHT22 now outputs data
; set data line for input
; Wait until it is low

       SELBANK 1               ; SET BANK 1        2 uS
    BSF    TRISA,2        ; Set DHT_Pin as input  1 uS
       SELBANK 0               ; SET BANK 0        2 uS

wait_responce_low:
        btfsc   DHT22_Pin        ; skip next inst if it is already low
        goto    wait_responce_low


; the DHT should next set the data line high for 80us
wait_responce_high
        btfss   DHT22_Pin
        goto    wait_responce_high


; now wait for it to go low again, marking the begining of the start bit
wait_bit_start:
        btfsc   DHT22_Pin
        goto    wait_bit_start
; start of bit -  50us low on the data line followed
; by 26-28 us high if is a "0" or a 70 us high if is a "1"
; So half way between is 49 uS

start_bit
; wait for the start bit to end
wait_high
        btfss   DHT22_Pin
        goto    wait_high

; delay for 49 us
    movlw 0x09        ; (1uS)                                1 uS
    movwf Del_Count        ;(1uS)                                2 uS
        bcf     STATUS, C    ;(1uS)    Set to 1 initially                    3 uS

Del_49us:
    decfsz Del_Count, f    ;(1uS) (2 uS on skip)                        4 uS  (Loop is 5 uS)
    goto No_timeout        ;(2 uS)                                6 uS
        bsf     STATUS, C    ; More than 40 uS have elapsed so clear carry bit. (1 uS)
No_timeout:
; Has data line gone low ? (End of bit.)

        btfsc   DHT22_Pin    ;(1uS) (2 uS on skip) Test for end of bit            7 uS
    goto     Del_49us        ;(2 uS)                            9 uS


;Shift carry bit into Bit 0    (We have 50 uS before start of next bit)
Shift_bit:
    RLF    DHT_Data4
    RLF    DHT_Data3
    RLF    DHT_Data2
    RLF    DHT_Data1
    RLF    DHT_Data0

dec_bit
        decfsz    bitcnt,f
       goto    wait_high      ;For next bit of frame.

Frame_End:
    RETURN


Les.
 
It helps if you give us an example of what a value should be, and what it actually reads as.
 
I'll ask again, what does the LCD say. Does it pass the checksum test?

Mike.
Edit, didn't realize the OP hasn't been back yet.
 
in simulation, it displays 1.245 % , when i change the humidity it change the tenths numbers and the full scale reading doesn't pass 2%
 
in simulation, it displays 1.245 % , when i change the humidity it change the tenths numbers and the full scale reading doesn't pass 2%

So do it properly, why would you imagine simulation is of any use?.
 
So do it properly, why would you imagine simulation is of any use?.
Sometimes it's easier to get the software right first.

That said... Show your schematic.... If you are using ISIS you will probably have the wrong resistor primitive...
 
yes, i am using ISIS, resistor is 10 kohm connected as datasheet
 

Attachments

  • Untitled.png
    30.3 KB · Views: 280
That's going to cause issues.. For digital simulation, you need a digital pullup
If you search "pullup" in the parts selector, you can use that instead..
 
do you mean that analog port can cause issues with this sensor?
note: i was working with dht11 which suddenly stopped working properly and read high or low value and stuck there, could that be the reason
 
Last edited:
I wish you would reveal the whole story.. Dribs and drabs of information isn't very helpful.

ISIS simulates noise and a 10k will produce noise ( more than for real ) You can of course remove transients from simulation, but why!! If you just used digital resistor primitives it'll make it simpler..
 
Sometimes it's easier to get the software right first.

And that's working so well isn't it?

There's tons of code out there for DHT sensors that works, all attempting to simulate it has done has produced 15 posts in a thread that never need have existed.
 
But the same resistor works with dht11.
I mean is there any diferrences between programming ov dht11 and dht22
 
But the same resistor works with dht11.
I mean is there any diferrences between programming ov dht11 and dht22
Software simulation doesn't just stop working... Something must have changed.. I was looking at the Arduino library for these things and the code is the same..

I used digital resistors because they work better in digital simulation... The models may be slightly different, they may have higher impedance or slightly differing registers... I haven't written code for this device so I cannot say...

note: i was working with dht11 which suddenly stopped working properly and read high or low value and stuck there, could that be the reason
This statement insinuates that the code has changed.. I would be looking at something else...
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…