Problem with displaying reading from DHT22 using Atmega32A

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello. I'm trying use DHT22 display on LCD 20x04. I'm code on Atmel Studio 7. Why lcd always display "1.sensor error and 3. sensor error"? My checksum is wrong? This is my code. Please help me!

 

main.c

/*
 *	Include header files
 */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <avr/wdt.h>
#include "lcdpcf8574.h"
#include "dht.h"
/*
 *	Define Macros
 */
#define F_CPU				16000000UL

/*
 *	Global variables
 */
volatile unsigned char DataReceived;
volatile unsigned int NumberReceived;
volatile unsigned char Flag=0;
float temp, humid;
double watertemp;
int inttemp, intwatertemp, inthumid;
int dectemp, decwatertemp, dechumid;
uint16_t lumenint16;
char *strfltemp;
char *strflhumid;
char *strdbtemp;
char *strdbhumid;
char *strlumen;
char *strwater;
char *strwater2;
uint8_t array[8];

/*
 *	MAIN FUNCTION
 */
int main(void)
{
	strfltemp  = malloc(sizeof(*strfltemp));
	strflhumid = malloc(sizeof(*strflhumid));
	strdbtemp  = malloc(sizeof(*strdbtemp));
	strdbhumid = malloc(sizeof(*strdbhumid));

	// Initialize LCD Operation
	lcd_init(LCD_DISP_ON_CURSOR_BLINK);
	lcd_home();
	lcd_led(0); //set led
	lcd_gotoxy(7,0);
	lcd_puts("HELLO");
	_delay_ms(2000);
	lcd_clrscr();
	// Initialize USART Operation
	lcd_gotoxy(2,0);
	lcd_puts("Aquaponic System");
	lcd_gotoxy(8,1);
	lcd_puts("V1.0");
	bh1750_init();
	_delay_ms(2000);
	lcd_clrscr();

	while(1)
	{
		//Sensor_Function();
		/*
		 * DHT22
		 */
		if (dht_gettemperaturehumidity(&temp,&humid) != -1)
		{
			inttemp = temp;
			inthumid = humid;
			dectemp = (int)(temp*10)%10;
			dechumid = (int)(humid*10)%10;
			array[0] = temp;
			array[1] = dectemp;
			array[2] = humid;
			array[3] = dechumid;
			//array[0] = 1;
			itoa(inttemp,strfltemp,10);
			itoa(inthumid,strflhumid,10);
			itoa(dechumid, strdbhumid,10);
			itoa(dectemp, strdbtemp,10);
			lcd_gotoxy(1,0);
			lcd_puts("Temp  :");		lcd_puts(strfltemp);	lcd_puts(".");		lcd_puts(strdbtemp);	lcd_puts(" C  ");
			lcd_gotoxy(1,2);
			lcd_puts("Humid :");		lcd_puts(strflhumid);	lcd_puts(".");		lcd_puts(strdbhumid);	lcd_puts(" %  ");

		}
		else
		{
			array[0] = 0;
			array[1] = 0;
			array[2] = 0;
			array[3] = 0;
			lcd_gotoxy(1,0);
			lcd_puts("1. Sensor ERROR");
			lcd_gotoxy(1,2);
			lcd_puts("3. Sensor ERROR");
		}
	}
}

 dht.h

#ifndef DHT_H_
#define DHT_H_

#include <stdio.h>
#include <avr/io.h>

//setup port
#define DHT_DDR DDRB
#define DHT_PORT PORTB
#define DHT_PIN PINB
#define DHT_INPUTPIN PB0

//sensor type
#define DHT_DHT11 1
#define DHT_DHT22 2
#define DHT_TYPE DHT_DHT22

//enable decimal precision (float)
#if DHT_TYPE == DHT_DHT11
#define DHT_FLOAT 0
#elif DHT_TYPE == DHT_DHT22
#define DHT_FLOAT 1
#endif

//timeout retries
#define DHT_TIMEOUT 200

//functions
#if DHT_FLOAT == 1
extern int8_t dht_gettemperature(float *temperature);
extern int8_t dht_gethumidity(float *humidity);
extern int8_t dht_gettemperaturehumidity(float *temperature, float *humidity);
#elif DHT_FLOAT == 0
extern int8_t dht_gettemperature(int8_t *temperature);
extern int8_t dht_gethumidity(int8_t *humidity);
extern int8_t dht_gettemperaturehumidity(int8_t *temperature, int8_t *humidity);
#endif

#endif

dht.c

#include <stdio.h>
#include <string.h>
#include <avr/io.h>
#include <util/delay.h>

#include "dht.h"

/*
 * get data from sensor
 */
#if DHT_FLOAT == 1
int8_t dht_getdata(float *temperature, float *humidity) {
#elif DHT_FLOAT == 0
int8_t dht_getdata(int8_t *temperature, int8_t *humidity) {
#endif
	uint8_t bits[5];
	uint8_t i,j = 0;

	memset(bits, 0, sizeof(bits));

	//reset port
	DHT_DDR |= (1<<DHT_INPUTPIN); //output
	DHT_PORT |= (1<<DHT_INPUTPIN); //high
	_delay_ms(100);

	//send request
	DHT_PORT &= ~(1<<DHT_INPUTPIN); //low
	#if DHT_TYPE == DHT_DHT11
	_delay_ms(18);
	#elif DHT_TYPE == DHT_DHT22
	_delay_us(500);
	#endif
	DHT_PORT |= (1<<DHT_INPUTPIN); //high
	DHT_DDR &= ~(1<<DHT_INPUTPIN); //input
	_delay_us(40);

	//check start condition 1
	if((DHT_PIN & (1<<DHT_INPUTPIN))) {
		return -1;
	}
	_delay_us(80);
	//check start condition 2
	if(!(DHT_PIN & (1<<DHT_INPUTPIN))) {
		return -1;
	}
	_delay_us(80);

	//read the data
	uint16_t timeoutcounter = 0;
	for (j=0; j<5; j++) { //read 5 byte
		uint8_t result=0;
		for(i=0; i<8; i++) {//read every bit
			timeoutcounter = 0;
			while(!(DHT_PIN & (1<<DHT_INPUTPIN))) { //wait for an high input (non blocking)
				timeoutcounter++;
				if(timeoutcounter > DHT_TIMEOUT) {
					return -1; //timeout
				}
			}
			_delay_us(30);
			if(DHT_PIN & (1<<DHT_INPUTPIN)) //if input is high after 30 us, get result
				result |= (1<<(7-i));
			timeoutcounter = 0;
			while(DHT_PIN & (1<<DHT_INPUTPIN)) { //wait until input get low (non blocking)
				timeoutcounter++;
				if(timeoutcounter > DHT_TIMEOUT) {
					return -1; //timeout
				}
			}
		}
		bits[j] = result;
	}

	//reset port
	DHT_DDR |= (1<<DHT_INPUTPIN); //output
	DHT_PORT |= (1<<DHT_INPUTPIN); //low
	_delay_ms(100);

	//check checksum
	if ((uint8_t)(bits[0] + bits[1] + bits[2] + bits[3]) == bits[4]) {
		//return temperature and humidity
		#if DHT_TYPE == DHT_DHT11
		*temperature = bits[2];
		*humidity = bits[0];
		#elif DHT_TYPE == DHT_DHT22
		uint16_t rawhumidity = bits[0]<<8 | bits[1];
		uint16_t rawtemperature = bits[2]<<8 | bits[3];
		if(rawtemperature & 0x8000) {
			*temperature = (float)((rawtemperature & 0x7FFF) / 10.0) * -1.0;
		} else {
			*temperature = (float)(rawtemperature)/10.0;
		}
		*humidity = (float)(rawhumidity)/10.0;
		#endif
		return 0;
	}

	return -1;
}

/*
 * get temperature
 */
#if DHT_FLOAT == 1
int8_t dht_gettemperature(float *temperature) {
	float humidity = 0;
#elif DHT_FLOAT == 0
int8_t dht_gettemperature(int8_t *temperature) {
	int8_t humidity = 0;
#endif
	return dht_getdata(temperature, &humidity);
}

/*
 * get humidity
 */
#if DHT_FLOAT == 1
int8_t dht_gethumidity(float *humidity) {
	float temperature = 0;
#elif DHT_FLOAT == 0
int8_t dht_gethumidity(int8_t *humidity) {
	int8_t temperature = 0;
#endif
	return dht_getdata(&temperature, humidity);
}

/*
 * get temperature and humidity
 */
#if DHT_FLOAT == 1
int8_t dht_gettemperaturehumidity(float *temperature, float *humidity) {
#elif DHT_FLOAT == 0
	int8_t dht_gettemperaturehumidity(int8_t *temperature, int8_t *humidity) {
#endif
	return dht_getdata(temperature, humidity);
}

Sorry for my bad english.

Thanks for reply!

Last Edited: Mon. Mar 23, 2020 - 09:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have already hijacked an old thread on this:

 

https://www.avrfreaks.net/commen...

 

If you want that discussion to continue here, then post a link there!

 

HoangNhut wrote:
Why lcd always display "1.sensor error and 3. sensor error"?

What debugging have you done to find out what's happening?

 

You can see in your code where those messages are produced - so trace back to see what could cause them

 

https://www.avrfreaks.net/commen...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well I guess it's obvious but the reason it displays the errors is because this est is not "true":

		if (dht_gettemperaturehumidity(&temp,&humid) != -1)

So that routine must be returning -1. The -1 is because it reaches the end of dht_getdata(). To know why you would probably need a JTAG or to annotate the dht_getdata() with some debug routines writing to the LCD so you know how far it gets. My own guess is that it might be failing the CRC test at the end. But it's only a guess.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi awneil. Thank you!

Last Edited: Mon. Mar 23, 2020 - 02:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So do it, then.

 

Note that clawson has effectively repeated what has already been posted for you in the other thread.

 

That's the trouble with posting the same thing multiple times - you waste people's time repeating stuff because they didn't see the other place!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simplify your main function.   You only need one function to display an integer value as a human-readable string on your LCD.   

 

Your malloc(), char* , ... make life complicated.   And prone to error.

 

Likewise,  your dht.h functions look more complicated than they need to be.    But if someone else wrote them for you and they work,   don't alter them.    Just concentrate on the main program logic i.e. call the "read" function,   check if valid,   display the value(s)

 

David.

Last Edited: Mon. Mar 23, 2020 - 12:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for reply.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank David!

Last Edited: Mon. Mar 23, 2020 - 02:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You may be using an outdated version of the DHT.h library.   Or the DHT22 device is wired wrong.  Or there is no 10K pull-up resistor between the DHT22 data pin and Vcc.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Simonetta. You right. I was update library and now it build success.

Thank you so much.