Dht22 programing

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));
}

{
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 */
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
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
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
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
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.)
;*
;*****************************************************************************
;

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

dknguyen

Well-Known Member
It helps if you give us an example of what a value should be, and what it actually reads as.

Pommie

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

mah

Member
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%

Nigel Goodwin

Super Moderator
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?.

Ian Rogers

User Extraordinaire
Forum Supporter
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...

mah

Member
yes, i am using ISIS, resistor is 10 kohm connected as datasheet

Attachments

• 30.3 KB Views: 3

mah

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

Nigel Goodwin

Super Moderator
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.

mah

Member
But the same resistor works with dht11.
I mean is there any diferrences between programming ov dht11 and dht22

Nigel Goodwin

Super Moderator
But the same resistor works with dht11.
I mean is there any diferrences between programming ov dht11 and dht22
Some minor differences, nothing much - but try it on hardware, not a simulator.

Ian Rogers

User Extraordinaire
Forum Supporter
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...