this code works well for dht11 but for dht22 it shows checksum error in the range from 49-51%.
I tried to put it in a code #but there is a problem
Chip type : ATmega8
Program type : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#include mega8.h#include stdint.h#include stdio.h#include delay.h#include stdlib.h#define DHT22 //define DHT22 or DHT11#define DHT_PORT PORTD#define DHT_DDR DDRD#define DHT_PIN PIND#define DHT11_PIN 1// Alphanumeric LCD Module functions#include <alcd.h>uint8_t c=0,I_RH,D_RH,I_Temp,D_Temp,CheckSum;int q;float RH;unsignedchar data [5];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(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;}void main(void){
PORTB=0x00;
DDRB=0xFF;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0xFF;
lcd_init(16);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,1);
lcd_putsf("Error");}else{
lcd_gotoxy(0,0);
lcd_putsf("Humidity =");
lcd_gotoxy(0,10);#ifdef DHT22
RH=(float) I_RH *256.0+ D_RH ;
RH=RH/10.0;#else
RH = I_RH;#endif sprintf(data,"%.1f%% ",RH);
lcd_puts(data);}
delay_ms(2000);}}
In some cases, it is necessary to invert the calculated value and add 1 (or alternatively, add a minus signal); moreover, the method you are using do not seem a good choice, once you are not checking when the calculated value equals to the one received, but you are checking if it differs. I presume you should have to do something like this: