Ir ao conteúdo
  • Cadastre-se

Sensor de Temperatura e umidade + 8051 + LCD


Chrisler

Posts recomendados

Olá pessoal.

Bom, eu e meu grupo da faculdade estamos tentando desenvolver um projeto de um sensor de temperatura e umidade, usando o uC 8051, um display LCD 16x2 e um sensor. Este sensor se chama DC-SS500, o fabricante é Sure Electronics. O manual pode ser visto no link abaixo:

http://www.sure-electronics.net/download/down.php?name=DC-SS500_Ver1.0_EN.pdf

Com relação à parte de 'hardware', não temos muitos problemas. Segundo o professor, usaremos apenas os pinos TX, RX, Vcc e GND do sensor. A comunicação será serial com o 8051, através dos pinos TX/RX de cada um deles. O 8051 também deve enviar para o display uma linha escrito "TEMPERATURA", com o valor da temperatura na frente, e uma linha escrito "UMIDADE", com o valor da umidade.

Tudo será feito em linguagem C. Temos todas as rotinas para acionamento do display, comunicação serial etc. O problema maior está no envio/recebimento dos dados entre o sensor e o 8051. Sabe-se que o sensor solta todos os valores no padrão ASCII. O padrão de comunicação é 9600bps (em 8N1).

Baseando-se num fluxograma simplificado, após a declaração de todas as rotinas "pré-prontas" de display e comunicação serial, é preciso "pedir" ao sensor o valor que ele deve enviar (no caso, temos que pedir uma das variáveis, lê-la, depois pedir a outra e lê-la, ou seja, tem que ser feita a mesma coisa 2x, uma pra umidade e a outra pra temperatura), jogar tudo isso em variáveis, formatar esses dados pro display e recomeçar o processo.

O sensor sabe que é preciso enviar um dado quando recebe o comando "$sure humidity" (para umidade) ou "$sure temperature -c" (para temperatura, usaremos só graus Celsius). Os dados que ele envia estão assim no manual:

0XX%RH (sendo XX é o valor da umidade neste instante) ou 0XXCentigrade(XX é o valor da temperatura em Celsius neste instante).

As nossas maiores dúvidas estão na comunicação, tanto pra enviar o dado pro sensor, como o valor a ser retornado por ele. Ou seja, qual tratamento teremos que dar para esses dados. Quanto ao sinal de saída do sensor, fomos orientados a usar um vetor de chars (string) para ler bit a bit o que é enviado, ainda que, como está sendo feito separada a leitura de uma grandeza de outra, acredito que apenas o bit 1, 2 e 3 importam, já que o resto da string liberada pelo sensor só consta o nome da grandeza.

Quanto à string a ser enviada do 8051 pro sensor, temos dúvidas em como isso deve ser feito. Pegando uma parte do programa, fomos orientados em fazer algo perto do seguinte:

TRASMITE_TEMP ("$sure temperature");

void TRANSMITE_TEMP (char *c)

{ for (; *c !=0 ; c++)

{ WR_SERIAL (*c); }}

void WR_SERIAL (unsigned char c)

{ SBUF=c;

while (TI!=1); }

Isso estaria correto? Esta seria a nossa estrutura básica para que o 8051 envie para o sensor o "pedido" de temperatura, e para que ele libere no seu TX o valor medido no instante aplicado. Para umidade seria quase igual.

Se alguém já mexeu com algo semelhante, e puder mandar por e-mail o programa em C utilizado, seria de grande ajuda para poder comparar as coisas! Ou então fornecer sugestões, partes de programas etc, tudo seria de grande utilidade. E-mail: [email protected]

Obrigado a todos. :)

Link para o comentário
Compartilhar em outros sites

Salve, Chrisler.

Acredito que sim, que seu algoritmo esteja correto. Mas, da teoria à prática, só testando.

Não se esqueça que pra enviar uma string, que é o padrão que o seu sensor funciona, você, nesse caso, deve terminar a string manualmente na transmissão. O terminador de string na serial, é a junção dos caracteres 0D + 0A. Então, seu código poderia ficar assim:



void TRANSMITE_TEMP (char *c)
{
for (; *c !=0 ; c++)
{
WR_SERIAL (*c);
}

WR_SERIAL (0x0D);
WR_SERIAL (0x0A);
}

void WR_SERIAL (unsigned char c)
{
SBUF=c;
while (TI!=1);
}
TRASMITE_TEMP ("$sure temperature"); 

Eu estou procurando uns exemplos de serial que tem no meu livro e assim que eu encontrar eu disponibilizo aqui.

Uma dica, essa, do fórum: quando você for postar código, use o botão CODE no alto da janela de edição (o símbolo do jogo da velha), e coloque o seu código entre as tags. Apesar de não aparecer smiles no seu código, sem ele, o código é substituído por smiles, e ele tb mantêm a formatação e identação do código. Fica mais fácil de visualizar!

Achei. Pode baixar os exemplos daquí:

http://www.4shared.com/file/155250032/994d8904/exercicios.html

[]'s

Link para o comentário
Compartilhar em outros sites

Salve, Chrisler.

Acredito que sim, que seu algoritmo esteja correto. Mas, da teoria à prática, só testando.

Não se esqueça que pra enviar uma string, que é o padrão que o seu sensor funciona, você, nesse caso, deve terminar a string manualmente na transmissão. O terminador de string na serial, é a junção dos caracteres 0D + 0A. Então, seu código poderia ficar assim:



void TRANSMITE_TEMP (char *c)
{
for (; *c !=0 ; c++)
{
WR_SERIAL (*c);
}

WR_SERIAL (0x0D);
WR_SERIAL (0x0A);
}

void WR_SERIAL (unsigned char c)
{
SBUF=c;
while (TI!=1);
}
TRASMITE_TEMP ("$sure temperature"); 

Eu estou procurando uns exemplos de serial que tem no meu livro e assim que eu encontrar eu disponibilizo aqui.

Uma dica, essa, do fórum: quando você for postar código, use o botão CODE no alto da janela de edição (o símbolo do jogo da velha), e coloque o seu código entre as tags. Apesar de não aparecer smiles no seu código, sem ele, o código é substituído por smiles, e ele tb mantêm a formatação e identação do código. Fica mais fácil de visualizar!

Achei. Pode baixar os exemplos daquí:

http://www.4shared.com/file/155250032/994d8904/exercicios.html

[]'s

Opa! Valeu pelas informações cara!! Vou tentar fazer alguma coisa hoje a noite e enviar o código aqui pra vocês darem uma olhada... como não tenho experiência acredito que vocês poderão reconhecer erros com mais facilidade. Vou dar uma olhada nesse link também hora que chegar em casa.

valeu!! Muito obrigado.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

olá. veja como envio strings com sucesso via serial com um rdc1122 (clone amd)

//*******************************************
void sendbyte(unsigned char data)
{
SP0TR=data;
while((SP0SR&0x0004)==0) ;
}
//*************************
void printf(const char *s)
{
while(*s)
{
sendbyte(*s);
s++;
}
}
//*************************

pro 51 troque a função sendbyte pela tua

void WR_SERIAL (unsigned char c)
{ SBUF=c;
while (TI!=1); } //while(!TI)

assim criei meu próprio printf. alguns compiladores "gostam" + de "flash" do que "const". keil, hitech-c, iar, mikroc... faça tua escolha

bj

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

tudo bem querido. mas a proposta é apenas "enviar uma string" e aquilo que postei o faz. Na verdade veio de um ex ldc.c do compilador hitech-c. veja

/* write a string of chars to the LCD */
void
lcd_puts(const char * s)
{
LCD_RS = 1; // write characters
while(*s)
lcd_write(*s++);
}

bastou trocar o lcd_write() pelo equiv uart. Alguns compiladores como o codevision usa-se flash no lugar de const subtendendo-se que (a grosso modo) a string é gravada na flash poupando a ram. Mas isso não nos vai agregar valor nenhum. Sugiro...

Bom, voltando ao dilema do minino tente-se fazer:

printf("$sure temperature"); 
printf("$sure humidity" );

pra ver o que acontece.

Também compile dos 2 jeitos e ver qual ocupa + memória ram e rom e faça sua escolha. Me avise...também posso evoluir. Ninguém é tão sábio que não tenha nada a aprender e nem tão ignorante que não a ensinar.

bj

Link para o comentário
Compartilhar em outros sites

Olá pessoal. Muito obrigado pelas dicas.

Fiz algumas alterações aqui e terinei o programa. Deve conter muitos erros, mas vou postar aqui para vocês darem uma olhada. Encaminhei ao meu professor também, que deve sanar algumas dúvidas básicas que perguntei.

Infelizmente meu conhecimento em C é muitíssimo limitado, aprendi há alguns anos o básico de C, mas não era voltado ao uso em microcontroladores, por isso tem muitas funções e rotinas que só estou aprendendo agora.

Fiz bastante comentários no programa, para tentar deixar um pouco mais claro. A tela limitada pela janela "código" vai cortar um pouco os comentários, e como esse quote não tem 'quebra', tem que ficar rolando a barra pra direita. Aí vai o programinha:



#include <AT89X52.h>

#define LCDCD P3_7 /*FUNÇÕES/*
#define LCDE P3_6 /*DO*/
#define LCDDATA P0 /*DISPLAY*/
#define LCD_LINE1 0x80 /*DE*/
#define LCD_LINE2 0xc0 /*LCD*/


/*=====================DECLARAÇÃO DAS ROTINAS E VARIÁVEIS====================*/

void INIT_SERIAL(void); /*ROTINA DE PREPARAÇÃO DA COMUNICAÇÃO SERIAL*/
void WR_SERIAL (unsigned char); /*ROTINA DE ESCRITA ATRAVÉS DA PORTA SERIAL*/
void RD_SERIAL (unsigned char); /*ROTINA DE LEITURA ATRAVÉS DA PORTA SERIAL*/

void TRANSMITE_TEMP (char *); /*FUNÇÃO QUE 'PEDE' A TEMPERATURA AO SENSOR*/
void TRANSMITE_HUMI (char *); /*FUNÇÃO QUE 'PEDE' A UMIDADE AO SENSOR*/

void RECEPCAO_TEMP (char *); /*FUNÇÃO QUE RETORNA A TEMPERATURA AO 8051*/
void RECEPCAO_HUMI (char *); /*FUNÇÃO QUE RETORNA A UMIDADE AO 8051*/

void INITLCD (void); /*ROTINA DE PREPARAÇÃO DO DISPLAY*/
void WRLCD (unsigned char); /*ROTINA DE PREPARAÇÃO DE ESCRITA NO LCD*/
void CMLCD (unsigned char); /*ROTINA DE COMANDO NO LCD*/
void WRITE (char *); /*ROTINA FINAL DE ESCRITA NO LCD*/
void CLR (void); /*ROTINA DE LIMPEZA DE TELA*/
void GOTOXY (unsigned char, unsigned char); /*ROTINA DE POSICIONAMENTO DE CURSOR*/
void TELA1(void); /*ROTINA DOS TEXTOS A SEREM ESCRITOS NO LCD*/


/*=============================ROTINAS E FUNÇÕES ============================*/

void INIT_SERIAL(void) /*ROTINA DE PREPARAÇÃO DA COMUNICAÇÃO SERIAL*/
{
SCON=0x52; /*SERIAL MODO 1, 8 bits, REN=1, TI=1*/
TMOD=0x20; /*TIMER1 MODO 2, 8 bits, RELOAD AUTOMATICO*/
TH1=0xFD; /*VELOCIDADE = 9600bps*/
TL1=TH1;
TR1=1; /*LIGA TIMER PARA GERAR BAUDRATE*/
}


void CMLCD (unsigned char CMD) /*ROTINA DE COMANDO NO LCD*/
{
unsigned char i;
LCDDATA = CMD;
LCDCD = 0;
LCDE = 1;
LCDE = 0;
for (i=150; i!=0; i--);
}

void WRLCD (unsigned char c) /*ROTINA DE PREPARAÇÃO DE ESCRITA NO LCD*/
{
char t;
LCDDATA = c;
LCDCD = 1;
LCDE = 1;
LCDE = 0;
for (t=10; t!=0; t--);
}

void WRITE (char *c) /*ROTINA FINAL DE ESCRITA NO LCD*/
{
for (; *c !=0 ; c++)
{ WRLCD (*c); }
}


void CLR (void) /*ROTINA PARA LIMPAR A TELA DO LCD*/
{
unsigned int i;
CMLCD (0x01);
for (i=0; i<0x150; i++);
}

void INITLCD (void) /*ROTINA DE LIGAÇÃO E CONFIGURAÇÃO INICIAL DO LCD*/
{
int t;
for (t=0x700; t!=0; t--);
CMLCD (0x38); /*2 linhas - 8 bits*/
for (t=0x700; t!=0; t--);
CMLCD (0x06); /*Desloca cursor p/ direita*/
for (t=0x700; t!=0; t--);
CMLCD (0x0E); /*Liga LCD e cursor*/
for (t=0x700; t!=0; t--);
CMLCD (0x01); /*Apaga LCD e volta o cursor para HOME*/
for (t=0x700; t!=0; t--);
}


/*==============TRANSMISSÃO DE DADOS DA TEMPERATURA - 8051 para SENSOR =================*/

TRASMITE_TEMP ("$sure temperature"); /*ROTINA DE 'PEDIDO' DE TEMPERATURA DO 8051 PRO SENSOR*/

void TRANSMITE_TEMP (char *c)
{
for (; *c !=0 ; c++)
{
WR_SERIAL (*c);
}

WR_SERIAL (0x0D); /*TERMINADORES DE STRING NECESSÁRIOS*/
WR_SERIAL (0x0A); /*NA COMUNICAÇÃO SERIAL -> 0D + 0A*/
}

void WR_SERIAL (unsigned char c)
{
SBUF=c;
while (TI!=1);
}

/*=============RECEPÇÃO DE DADOS DA TEMPERATURA - SENSOR para 8051=================*/

unsigned char BUFFER_TEMP=[13]; /*CHAR DE 13 POSIÇÕES PARA CAPTURAR A STRING 0xxCentigrade*/

void RECEPCAO_TEMP (char *cont)
{
for (; cont=12 ; cont++)
{
RD_SERIAL(*cont);
}
}

void RD_SERIAL(unsigned char cont)
{
SBUF=BUFFER_TEMP[cont];
while (TI!=1);
}

/*=============TRANSMISSÃO DE DADOS DA UMIDADE - 8051 para SENSOR =================*/

TRASMITE_HUMI ("$sure humidity"); /*ROTINA DE 'PEDIDO' DE UMIDADE DO 8051 PRO SENSOR*/

void TRANSMITE_HUMI (char *c)
{
for (; *c !=0 ; c++)
{
WR_SERIAL (*c);
}

WR_SERIAL (0x0D); /*TERMINADORES DE STRING NECESSÁRIOS*/
WR_SERIAL (0x0A); /*NA COMUNICAÇÃO SERIAL -> 0D + 0A*/
}

void WR_SERIAL (unsigned char c)
{
SBUF=c;
while (TI!=1);
}


/*=============RECEPÇÃO DE DADOS DA UMIDADE - SENSOR para 8051=================*/

unsigned char BUFFER_HUMI=[6]; /*CHAR DE 6 POSIÇÕES PARA CAPTURAR A STRING 0xx%RH*/

void RECEPCAO_HUMI (char *cont)
{
for (; cont=5 ; cont++)
{
RD_SERIAL(*cont);
}

}

void RD_SERIAL(unsigned char cont)
{
SBUF=BUFFER_HUMI[cont];
while (TI!=1);
}

/*================ROTINAS PARA ESCRITA E POSICIONAMENTO DE CURSOR===========*/

void GOTOXY (unsigned char x, unsigned char y) /*ROTINA DE POSICIONAMENTO DO CURSOR NO DISPLAY*/
{
x--;
switch(y)
{
case 1: CMLCD (LCD_LINE1+x); break;
case 2: CMLCD (LCD_LINE2+x); break;
}
}


void TELA1 (void) /*ROTINA DOS TEXTOS A SEREM ESCRITOS NO LCD*/
{
CLR();
WRITE("TEMPERATURA: "); /*ESCREVE A PALAVRA "TEMPERATURA" NO LCD*/
WRLCD(BUFFER_TEMP[0]); /*ESCREVE O PRIMEIRO CARACTER DA STRING DE TEMP. VINDA DO SENSOR*/
WRLCD(BUFFER_TEMP[1]); /*ESCREVE O SEGUNDO CARACTER DA STRING DE TEMP. VINDA DO SENSOR*/
WRLCD(BUFFER_TEMP[2]); /*ESCREVE O TERCEIRO CARACTER DA STRING DE TEMP. VINDA DO SENSOR*/
WRLCD('0xB0'); /*ESCREVE O CARACTER DO GRAU (" ° "), EM ASCII é 0xB0 (em hexadecimal)*/

GOTOXY (1,2); /*MOVER CURSOR PARA coluna 1 - linha 2 */

WRITE("UMIDADE: "); /*ESCREVE A PALAVRA 'UMIDADE' NO LCD*/
WRLCD(BUFFER_HUMI[0]); /*ESCREVE O PRIMEIRO CARACTER DA STRING DE UMIDADE VINDA DO SENSOR*/
WRLCD(BUFFER_HUMI[1]); /*ESCREVE O SEGUNDO CARACTER DA STRING DE UMIDADE VINDA DO SENSOR*/
WRLCD(BUFFER_HUMI[2]); /*ESCREVE O TERCEIRO CARACTER DA STRING DE UMIDADE VINDA DO SENSOR*/
WRLCD('0x25'); /*ESCREVE O CARACTER "%", EM ASCII é 0x25 (em hexadecimal)*/
}

/*COMENTÁRIO GERAL QUANTO ÀS STRINGS RECEBIDAS: só estão sendo escritos os 3 primeiros caracteres de cada string
recebida pelo 8051, que são os valores numéricos das grandezas que importam, o resto é lido também na comunicação serial, mas não é preciso escrever.*/


/*=========================MAIN(***####*INCOMPLETA)=========================*/
void main(void)
{
INIT_SERIAL(); /*CHAMA A ROTINA DE COMUNICAÇÃO SERIAL*/
TRANSMITE_TEMP();
RECEPCAO_TEMP();
TRANSMITE_HUMI();
RECEPCAO_HUMI();
INITLCD(); /*CHAMA A ROTINA DO DISPLAY*/

while(1)
{ CLR();
/*DÚVIDA!!!!*/ /*?????????É PRECISO CRIAR FUNÇÕES DE TEMPO ENTRE O CLR E A FUNÇÃO TELA1,
SE FOR USADA APENAS UMA "TELA" FIXA????*/
TELA1();
}
}

/*DÚVIDA = o que mais é preciso chamar na main??? */
/*=====INSTRUÇÕES PARA DEFINIÇÃO DO MODELO DO 8051 USADO E INSTRUÇÕES BÁSICAS DO LCD=====*/

Link para o comentário
Compartilhar em outros sites

  • 3 anos depois...

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!