• 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.

Dht22 programing

Thread starter #1
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);
    }   
}
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
#2
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..
 

Pommie

Well-Known Member
Most Helpful Member
#3
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.
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
#4
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.
He said it works, but the value is wrong..
 

Les Jones

Well-Known Member
#5
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.
 

Pommie

Well-Known Member
Most Helpful Member
#7
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.
 
Thread starter #8
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%
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
#10
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...
 
Thread starter #13
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:

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
#14
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..
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
#18
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...
 

EE World Online Articles

Loading

 
Top