Witam,
Przygotowuję właśnie projekt na studia i moim celem jest urządzenie oparte na ATmega służące do pomiaru temperatury i wilgotności. Napotkałem taki problem że DHT11 cały czas zwraca mi -1 dla tem oraz wilgotności. Czy ktoś się spotkał już z takim problemem? Wiem że jest to błąd podczas sprawdzania sumy kontrolnej ale niestety nie umiem się z tym uporać.
Będę wdzięczny za pomoc.
Troszeczkę szczegółów:
ATmega8 z wewnętrznym oscylatorem,
LCD HD44780:
RS PC0
RW PC1
E PC2
D4 PC3
D5 PC4
D6 PC2
D7 PC1
DHT11:
DATA: PC5
Kod programu:
Kod:
#include <stdio.h>
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//-------------------------------------------------------------------------------------------------
//
// Konfiguracja sygna??w steruj?cych wy?wietlaczem.
// Mo?na zmieni? stosownie do potrzeb.
//
//-------------------------------------------------------------------------------------------------
#define LCD_RS_DIR DDRC
#define LCD_RS_PORT PORTC
#define LCD_RS_PIN PINC
#define LCD_RS (1 << PC0)
#define LCD_RW_DIR DDRC
#define LCD_RW_PORT PORTC
#define LCD_RW_PIN PINC
#define LCD_RW (1 << PC1)
#define LCD_E_DIR DDRC
#define LCD_E_PORT PORTC
#define LCD_E_PIN PINC
#define LCD_E (1 << PC2)
#define LCD_DB4_DIR DDRC
#define LCD_DB4_PORT PORTC
#define LCD_DB4_PIN PINC
#define LCD_DB4 (1 << PC3)
#define LCD_DB5_DIR DDRC
#define LCD_DB5_PORT PORTC
#define LCD_DB5_PIN PINC
#define LCD_DB5 (1 << PC4)
#define LCD_DB6_DIR DDRB
#define LCD_DB6_PORT PORTB
#define LCD_DB6_PIN PINB
#define LCD_DB6 (1 << PB2)
#define LCD_DB7_DIR DDRB
#define LCD_DB7_PORT PORTB
#define LCD_DB7_PIN PINB
#define LCD_DB7 (1 << PB1)
//-------------------------------------------------------------------------------------------------
//
// Instrukcje kontrolera Hitachi HD44780
//
//-------------------------------------------------------------------------------------------------
#define HD44780_CLEAR 0x01
#define HD44780_HOME 0x02
#define HD44780_ENTRY_MODE 0x04
#define HD44780_EM_SHIFT_CURSOR 0
#define HD44780_EM_SHIFT_DISPLAY 1
#define HD44780_EM_DECREMENT 0
#define HD44780_EM_INCREMENT 2
#define HD44780_DISPLAY_ONOFF 0x08
#define HD44780_DISPLAY_OFF 0
#define HD44780_DISPLAY_ON 4
#define HD44780_CURSOR_OFF 0
#define HD44780_CURSOR_ON 2
#define HD44780_CURSOR_NOBLINK 0
#define HD44780_CURSOR_BLINK 1
#define HD44780_DISPLAY_CURSOR_SHIFT 0x10
#define HD44780_SHIFT_CURSOR 0
#define HD44780_SHIFT_DISPLAY 8
#define HD44780_SHIFT_LEFT 0
#define HD44780_SHIFT_RIGHT 4
#define HD44780_FUNCTION_SET 0x20
#define HD44780_FONT5x7 0
#define HD44780_FONT5x10 4
#define HD44780_ONE_LINE 0
#define HD44780_TWO_LINE 8
#define HD44780_4_BIT 0
#define HD44780_8_BIT 16
#define HD44780_CGRAM_SET 0x40
#define HD44780_DDRAM_SET 0x80
//-------------------------------------------------------------------------------------------------
//
// Deklaracje funkcji
//
//-------------------------------------------------------------------------------------------------
void LCD_WriteCommand(unsigned char);
unsigned char LCD_ReadStatus(void);
void LCD_WriteData(unsigned char);
unsigned char LCD_ReadData(void);
void LCD_WriteText(char *);
void LCD_GoTo(unsigned char, unsigned char);
void LCD_Clear(void);
void LCD_Home(void);
void LCD_Initalize(void);
//-------------------------------------------------------------------------------------------------
//
// Koniec pliku HD44780.h
//
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
// Wy?wietlacz alfanumeryczny ze sterownikiem HD44780
// Sterowanie w trybie 4-bitowym bez odczytu flagi zaj?to?ci
// z dowolnym przypisaniem sygna??w steruj?cych
// Plik : HD44780.c
// Mikrokontroler : Atmel AVR
// Kompilator : avr-gcc
// Autor : Rados?aw Kwiecie?
// ?r?d?o : http://radzio.dxp.pl/hd44780/
// Data : 24.03.2007
//-------------------------------------------------------------------------------------------------
//#include "HD44780.h"
//-------------------------------------------------------------------------------------------------
//
// Funkcja wystawiaj?ca p?bajt na magistral? danych
//
//-------------------------------------------------------------------------------------------------
void _LCD_OutNibble(unsigned char nibbleToWrite)
{
if(nibbleToWrite & 0x01)
LCD_DB4_PORT |= LCD_DB4;
else
LCD_DB4_PORT &= ~LCD_DB4;
if(nibbleToWrite & 0x02)
LCD_DB5_PORT |= LCD_DB5;
else
LCD_DB5_PORT &= ~LCD_DB5;
if(nibbleToWrite & 0x04)
LCD_DB6_PORT |= LCD_DB6;
else
LCD_DB6_PORT &= ~LCD_DB6;
if(nibbleToWrite & 0x08)
LCD_DB7_PORT |= LCD_DB7;
else
LCD_DB7_PORT &= ~LCD_DB7;
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja wystawiaj?ca p?bajt na magistral? danych
//
//-------------------------------------------------------------------------------------------------
unsigned char _LCD_InNibble(void)
{
unsigned char tmp = 0;
if(LCD_DB4_PIN & LCD_DB4)
tmp |= (1 << 0);
if(LCD_DB5_PIN & LCD_DB5)
tmp |= (1 << 1);
if(LCD_DB6_PIN & LCD_DB6)
tmp |= (1 << 2);
if(LCD_DB7_PIN & LCD_DB7)
tmp |= (1 << 3);
return tmp;
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja zapisu bajtu do wy?wietacza (bez rozr?nienia instrukcja/dane).
//
//-------------------------------------------------------------------------------------------------
void _LCD_Write(unsigned char dataToWrite)
{
LCD_DB4_DIR |= LCD_DB4;
LCD_DB5_DIR |= LCD_DB5;
LCD_DB6_DIR |= LCD_DB6;
LCD_DB7_DIR |= LCD_DB7;
LCD_RW_PORT &= ~LCD_RW;
LCD_E_PORT |= LCD_E;
_LCD_OutNibble(dataToWrite >> 4);
LCD_E_PORT &= ~LCD_E;
LCD_E_PORT |= LCD_E;
_LCD_OutNibble(dataToWrite);
LCD_E_PORT &= ~LCD_E;
while(LCD_ReadStatus()&0x80);
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja odczytu bajtu z wy?wietacza (bez rozr?nienia instrukcja/dane).
//
//-------------------------------------------------------------------------------------------------
unsigned char _LCD_Read(void)
{
unsigned char tmp = 0;
LCD_DB4_DIR &= ~LCD_DB4;
LCD_DB5_DIR &= ~LCD_DB5;
LCD_DB6_DIR &= ~LCD_DB6;
LCD_DB7_DIR &= ~LCD_DB7;
LCD_RW_PORT |= LCD_RW;
LCD_E_PORT |= LCD_E;
tmp |= (_LCD_InNibble() << 4);
LCD_E_PORT &= ~LCD_E;
LCD_E_PORT |= LCD_E;
tmp |= _LCD_InNibble();
LCD_E_PORT &= ~LCD_E;
return tmp;
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja zapisu rozkazu do wy?wietlacza
//
//-------------------------------------------------------------------------------------------------
void LCD_WriteCommand(unsigned char commandToWrite)
{
LCD_RS_PORT &= ~LCD_RS;
_LCD_Write(commandToWrite);
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja odczytu bajtu statusowego
//
//-------------------------------------------------------------------------------------------------
unsigned char LCD_ReadStatus(void)
{
LCD_RS_PORT &= ~LCD_RS;
return _LCD_Read();
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja zapisu danych do pami?ci wy?wietlacza
//
//-------------------------------------------------------------------------------------------------
void LCD_WriteData(unsigned char dataToWrite)
{
LCD_RS_PORT |= LCD_RS;
_LCD_Write(dataToWrite);
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja odczytu danych z pami?ci wy?wietlacza
//
//-------------------------------------------------------------------------------------------------
unsigned char LCD_ReadData(void)
{
LCD_RS_PORT |= LCD_RS;
return _LCD_Read();
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja wy?wietlenia napisu na wyswietlaczu.
//
//-------------------------------------------------------------------------------------------------
void LCD_WriteText(char * text)
{
while(*text)
LCD_WriteData(*text++);
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja ustawienia wsp?rz?dnych ekranowych
//
//-------------------------------------------------------------------------------------------------
void LCD_GoTo(unsigned char x, unsigned char y)
{
LCD_WriteCommand(HD44780_DDRAM_SET | (x + (0x40 * y)));
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja czyszczenia ekranu wy?wietlacza.
//
//-------------------------------------------------------------------------------------------------
void LCD_Clear(void)
{
LCD_WriteCommand(HD44780_CLEAR);
_delay_ms(2);
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja przywr?cenia pocz?tkowych wsp?rz?dnych wy?wietlacza.
//
//-------------------------------------------------------------------------------------------------
void LCD_Home(void)
{
LCD_WriteCommand(HD44780_HOME);
_delay_ms(2);
}
//-------------------------------------------------------------------------------------------------
//
// Procedura inicjalizacji kontrolera HD44780.
//
//-------------------------------------------------------------------------------------------------
void LCD_Initalize(void)
{
unsigned char i;
LCD_DB4_DIR |= LCD_DB4; // Konfiguracja kierunku pracy wyprowadze?
LCD_DB5_DIR |= LCD_DB5; //
LCD_DB6_DIR |= LCD_DB6; //
LCD_DB7_DIR |= LCD_DB7; //
LCD_E_DIR |= LCD_E; //
LCD_RS_DIR |= LCD_RS; //
LCD_RW_DIR |= LCD_RW; //
_delay_ms(15); // oczekiwanie na ustalibizowanie si? napiecia zasilajacego
LCD_RS_PORT &= ~LCD_RS; // wyzerowanie linii RS
LCD_E_PORT &= ~LCD_E; // wyzerowanie linii E
LCD_RW_PORT &= ~LCD_RW;
for(i = 0; i < 3; i++) // trzykrotne powt?rzenie bloku instrukcji
{
LCD_E_PORT |= LCD_E; // E = 1
_LCD_OutNibble(0x03); // tryb 8-bitowy
LCD_E_PORT &= ~LCD_E; // E = 0
_delay_ms(5); // czekaj 5ms
}
LCD_E_PORT |= LCD_E; // E = 1
_LCD_OutNibble(0x02); // tryb 4-bitowy
LCD_E_PORT &= ~LCD_E; // E = 0
_delay_ms(1); // czekaj 1ms
LCD_WriteCommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_4_BIT); // interfejs 4-bity, 2-linie, znak 5x7
LCD_WriteCommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_OFF); // wy??czenie wyswietlacza
LCD_WriteCommand(HD44780_CLEAR); // czyszczenie zawartos?i pamieci DDRAM
LCD_WriteCommand(HD44780_ENTRY_MODE | HD44780_EM_SHIFT_CURSOR | HD44780_EM_INCREMENT);// inkrementaja adresu i przesuwanie kursora
LCD_WriteCommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_ON | HD44780_CURSOR_OFF | HD44780_CURSOR_NOBLINK); // w??cz LCD, bez kursora i mrugania
}
/*
DHT11 Library 0x01
copyright (c) Davide Gironi, 2011
Released under GPLv3.
Please refer to LICENSE file for licensing information.
References:
- DHT-11 Library, by Charalampos Andrianakis on 18/12/11
*/
#include <stdio.h>
#include <avr/io.h>
//setup parameters
#define DHT11_DDR DDRC
#define DHT11_PORT PORTC
#define DHT11_PIN PINC
#define DHT11_INPUTPIN PC5
extern int8_t dht11_gettemperature();
extern int8_t dht11_gethumidity();
/*
DHT11 Library 0x01
copyright (c) Davide Gironi, 2011
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>
#define DHT11_ERROR 255
/*
* get data from dht11
*/
uint8_t dht11_getdata(uint8_t select) {
uint8_t bits[5];
uint8_t i,j = 0;
memset(bits, 0, sizeof(bits));
//reset port
DHT11_DDR |= (1<<DHT11_INPUTPIN); //output
DHT11_PORT |= (1<<DHT11_INPUTPIN); //high
_delay_ms(100);
//send request
DHT11_PORT &= ~(1<<DHT11_INPUTPIN); //low
_delay_ms(18);
DHT11_PORT |= (1<<DHT11_INPUTPIN); //high
_delay_us(1);
DHT11_DDR &= ~(1<<DHT11_INPUTPIN); //input
_delay_us(39);
//check start condition 1
if((DHT11_PIN & (1<<DHT11_INPUTPIN))) {
return DHT11_ERROR;
}
_delay_us(80);
//check start condition 2
if(!(DHT11_PIN & (1<<DHT11_INPUTPIN))) {
return DHT11_ERROR;
}
_delay_us(80);
//read the data
for (j=0; j<5; j++) { //read 5 byte
uint8_t result=0;
for(i=0; i<8; i++) {//read every bit
while(!(DHT11_PIN & (1<<DHT11_INPUTPIN))); //wait for an high input
_delay_us(30);
if(DHT11_PIN & (1<<DHT11_INPUTPIN)) //if input is high after 30 us, get result
result |= (1<<(7-i));
while(DHT11_PIN & (1<<DHT11_INPUTPIN)); //wait until input get low
}
bits[j] = result;
}
//reset port
DHT11_DDR |= (1<<DHT11_INPUTPIN); //output
DHT11_PORT |= (1<<DHT11_INPUTPIN); //low
_delay_ms(100);
//check checksum
if (bits[0] + bits[1] + bits[2] + bits[3] == bits[4]) {
if (select == 0) { //return temperature
return(bits[2]);
} else if(select == 1){ //return humidity
return(bits[0]);
}
}
return DHT11_ERROR;
}
/*
* get temperature (0..50C)
*/
int8_t dht11_gettemperature() {
uint8_t ret = dht11_getdata(0);
if(ret == DHT11_ERROR)
return -1;
else
return ret;
}
/*
* get humidity (20..90%)
*/
int8_t dht11_gethumidity() {
uint8_t ret = dht11_getdata(1);
if(ret == DHT11_ERROR)
return -1;
else
return ret;
}
int main(void)
{
char printbuff[100];
//init uart
//uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
//init interrupt
sei();
LCD_Initalize();
int8_t temperature = 0;
int8_t humidity = 0;
LCD_GoTo(0,0);
LCD_WriteText("Hello");
_delay_ms(100);
LCD_Clear();
while(1)
{
humidity = dht11_gethumidity();
temperature = dht11_gettemperature();
itoa(temperature, printbuff, 10);
//uart_puts(printbuff);
LCD_GoTo(0,0);
LCD_WriteText("Temp:");
LCD_GoTo(6,0);
LCD_WriteText(printbuff);
itoa(humidity, printbuff, 10);
//uart_puts(printbuff); uart_puts("\r\n");
LCD_GoTo(0,1);
LCD_WriteText("Wilg:");
LCD_GoTo(6,1);
LCD_WriteText(printbuff);
_delay_ms(1500);
}
return 0;
}