Could you please help me port this UART program into a program for LCD?

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

I'm trying to connect a DHT-11 with an ATMega8. I'm not much proficient in this field, and just a passion-driven beginner. I can use the ADC well  now, but I'm still learning digital libraries and registries.

 

I'm searching for codes and libraries to use with DHT-11. The most promising I found is the David Gioroni's DHT-11 library. But unfortunately, in his code, the output of the DHT-11 is sent to UART. I need to display them on a 16x2 LCD.

 

I tried a lot for 3 days, but couldn't get it working.

 

Can you please help and edit the code?

 

This is the main code.

 

 

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

#include "dht/dht.h"

#define UART_BAUD_RATE 2400
#include "uart/uart.h"

int main(void)
{
	char printbuff[100];

	//init uart
	uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );

	//init interrupt
	sei();

	#if DHT_FLOAT == 0
	int8_t temperature = 0;
	int8_t humidity = 0;
	#elif DHT_FLOAT == 1
	float temperature = 0;
	float humidity = 0;
	#endif

	for (;;) {
		if(dht_gettemperaturehumidity(&temperature, &humidity) != -1) {

			#if DHT_FLOAT == 0
			itoa(temperature, printbuff, 10);
			#elif DHT_FLOAT == 1
			dtostrf(temperature, 3, 3, printbuff);
			#endif
			uart_puts("temperature: "); uart_puts(printbuff); uart_puts("C");uart_puts("\r\n");
			#if DHT_FLOAT == 0
			itoa(humidity, printbuff, 10);
			#elif DHT_FLOAT == 1
			dtostrf(humidity, 3, 3, printbuff);
			#endif
			uart_puts("humidity: "); uart_puts(printbuff); uart_puts("%RH");uart_puts("\r\n");

		} else {
			uart_puts("error"); uart_puts("\r\n");
		}

		uart_puts("\r\n");

		_delay_ms(1500);
	}
	
	return 0;
}

Thanks a bunch, in advance! laugh

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

what code do you have now that can output to the LCD display, irrespective of the DHT-11?

that is, take the DHT-11 out of the code, out of the picture. Get the LCD library w/example running.

Then integrate the DHT-11.

 

You may also want to shift gears, use the Aruduino world's code and libraries, as a newbie.

 

Last Edited: Sat. Jun 20, 2015 - 05:47 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for your reply. I do not actually use arduino as I usually do not reuse a machine once I get it to work. For example, I make a thermometer, and keep it in the greenhouse. I make a clock and keep it in my room. Buying Arduinos seems cost ineffective for this reason. But your suggestion is very appreciated. I'll buy an Arduino and learn these things.

I have the Fleury LCD library. The LCD is up and running.

But I can't get this code to work with DHT11.

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

I strongly advise that you buy an Arduino.    I bet that a Chinese UNO clone is cheaper than a raw ATmega8 chip.   It is certainly easier to use.

You can develop on the UNO and build the project on a Pro-Mini.

 

Regarding your port.    First off,  you simplify the original code:

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

#include "dht/dht.h"

#define UART_BAUD_RATE 2400
#include "uart/uart.h"

int main(void)
{
    char printbuff[100];
    uart_init(UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU));
    sei();   //init interrupt

    float temperature = 0;
    float humidity = 0;

    for (;;) {
        if (dht_gettemperaturehumidity(&temperature, &humidity) != -1) {
            dtostrf(temperature, 3, 3, printbuff);
            uart_puts("temperature: ");
            uart_puts(printbuff);
            uart_puts("C");
            uart_puts("\r\n");
            dtostrf(humidity, 3, 3, printbuff);
            uart_puts("humidity: ");
            uart_puts(printbuff);
            uart_puts("%RH");
            uart_puts("\r\n");
        } else {
            uart_puts("error");
            uart_puts("\r\n");
        }
        uart_puts("\r\n");
        _delay_ms(1500);
    }
}

i.e. remove extraneous #if blocks and unnecessary blank lines.    Then you can write the equivalent for the LCD (untested):

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

#include "dht/dht.h"
#include "lcd.h"

int main(void)
{
    char printbuff[100];
    lcd_init(LCD_DISP_ON);
    sei();   //init interrupt

    float temperature = 0;
    float humidity = 0;

    for (;;) {
        lcd_clrscr();
        if (dht_gettemperaturehumidity(&temperature, &humidity) != -1) {
            dtostrf(temperature, 3, 3, printbuff);
			lcd_puts("temp: ");
            lcd_puts(printbuff);
            lcd_puts("C");
            lcd_puts("\r\n");
            dtostrf(humidity, 3, 3, printbuff);
            lcd_puts("hum : ");
            lcd_puts(printbuff);
            lcd_puts("%RH");
            lcd_puts("\r\n");
        } else {
            lcd_puts("error");
            lcd_puts("\r\n");
        }
        lcd_puts("\r\n");
        _delay_ms(1500);
    }
}

Note that this relies on the LCD library understanding "\r\n"

In practice,   you would use lcd_gotoxy() and lcd_puts()

 

Seriously,   if you want to learn this hobby,   you need to put in some effort yourself.

 

David.

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

Thank you very much. How are you doing, sir? Thanks for all the help.

 

I did exactly this; replacing uart_puts to lcd_puts, but it was displaying "error" on the screen.

 

Now the code you have given me also displays "error" on the screen. 

 

I am thinking now, after your assurance of code, is the DHT-11 faulty?

 

 

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

I am guessing you are abandoning this thread then?

 

https://www.avrfreaks.net/forum/c...

 

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

It is printing "error" because the library function is returning -1
Note that I assumed that DHT_FLOAT is true. I presume that this macro is defined in "dht.h"
Most properly written library functions will return a good/bad status. At least your code is USING this return value.
David.

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

 

That code displays "error" when dht_gettemperaturehumidity() does not return -1. So surely this thread is nothing about UART or LCD but why that function is not returning -1?

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

I'm not abandoning. smiley This sleepless night was not enough to get this LM35 working, I guess.

 

I'm trying to design a dedicated ATMega16 board and planning to use its ADC. Shall update.

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

Why is the library function (not) returning -1?

 

Does this mean that the DHT is returning an integer value instead of float?

Last Edited: Sat. Jun 20, 2015 - 01:40 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How do we know?
Only you know what is in "dht.h"

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

dht.c:

 

/*
DHT Library 0x03

copyright (c) Davide Gironi, 2012

Released under GPLv3.
Please refer to LICENSE file for licensing information.
*/


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


 

dht.h

 

/*
DHT Library 0x03

copyright (c) Davide Gironi, 2012

Released under GPLv3.
Please refer to LICENSE file for licensing information.

References:
  - DHT-11 Library, by Charalampos Andrianakis on 18/12/11
*/


#ifndef DHT_H_
#define DHT_H_

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

//setup port
#define DHT_DDR DDRD
#define DHT_PORT PORTD
#define DHT_PIN PIND
#define DHT_INPUTPIN PD6

//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

 

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

Well, there you are. DHT_FLOAT is 0.
Hence the reduced program needs to use the integer version of the code.
Personally, I think it important to uncomplicate the code i e. Remove the conditionals.
Of course you can restore them afterwards, but at least you can understand what is going on.
IF you had posted "dht.h" or a link to the library, I would have made a better guess about DHT_FLOAT in the first place.

David.

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

Aah, thank you so much, David sir. There lies your awesomeness!

So if we change all float to int in the main C program, and keep the dht.h unchanged, would it work?

Or should I edit the dht.h?

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

I would simply edit my example code to take the integer version. i.e. int8_t instead of float. And itoa () instead of dstrtof ().
I really think that anyone over the age of 11 should be able to do this for himself. It is not rocket science.
l also reckon that you will probably understand Extreme Electronics projects. You have the advantage of being Indian. Non-Indians have minds that work differently !!!
OF course, if you still get -1 then we need to study your library code. But I would guess that Mr Girone would have debugged his code already.
David.

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

I wrote this and it shows 0,0 as temp, humidity values.

 

#include <stdio.h>
#include <stdlib.h>
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>


#include "dht.h"
#include "lcd.h"

int main(void)
{
	
	DHT_FLOAT == 0;
	
	char buffer[100];
	lcd_init(LCD_DISP_ON);
	sei();   //init interrupt

	int8_t temperature = 0;
	int8_t humidity = 0;
	
	_delay_ms(2000);

	
	while (1)
	
	{
		lcd_clrscr();
			
	dht_gettemperaturehumidity(&temperature, &humidity);
		
			itoa(temperature, buffer, 10);
			lcd_puts("temp: ");
			lcd_puts(buffer);
			lcd_puts("C");
			
		
			
			itoa(humidity, buffer, 10);
			lcd_puts("hum : ");
			lcd_puts(buffer);
			lcd_puts("%RH");
			
			_delay_ms(2000);
			
		}
			
		

		lcd_puts("Done");
}


 

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

Finally made it. But by ATmega328p and arduino boot loader. smiley

 

Arduino platform has a 10x less steep learning curve!

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

Ok. So what did you do? Just use an Arduino sketch or work out what to change in a C program?
Yes, the Arduino is an excellent platform for experimenting and prototyping. But you can still run a regular C or C++ program on the hardware.
Most importantly, anyone from any country in the world can try your program because almost everyone owns a UNO or PRO MINI.
Incidentally, I often "simulate" a Fleury LCD program on a Terminal by simply linking with a "lcd_uart.c" file.
Oh, and I have just received a DHT11 in the mail. So I can actually copy your hardware now.
David.

Last Edited: Thu. Jul 2, 2015 - 04:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's a great information about simulating the LCD program! Thank you.

 

Yes, so this is what I did; I downloaded the DHT library. The library came with an example attached. It's just a few lines of simple code. I opened the example's .INO file, changed the DHT and LCD pin settings according to my convenience, and the LCD was displaying the temperature and humidity in the first attempt.

 

In order to spice the setup up, I slapped in a DS3231 and a BMP180 on the I2C bus, spent a day trying to run two I2C devices simultaneously, and guess what came out of it.  smiley A chronometer cum weather station! wink

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



#include <Wire.h>
#include <LiquidCrystal.h>
#include "DHT.h"// specify use of Wire.h library.
#define DHTPIN A2   
#define DHTTYPE DHT11 
DHT dht(DHTPIN, DHTTYPE);

LiquidCrystal lcd(A0, A1, 9, 10, 11, 12);


void setup()

{

dht.begin();
lcd.begin(16, 2);

 

}

void loop()

{
 
int h = dht.readHumidity();
int t = dht.readTemperature();

lcd.clear();

lcd.setCursor(0,0);
lcd.print("Temp= ");
  lcd.print(t);
  lcd.print(" C");
  
  
lcd.setCursor(0,1);

  lcd.print("Rel Humidity= ");
  lcd.print(h);
 lcd.print(" %");
 
 

 delay(2000);
}
  

The Arduino Code for DHT11.

Last Edited: Fri. Jul 3, 2015 - 11:22 PM