Aprimorando um projeto - Termômetro com registro de temperatura mínima, máxima, atual e com arredondamento de valores lidos.

Antes de iniciar está leitura recomendo que leiam os artigos anteriores especialmente estes:
utilizando um display de LCD, leitura de temperatura exibindo resultado no computador e Leitura de temperatura exibindo resultado no LCD 

Faça a montagem da placa como mostrado no projeto de leitura de temperatura exibida no LCD,
este novo projeto somente implementa novas funções ao antigo e no final citará algumas dicas para tornar este projeto algo ainda melhor, podendo até servir de base para algum trabalho de conclusão de curso técnico.


Função para arredondar um valor lido.


Dúvidas em relação ao uso de funções? recomendo o seguinte site: 
http://www.inf.pucrs.br/~pinho/LaproI/Funcoes/AulaDeFuncoes.htm (acessado no dia 05/07/2011)


Se quisermos mostrar valores dentro de uma faixa pré determinada podemos tratar os valores lidos pelo sensor e estipular uma regra de controle.
Enviamos um valor a função (parâmetro) este valor será do tipo float portanto utilizaremos do seguinte estratagema para calcular somente o valor fracional.

Vamos supor que o sensor envia o seguinte valor para a função "30,25"
Decalaramos uma variável temporária do tipo int para armazenar o valor de 30,25
como a váriavel é do tipo int ela ignorará o valor fracional.


float arredondado=30,25;
int temp_aux=0;
arredondado=30,25;
temp_aux=arredondado; 


Ao lermos o valor da variável temp_aux leremos somente 30
Então para calcular somente o valor fracional faremos arredonda-temp_aux que seria (30,25)-(30)=0,25



 float arredondamento(float arredonda)
  {
  int temp_aux=0;
  float temp_fracional=0;
  float temp_final=0;
  temp_aux=arredonda;
  temp_fracional=(arredonda-temp_aux);
     
  if (temp_fracional>=0.125 && temp_fracional<0.375)
    {
    temp_fracional=0.25;
    temp_final=(temp_aux+temp_fracional);
    return temp_final;
    }
}



O bloco IF acima testa se um valor é maior ou igual a 0,125 e menor que 0,375, se as duas condições forem satisfeitas a temperatura retornada terá um valor de 0,25 adicionada ao seu valor inteiro.



Exibindo valores mínimos e máximos no display LCD



Para exibir toda essa gama de valores precisaremos de um display de 20x4, caso você possua um display de somente duas linhas, altere o código para exibir somente os valores que desejar.

A grande pergunta que deve ser feita neste projeto é como descobrir e manter atualizado os valores mínimos e máximos de temperatura durante um período,  para realizar esse controle utilizaremos uma lógica condicional muito simples.
Primeiro devemos declarar duas variáveis que irão armazenar os valores máximos e mínimos definiremos um valor inicial para as mesmas que garantirão uma condição inicial verdadeira.
 

float temp_maxima=-150;  // valor muito BAIXO para condição de temp MAX
float temp_minima=300;  // valor muito ALTO para condição de temp MIN



Repare que as variáveis declaradas são do tipo float pois estas receberão valores reais fracionários dentro do laço de controle se a condição for verdadeira


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



 Bloco responsável por imprimir a temperatura mínima

   if (temp_minima>valor_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");
    }
 



O funcionamento deste bloco de código segue a mesma linha do anterior, temp_minima terá um valor inicial muito alto o que garantirá uma condição inicial verdadeira, todo o controle de impressão no LCD e de posicionamento está no bloco do if para somente ser executado quando uma condição verdadeira for detectada, garantindo maior velocidade ao programa.

 Repare que como declaramos temp_maxima com o valor de -150 a primeira condição sempre vai ser verdadeira, por ser verdadeiros o laço do IF será executado e a variável temp_máxima receberá o primeiro valor enviado pelo programa e nas próximas execuções irá atualizar o valor somente se temp_maxima<valor_arredondado.
 


Código fonte


#define sensor 0
#include <LiquidCrystal.h>
/* Biblioteca com funcoes para uso de um LCD baseado no Hitachi HD 44780 */
LiquidCrystal lcd(1, 0, 5, 4, 3, 2); // deve ser colocada fora do setup() para valer em todos os blocos do programa
/* Define os pinos de ligação do LCD ao arduino com esta ordem LiquidCrystal(rs, enable, d4, d5, d6, d7)  */

float temp_maxima=-150;  // valor muito BAIXO para condição de temp MAX
float temp_minima=300;  // valor muito ALTO para condição de temp MIN

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!");
 
  float le_temp(float x_sensor);
  float arredondamento(float arredonda);
  }

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
float temperatura_lida, valor_arredondado; 

// Bloco responsável por imprimir a temperatura atual
  temperatura_lida=le_temp(sensor); //chama a função le_temp() e passa como parametro a variavel sensor
  valor_arredondado = arredondamento(temperatura_lida); //chama a função arredondamento e passa como parametro temperatura_lida
  lcd.setCursor(0,1);
  lcd.print("Temp atual: " );
  lcd.print(valor_arredondado);
  lcd.write(0); // Imprime o caractere º
  lcd.print("C");

// Bloco responsavel por imprimir a temperatura maxima
   if (temp_maxima<valor_arredondado)
    {
    temp_maxima=valor_arredondado;
    lcd.setCursor(0,2);
    lcd.print("Temp max: " );
    lcd.print(temp_maxima);
    lcd.write(0); // Imprime o caractere º
    lcd.print("C");
    }

// Bloco responsavel por imprimir a temperatura mínima
   if (temp_minima>valor_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");
    }
}

float le_temp(float x_sensor)
  {
   float temperatura=0;
   float temperatura1=0;
   float temperatura2=0;
   float temperatura3=0;
   float temperatura4=0;
   float valor_lido=0;
     
    valor_lido=analogRead(x_sensor); /* Lê tensao do LM35 */
    temperatura1=(valor_lido*5*100)/1024; /* Conversao do valor lido */
    delay(50); /* Espera 100 mili segundos antes de prosseguir para a próxima medição*/
    valor_lido=analogRead(x_sensor); /* Lê tensao do LM35 */
    temperatura2=(valor_lido*5*100)/1024; /* Conversao do valor lido */
    delay(50); /* Espera 100 mili segundos antes de prosseguir para a próxima medição*/
    valor_lido=analogRead(x_sensor); /* Lê tensao do LM35 */
    temperatura3=(valor_lido*5*100)/1024; /* Conversão do valor lido */
    delay(50); /* Espera 100 mili segundos antes de prosseguir para a próxima medição*/
    valor_lido=analogRead(x_sensor); /* Lê tensao do LM35 */
    temperatura4=(valor_lido*5*100)/1024; /* Conversão do valor lido */
    temperatura=(temperatura1+temperatura2+temperatura3+temperatura4)/4;
    return temperatura;
  }
   
    /* Código responsável pelo arredondamento */
  float arredondamento(float arredonda)
  {
  int temp_aux=0;
  float temp_fracional=0;
  float temp_final=0;
  temp_aux=arredonda;
  temp_fracional=(arredonda-temp_aux);

  if (temp_fracional>=0 && temp_fracional<0.125)
    {
    temp_fracional=0.00;
    temp_final=(temp_aux+temp_fracional);
    return temp_final;
    }
   
  if (temp_fracional>=0.125 && temp_fracional<0.375)
    {
    temp_fracional=0.25;
    temp_final=(temp_aux+temp_fracional);
    return temp_final;
    }

  if (temp_fracional>=0.375 && temp_fracional<0.625)
    {
    temp_fracional=0.50;
    temp_final=(temp_aux+temp_fracional);
    return temp_final;
    }

  if (temp_fracional>=0.625 && temp_fracional<0.875)
    {
    temp_fracional=0.75;
    temp_final=(temp_aux+temp_fracional);
    return temp_final;
    }

  if (temp_fracional>=0.875 && temp_fracional<1)
    {
    temp_fracional=1;
    temp_final=(temp_aux+temp_fracional);
    return temp_final;
    }
  } 




Resultado final



Figura 1 - Display LCD 20x4 informando temperatura lida em um período.
 
Dicas para melhorar um projeto com termômetro.


Uma função adicional de fácil aplicação seria instalar um buzzer no arduino e disparar um alarme toda vez que uma temperatura pré determinada for atingida. Outra aplicação interessante mas um pouco mais complexa seria fazer um controlador de temperatura, onde se usaria uma resistência para gerar calor, existem duas maneiras simples de controlar a temperatura, a primeira seria controle ON/OFF e a segunda controle por PWM, lembrando que o arduino possui pinos dedicados a essa função.

Interessado em entrar no mundo Arduino? Confira meus produtos no mercado livre:

http://produto.mercadolivre.com.br/MLB-231090632-arduino-duemilanove-microcontrolador-avr-_JM
http://produto.mercadolivre.com.br/MLB-231096670-sensor-de-fumaca-para-arduino-pic-avr-8051-_JM
http://produto.mercadolivre.com.br/MLB-231098016-matriz-de-led-8x8-para-arduino-pic-avr-8051-_JM