27 de mai de 2011

Leitura de temperatura (termometro) com o arduino exibindo resultado no LCD

Antes de iniciar está leitura recomendo que leiam os artigos anteriores especialmente estes:

Os artigos acima são a base para integrar um LM35 (sensor de temperatura) com um display de LCD. Recomendo que em caso de dúvidas utilizem os comentários e na medida do possível irei respondê-las.

Para a realização deste projeto, será necessário algumas adaptações nos códigos, e algumas explicações adicionais, como por exemplo:
1) Imprimir um caractere personalizado no LCD.
2) Imprimir uma variável no LCD.
3) Redução os erros.

Imprimindo caracteres personalizados.

Em um display LCD se repararmos atentamente podemos ver que os caracteres são formados por pequenos pontos. Cada um desses pontos é organizado em "blocos" de 5 colunas por 8 linhas, em um display de 20x04
temos 20 "blocos" por linha ou um total de 80 "blocos".

 
Figura 1 - Display LCD de 20x04 com alto nível de contraste.
  
Figura 2 - Zoom em um bloco  

 Para darmos um acabamento mais profissional ao termômetro utilizaremos um recurso que nos permite criar um caractere customizado para indicarmos a temperatura em graus Celsius ( ºC )

Figura 3 - Caractere personalizado seguido da letra C. 

Para criarmos nosso caractere precisamos definir quais pontos ou pixels deixaremos ligados. Isto é facilmente implementado utilizando um vetor. O exemplo abaixo mostra como criar um bloco sólido isto é com todos os pixels ligados.
 
byte a[8]= 
{

B11111,

B11111,

B11111,

B11111,

B11111,

B11111,

B11111,

B11111,
}

Repare que temos 8 linhas e cada linha é preenchida cinco vezes com números 1, isto soa familiar não?
O próximo passo é armazenar esse vetor em uma posição de memória para isto utilizaremos a seguinte função:
lcd.createchar(0,a);
 
 E para mostrarmos no display nosso caractere personalizado usaremos 

lcd.write(0);
Sendo 0 a posição de memória do caracter, se tivermos mais de um caracter personalizado devemos armazená-lo em outra posição. Existe um limite de 7 caracteres para os controladores de LCD mais comuns,
nuca se esqueça de respeitar esse limite  
               lcd.createchar(7,a);

Imprimindo uma variável no LCD.

Até agora somente escrevemos no LCD dados fixos que não se alteravam com o passar do tempo, este tipo de solução não irá nos satisfazer visto que sensores sempre estão captando variações no ambiente e atualizando sua saída de tensão , corrente, etc.

Para imprimir dados estáticos se utiliza a função lcd.print("Texto a ser impresso ");
Quando um valor se atualiza constantemente este deve ser armazenado em uma variável e esta deve ser impressa no LCD para isto declararemos uma variável e atribuiremos um valor a mesma.
float temperatura=0;
lcd.print(temperatura); // imprime no LCD o conteúdo da variável temperatura

Para aumentar a precisão do termômetro a variável temperatura foi declarado com o tipo float para permitir leitura e impressão de números fracionais.

Reduzindo os erros por software.

Para evitarmos mudanças repentinas durante a exibição da temperatura podemos ler por diversas vezes a temperatura e depois tirarmos uma média dos valores lidos e imprimir a média obtida. Outro ponto válido seria excluir o valor máximo e mínimo lidos e tirarmos a média dos restantes.

O último exemplo ficará para uma aplicação futura, mostrarei apenas o código para tirar a média dos valores.

    valor_lido=analogRead(sensor); /* Lê tensao do LM35 */
    temperatura1=(valor_lido*5*100)/1024; /* Conversao do valor lido */
    delay(100); /* Espera 100 mili segundos antes de prosseguir para a próxima medição*/
    valor_lido=analogRead(sensor); /* Lê tensao do LM35 */
    temperatura2=(valor_lido*5*100)/1024; /* Conversao do valor lido */
    delay(100); /* Espera 100 mili segundos antes de prosseguir para a próxima medição*/
    valor_lido=analogRead(sensor); /* Lê tensao do LM35 */
    temperatura3=(valor_lido*5*100)/1024; /* Conversao do valor lido */
    delay(100); /* Espera 100 mili segundos antes de prosseguir para a próxima medição*/
    valor_lido=analogRead(sensor); /* Lê tensao do LM35 */
    temperatura4=(valor_lido*5*100)/1024; /* Conversao do valor lido */
    temperatura=(temperatura1+temperatura2+temperatura3+temperatura4)/4;


Para  melhorar a visualização e entendimento do código é recomendado o uso de funções, nos próximos projetos farei uso desta caracteristica da linguagem C.

Montagem do circuito

A montagem segue o mesmo padrão dos artigos utilizando um display de LCD e leitura de temperatura. Porém combinaremos as duas.Para poupar o trabalho de consultar os artigos anteriores siga as imagens abaixo. Lembre-se de consultar o datasheet de seu Display LCD para conferir a compatibilade do seu módulo com o usado neste projeto.




O código

#define sensor 0
#include <LiquidCrystal.h>

 /* Biblioteca com funcoes para uso de um LCD baseado no Hitachi HD 44780 */
 LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 /* Define os pinos de ligacaoi do LCD ao arduino com esta ordem LiquidCrystal(rs, enable, d4, d5, d6, d7)  */

 float temperatura=0;
 float temperatura1=0;
 float temperatura2=0;
 float temperatura3=0;
 float temperatura4=0;
 float valor_lido=0;

void setup()
{
   /*lcd.begin(cols, rows) */
   lcd.begin(20, 4); /* Tipo de LCD usado no meu caso de 20 colunas por 4 linhas */
   lcd.setCursor(0, 0); /* O Cursor iniciara na coluna zero linha 0 */
   lcd.print("    Central AVR!");
  
     
}
void loop()
    {
    byte a[8] = {  B01110,  B01010,  B01010,  B001110,  B00000,    B00000,  B00000,  B00000}; // Caractete criado
    lcd.createChar(0,a); // define nosso caractere º como uma variável
       
    valor_lido=analogRead(sensor); /* Lê tensao do LM35 */
    temperatura1=(valor_lido*5*100)/1024; /* Conversao do valor lido */
    delay(100); /* Espera 100 mili segundos antes de prosseguir para a próxima medição*/
    valor_lido=analogRead(sensor); /* Lê tensao do LM35 */
    temperatura2=(valor_lido*5*100)/1024; /* Conversao do valor lido */
    delay(100); /* Espera 100 mili segundos antes de prosseguir para a próxima medição*/
    valor_lido=analogRead(sensor); /* Lê tensao do LM35 */
    temperatura3=(valor_lido*5*100)/1024; /* Conversao do valor lido */
    delay(100); /* Espera 100 mili segundos antes de prosseguir para a próxima medição*/
    valor_lido=analogRead(sensor); /* Lê tensao do LM35 */
    temperatura4=(valor_lido*5*100)/1024; /* Conversao do valor lido */
    temperatura=(temperatura1+temperatura2+temperatura3+temperatura4)/4;
   
    lcd.setCursor(0, 2); /* O Cursor iniciara na coluna zero linha 2 */
    lcd.print("Temperatura= ");
    lcd.print(temperatura); // imprime no LCD o conteúdo da variável temperatura
    lcd.write(0); // Imprime º na tela do LCD
    lcd.print("C");
    delay(600);
    }


O resultado final

 Figura 4 - Resultado Final


 Figura 5 - Sensor LM35DZ




Video 1 - Resultado Final

6 comentários:

  1. muito bom ! parabens ! eu estou a realizar um projecto de escola, e o meu projecto é praticamente a mesma coisa que este ! só que o meu, nao tem arduino, tenho apenas 2 atmega16, LCD 16x2, LM35DZ, LDR, ainda nao consegui meter aquilo a funcionar, não consigo ver a temperatura e luminosidade no meu lcd, enfim tenho de ter paciencia eheheh continuaçao de bom trabalho !

    ResponderExcluir
  2. O problema com a luminosidade deve ser por causa da ligação do potenciometro com o pino de contraste, de uma conferida na minha montagem de circuito. Quanto ao funcionamento do código com o atmega16 eu estou esperando chegar um conversor serial USB para lançar mais tutóriais para ele, caso precise tenho o código funcionando para 8051 bem comentado, o segredo é obedecer os tempos para enviar cada comando.

    ResponderExcluir
  3. Olá, você falou em excluir o valor máximo e mínimo lidos e tirar a média dos restantes, como seria este procedimento? obrigado

    ResponderExcluir
    Respostas
    1. Leia esse post para ter uma ideia melhor de como tratar esses dados
      http://centralavr.blogspot.com.br/2011/07/incrementando-um-projeto-termometro-com.html

      O processo não é complicado, o primeiro passo é ler a variável desejada diversas vezes, por exemplo posso ler 4 vezes a temperatura em um intervalo de 1 segundo, o importante é em casa leitura salvar o valor em uma variável diferente
      float temperatura1=0;
      float temperatura2=0;
      float temperatura3=0;
      float temperatura4=0;
      Após ler 4 vezes faça um bloco de comparação usando IF e descubra qual é o maior valor das 4 e após o menor valor das 4.
      some todas as 4 leituras e exclua o valor maximo e o valor minimo e divida por 2 e pronto =)

      Bloco responsável por imprimir a temperatura máxima
      if (temp_maximavalor_arredondado)
      {
      temp_minima=valor_arredondado;
      lcd.setCursor(0,3);
      lcd.print("Temp min: " );
      lcd.print(temp_minima);
      lcd.write(0); // Imprime o caractere º
      lcd.print(C");
      }

      Excluir
  4. Olá
    apareceu isso daqui quando mandei fazer up...
    Binary sketch size: 4950 bytes (of a 30720 byte maximum)
    avrdude: stk500_getsync(): not in sync: resp=0x00
    avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x51

    poderia me ajudar?

    desde já agradeço...
    Guilherme

    ResponderExcluir
  5. Procure o suporte do arduino, creio que pode ser um problema com drives ou cabo USB, tente reinstalar os drives do arduino e mudar a porta USB ou o cabo.

    ResponderExcluir