arduino

Aprimorando um projeto – Termômetro com registro de  temperatura.

Aprimorando um projeto – Termômetro com registro de temperatura.

Aprimorando um projeto – Termômetro com registro de temperatura mínima e máxima

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 20×4, 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 20×4 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.

 

Posted by medigaco_wp in Arduino, 0 comments
Projeto básico – Utilizando um teclado com o arduino e exibindo o resultado em um display de LCD

Projeto básico – Utilizando um teclado com o arduino e exibindo o resultado em um display de LCD

 

Teclado

Teclados são dispositivos de entrada normalmente utilizados para realizar a interface do homem com a máquina. Os teclados matriciais como o usado neste projeto são os mais conhecidos devido a sua arquitetura simples e fácil integração com microcontroladores.
Figura 1 – Teclado matricial estilo membrana.

 

Lendo os dados enviados por um teclado
Existem vários métodos de se ler dados enviados por um teclado e estes basicamente se diferenciam pela maneira com que são conectados a um microcontrolador, mas a lógica permanece a mesma.

 

No micro controlador as colunas são definidas como pinos de entrada e as linhas como pinos de saída.

 

 Figura 2 – Detalhe das conexões de um teclado matricial.

Primeiro definimos as linhas como pinos de saída em nível alto (HIGH) e as colunas como pinos de entrada com nível baixo (LOW).
Para detectar qual tecla foi pressionada cada linha recebe individualmente nível lógico alto e todas as colunas recebem nível baixo, o micro controlador espera alguma mudança de estado nas colunas, se uma tecla foi pressionada o nível alto será enviado para a entrada do micro processador, pois as colunas foram definidas como pinos de entrada.
Para garantir níveis altos e baixos nos pinos de entrada do microcontrolador podemos utilizar resistores de pull-up ou pull-down.
 
 Figura 3 – Esquema de funcionamento individual.
 
Analisando a imagem acima, sabemos que não teremos tensão na coluna C1 pois ela está  ligada a uma resistência de 10K e ao terra, mas se pressionarmos a chave que interliga L1 com C1 teremos 5 volts em cima do resistor, estes 5 volts serão interpretados como lógica alta pelo arduino toda vez que a chave for pressionada.
 
Interface
 
Todas as linhas deverão ser conectadas diretamente ao arduino e as colunas devem ser ligadas a uma resistência aterrada como mostra a figura abaixo:
 
Figura 4 – Esquema de ligação simplificado
 
Infelizmente em um teclado comercial como o de membrana não é possível ver as conexões internas, portanto deveremos medir continuidade em todos os contatos de saída.
Fixa-se uma ponta do multímetro em um dos terminais e se pressiona uma tecla (mantenha a tecla pressionada) e coloque a outra ponta do multímetro em outro terminal. Veja se entre esses dois pinos há condutividade, se não houver coloque a segunda ponta do multímetro em outros terminais até confirmar condutividade. Fazendo isto você terá descoberto  a união entre uma linha e uma coluna, continue com este procedimento até descobrir todas as colunas e todas as linhas.
 
O teclado de 4 linhas por 3 colunas utilizado neste projeto terá um total  de 7 saídas, cada saída será ligada ao arduino através de um fio ou conexão, veja abaixo os resultados que encontrei depois da medição com o multímetro.
  • COLUNA 1 = Fio 4
  • COLUNA 2 = Fio 3
  • COLUNA 3 = Fio 2
  • LINHA 1 = Fio 1
  • LINHA 2 = Fio 5
  • LINHA 3 = Fio 6
  • LINHA 4 = Fio 7

 

Após descobrir a função de cada fio, vamos definir em quais pinos eles entraram no arduino:
 

 

#define col1 13 // Com resistor de pull down                                                                
#define col2 12 // Com resistor de pull down 
#define col3 6 // Com resistor de pull down 
#define l1 10
#define l2 9
#define l3 8
#define l4 7
 
 
Figura 5 – Esquema de ligação das colunas com os resistores. As linhas devem ser ligadas diretas no arduino.
 
 
 
O código
 

 

#include <LiquidCrystal.h>  // Biblioteca com funcoes para uso de um LCD baseado no Hitachi HD 44780 
LiquidCrystal lcd(1, 0, 5, 4, 3, 2);// Define os pinos de ligacao do LCD ao arduino com esta ordem LiquidCrystal(rs, enable, d4, d5, d6, d7)
#define col1 13 // Com resistor de pull down                                                                
#define col2 12 // Com resistor de pull down 
#define col3 6 // Com resistor de pull down 
#define l1 10 // Linha 1
#define l2 9
#define l3 8
#define l4 7 // Linha 4
 
void setup()
{
/*lcd.begin(cols, rows) */
lcd.begin(20, 4); /* Tipo de LCD usado no meu caso de 20 colunas por 4 linhas */
lcd.print(”    Central AVR!”);
   
// Declarando as colunas como INPUT, fios 4,3,2 do teclado
pinMode(col1,INPUT); /* Coluna 1, fio 4 */
pinMode(col2,INPUT); /* Coluna 2, fio 3 */
pinMode(col3,INPUT); /* Coluna 3, fio 2 */
 
// Declarando as linhas como OUTPUT fios 1,5,6,7 do teclado
pinMode(l1,OUTPUT); /* Linha 1, fio 1 */
pinMode(l2,OUTPUT);
pinMode(l3,OUTPUT); 
pinMode(l4,OUTPUT); /* Linha 4, fio 7 */  
}
 
void loop() 
{
int l[]={l1, l2, l3, l4}; // Array de 4 posições contendo os 4 pinos de linhas
int i=0;  
int k=0;
int tecla_apertada=0;
for (i=0; i<4; i++)
{
digitalWrite(l1,LOW); 
digitalWrite(l2,LOW);
digitalWrite(l3,LOW);
digitalWrite(l4,LOW);
digitalWrite(l[i],HIGH); // Torna uma linha alta por vez
   k=i*3; // Responsavel pela mudança de valores nas linhas após cada ciclo do for
  if(digitalRead(col1)==HIGH) // Se alguma tecla da coluna 1 for apertada executa o código abaixo
  {
    delay(10);
    tecla_apertada=k+1;
    lcd.setCursor(0, 1); /* O Cursor iniciara na coluna zero linha 3 */
    lcd.print(“Coluna 1: “);
    lcd.print(tecla_apertada);
    k=0; 
  }
 
  if(digitalRead(col2)==HIGH)
  {
    delay(10);
    tecla_apertada=k+2;
    lcd.setCursor(0, 2); /* O Cursor iniciara na coluna zero linha 3 */
    lcd.print(“Coluna 2: “);
    lcd.print(tecla_apertada); 
    k=0;
  }
 if(digitalRead(col3)==HIGH)
  {
    delay(10);
    tecla_apertada=k+3;
    lcd.setCursor(0, 3); // O Cursor iniciara na coluna zero linha 3 
    lcd.print(“Coluna 3: “);
    lcd.print(tecla_apertada);
    k=0; 
  }
}
 
}



Algumas explicações sobre o funcionamento do programa.

A parte mais “complexa” deste código reside no laço do for onde utilizei um array para organizar a mudança para lógica HIGH das linhas, lembrando que o mesmo deve ser feito individualmente.

for (i=0; i<4; i++)
{
digitalWrite(l1,LOW); 
digitalWrite(l2,LOW);
digitalWrite(l3,LOW);
digitalWrite(l4,LOW);
digitalWrite(l[i],HIGH); // Torna uma linha alta por vez
   k=i*3; // Responsavel pela mudança de valores nas linhas após cada ciclo do for
.
.
.
.
.

}


Supondo i=0 a condição do for será verdadeira e o código dentro do laço será executado, todas as linhas são setada em nível LOW e apenas a linha 1 será setada em nível HIGH pois i=0 e no array l[] posição zero temos l1.
 digitalWrite(l[0],HIGH); // Torna uma linha alta por vez

O código executará até o final das condições(IF) e se não não for pressionada nenhuma tecla novamente todas as linhas receberão nível lógico LOW e somente a linha 2 será setada em nivel HIGH pois i=1 e no array l[] posição um temos l2.
digitalWrite(l[1],HIGH); // Torna uma linha alta por vez

k=i*3 é uma jogada para retornar um valor condizente com a linha com lógica HIGH, novamente supondo  i=0 ou seja a primeira execução do for temos k=0*3 portanto k=0 se a primeira coluna foi acionada o valor a ser impresso será 1 pois tecla_apertada=k+1;
Supondo i=1 ou seja a segunda execução do for temos k=1*3 portanto k=3 se a terceira coluna foi acionada o valor a ser impresso será 6 pois  tecla_apertada=k+3;

 

 

Resultado final
 

Vídeo 1 – Exibindo as teclas apertadas e indicando suas respectivas colunas.

Posted by medigaco_wp in Arduino, 4 comments
Leitura de temperatura (termometro) com o arduino exibindo resultado no LCD

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 20×04
temos 20 “blocos” por linha ou um total de 80 “blocos”.
 
Figura 1 – Display LCD de 20×04 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
Posted by medigaco_wp in Arduino, 6 comments
Leitura de temperatura (termometro) com o arduino e comunicação serial

Leitura de temperatura (termometro) com o arduino e comunicação serial

[vc_row][vc_column][vc_column_text]

Construindo um termometro com um LM35 e enviando a temperatura lida a um computador.

Nos artigos anteriores observamos que o arduino é capaz de detectar tensões aplicadas nos seus pinos e informá-las através da função digitalRead().
Porém este tipo de indicação é binário ou seja somente nos indica nível alto (5V) ou nível baixo (0V). Existem outros tipos de aplicações que necessitam de mais precisão e nos mostram tensões com maior índice de variações. Os componentes que são capazes de transformar variações físicas do ambiente (temperatura, pressão, umidade) em grandezas que podemos interpretar facilmente (tensão e corrente) são chamados de sensores.

Para facilitar a coompreensão vamos analisar o funcionamento de um LDR (do inglês Light Dependent Resistor ou em português Resistor Dependente de Luz).
O LDR é um tipo de resistor cuja resistência varia conforme a intensidade de radiação eletromagnética do espectro visível (luz) que incide sobre ele.
Um LDR é um transdutor de entrada (sensor) que converte a luz em valores de resistência. É feito de sulfeto de cádmio (CdS) ou seleneto de cádmio (CdSe). Sua resistência diminui quando a luz é muito alta, e quando a luz é baixa, a resistência no LDR aumenta. Um multímetro pode ser usado para encontrar a resistência na escuridão ou na presença de luz intensa. Estes são os resultados típicos para um LDR padrão:
• Escuridão : resistência máxima, geralmente acima de 1M ohms.
• Luz muito brilhante : resistência mínima, aproximadamente 100 ohms.
O LDR é muito frequentemente utilizado nas chamadas fotocélulas que controlam o acendimento de poste de iluminação e luzes em residências. Também é utilizado em sensores foto-elétricos assim como foto-diodos. (fonte wikipedia http://pt.wikipedia.org/wiki/LDR)
Vimos que um LDR varia sua resistência de acordo com a quantidade de luz que incide sobre ele, se fizermos uma montagem utilizando uma resistência fixa em série com um LDR criamos um simples divisor de tensão como visto na figura abaixo:

Figura 1 – Divisor de tensão com um LDR.  http://www.feiradeciencias.com.br/sala15/15_05.asp acessado em 24/07/2011
Construindo um termometro com o arduino e um Sensor de temperatura.

Na parte inferior direita da placa do arduino encontramos 6 entradas analógicas:
A0, A1, A2, A3, A4 e A5. Trata-se de pinos especiais que podem nos dizer exatamente qual a tensão aplicada a eles, sendo que para ler essa tensão usaremos uma nova função chamada de analogRead().
Esta função retorna um número entre 0 e 1023, que representa uma voltagem entre 0V e 5V. Por exemplo se uma voltagem de 2,5V é aplicada a uma das entradas analógicas o valor retornado pela função é de 512.

No mundo físico, parâmetros como temperatura, força, pressão, umidade, velocidade entre outros são sinais analógicos. Essas grandezas físicas são convertidas em sinais elétricos, sendo que, para podermos trabalhar com esses dados com o auxilio de micro controladores, devemos converter esses sinais usando um conversor analógico digital (ADC) que é um componente eletrônico que converte sinais para uma forma discreta. Os conversores analógicos digitais são os dispositivos mais usados no mundo para a aquisição de dados.

O sensor LM35 DZ

O sensor LM35 é um sensor de precisão, fabricado pela National Semiconductor
(www.national.com), que apresenta uma saída de tensão linear relativa à temperatura em
que ele se encontrar no momento em que for alimentado por uma tensão, tendo em sua saída um sinal de 10mV para cada grau Celsius de temperatura, sendo assim, apresenta uma boa vantagem com relação aos demais sensores de temperatura calibrados em “KELVIN”, não necessitando nenhuma subtração de variáveis  para que se obtenha uma escala de temperatura em Graus Celsius.
O sensor LM35 é apresentado com vários  tipos de encapsulamentos, sendo o mais
comum o TO-92, que mais se parece com um  transistor, e oferece ótima relação custo
benefício, por ser o mais barato dos modelos e propiciar a mesma precisão dos demais. A
grande diversidade de encapsulamentos se  dá devido à alta gama de aplicações deste
integrado.

Figura 2 – Tipos de encapsulamento de um LM35.

Para uma variação de 1ºC o LM35 DZ gera uma tensão de saída de 10mV, se a temperatura ambiente for de 23ºC a saída do LM35 será de 0,23V ou 230mV (23*10mV).
O LM35DZ é capaz de indicar temperaturas de 0ºC a 100ºC este tipo de informação é importante pois ao trabalharmos com sensores e conversores analógicos para digitais (ADC) temos que saber o fim de escala isto é o último valor informado pelo sensor e sua tensão final de saída.
Neste caso o LM35 DZ se mostra de fácil entendimento pois 100ºC equivale a 1V (100*10mV), o ADC do arduino trabalha normalmente com um fundo de escala de 5V então teremos que nos ajustar para esse requisito, o que pode ser feito via software ou hardware.
O foco deste artigo é tomar sempre o caminho mais simples, portanto seguirei com o ajuste por software, mas darei uma dica sobre o ajuste por hardware, procure na internet ou na própria referência do arduino o ajuste de valor de referência do ADC.

Mais sobre o LM35 em http://hermes.ucs.br/ccet/demc/vjbrusam/inst/temp51.pdf acessado em 24/07/2011

Conversão de tensão em uma grandeza física TEMPERATURA.

O fundo de escala do LM35 DZ é de 100ºC ou 1V que é exatamente 5 vezes menor que a tensão de referência, portanto para termos uma leitura padrão faremos o valor lido vezes 5 vezes 100, e dividiremos o resultado por 1024 que é o número de retorno da função para termos um valor de retorno unitário. Assim corrigimos o fundo de escala e temos um valor de saída conhecido.

Agora vamos comprovar teoricamente a eficiência da conversão.
10mV é o passo unitário do sensor ou sua sensibilidade
5V é a tensão de referência do ADC que possui resolução de 10 bits (2^10 = 1024).
5V/1024 = 0,00488 que é a sensibilidade do ADC.

Para 1ºC temos:
valor lido = 10mV/0,00488 = 2,04 como esse resultado será armazenado em valor_lido uma variável do tipo int valor_lido será igual a 2.
Agora faremos os ajustes de fundo de escala e de conversão fisíca que se resume a uma simples multiplicação por 500 (5*100*valor_lido)

Resultado final

(Valor_lido *5 *100)/1024

(2*5*100)/1024 = 0,97ºC como nosso resultado sera apresentado como número inteiro teremos exibido 1ºC

Para 100ºC temos:
100ºC retorna o valor 1023 pela função analogRead; (que vai de 0 a 1023 no total 1024 passos )
como temos um valor 5 vezes menor devido a discrepância entre as referências teremos o seguinte
valor_lido= 1023/5 = 204,6

Agora aplicando a formula final:
(Valor_lido *5 *100)/1024
(1024*5*100)/1024 = 99,9ºC como nosso resultado sera apresentado como número inteiro teremos exibido 100ºC
Resolução de um ADC

A conversão D/A (digital / analógica) ou A/D (analógica / digital) gera ou utiliza um sinal digital composto por bits. A quantidade  de bits utilizada pela palavra digital na conversão determina o que é chamado de resolução. Quanto maior a resolução de uma interface, mais exata será sua percepção em relação aos sinais analógicos externos e mais precisa será sua representação digital.
De acordo com a ANALOG DEVICES resolução é o número de bits que o ADC utiliza para
representar o sinal analógico. Quanto maior a resolução, maior o número de divisões em que a faixa do sinal será representada, sendo assim quanto maior a resolução mais sensível é o ADC para as variações de tensão em uma mesma faixa de entrada e ganho. A menor variação de tensão detectável (também chamada de largura de código – code width) para um dispositivo de aquisição de dados  ideal é determinada por:

Menor variação de tensão detectável = faixa / (ganho*2resolução)
Considerando o ADC0808 com uma resolução de apenas 8 bits teremos apenas 256 passos, isso significa que o ADC só acusará mudanças de estado quando a tensão de entrada variar na ordem de 20mV.
Faixa / (ganho*2resolução) = 5V/2^8 = 20mV.
Agora considerando um ADC com 10 bits como o da linha de micro controladores da ATMEL série AVR (arduino), poderíamos notar diferenças de tensão na ordem de 5V/2^10= 5mV.
Abaixo podemos ver as características elétricas referentes a erros no ADC0808 (cito o ADC 0808 como um exemplo, visto que não é este o ADC dentro de um arduino)
Figura 3 – Características Elétricas ADC0808 (National Semiconductor  – Data sheet ADC0808 – Outubro de 1999).
Montagem do circuito
Figura 4 – Diagrama de montagem.
Exibindo o resultado

Para este artigo o resultado será exibido na tela de seu computador, a partir do protocolo de comunicação serial.
O arduino pode tanto receber comandos de um computador como também enviar. Para este objetivo iremos utilizar um objeto serial ( um objeto é uma coleção de habilidades que são postas juntas para a conveniência das pessoas que escrevem os códigos ou sketches).
Este objeto contém todo o código necessário para o envio/recebimento de dados.
A função para escrever dados serialmente é a Serial.println, mais informações sobre a mesma podem ser encontradas na pasta de referência do arduino.
Para habilitar a visualização dos dados envidos serialemtne pelo arduino, clique no ícone “Serial Monitor” e configure a taxa de transferência para 9600 baud.

Figura 5 – Tela de verificação de comunicação serial
O código:

#define sensor 0

int temperatura=0;
int valor_lido=0;

void setup()
{
Serial.begin(9600);
}
void loop(){
if (Serial.available())
{
valor_lido=analogRead(sensor);
temperatura=(valor_lido*5*100)/1024;
Serial.println((long)temperatura);
}
delay(1000);
}

O resultado Final

Para visualizar o valor lido clique no campo para entrada de dados do serial monitor e aperte ENTER, se tudo ocorreu perfeitamente um valor de temperatura será enviado pelo arduino, no meu caso em um dia chuvoso a temperatura lida foi de 21ºC

 

Figura 6 – Temperatura enviada pelo arduino.
 O código acima não é eficiente e muitas vezes pode até retornar valores totalmente confusos, pois as variáveis foram declaradas com o tipo INT. Ao se fazer isso se despreza parte dos resultados além de esta não ser uma prática recomendada de programação.
Fica a cargo do leitor a opção de corrigir o código (sim é muito fácil) e para aqueles que gostam de ler e querem ver tudo funcionando corretamente, leiam o próximo post onde farei a interface com um Display de LCD desta vez totalmente funcional.

[/vc_column_text][/vc_column][/vc_row]

Posted by medigaco_wp in Arduino, 0 comments
Utilizando um display de cristal líquido LCD com o arduino.

Utilizando um display de cristal líquido LCD com o arduino.

Teoria sobre LCD displays de cristal líquido.

 

Os LCD são formados por um material que se denomina cristal líquido. As moléculas desse material são distribuídas entre duas lâminas transparentes polarizadas. Essa polarização é orientada de maneira diferente nas duas lâminas, de forma que estas formem eixos polarizadores perpendiculares, como se formassem um ângulo de 90º. As moléculas de cristal líquido são capazes de orientar a luz.
A base da iluminação de um LCD é a luz fornecida por uma lâmpada CCFL ou um conjunto de LEDS. Nos displays monocromáticos, cada ponto da tela corresponde a um ponto da imagem.
Um pixel é a menor unidade de uma imagem, o número de pixels no display determina a resolução do LCD. 

 

LCD monocromático, Chinmayananda Das  – Monitor and Control of Greenhouse Environment
Os LCDs são amplamente usados em conjunto com micro controladores para mostrar a informação visualmente, os LCDs possuem uma tabela de caracteres ASCII e símbolos matemáticos em sua memória.
Display com back light azul – 20 colunas e 4 linhas
Caracteres padrões contidos na memória do LCD – (Data Sheet MGD2004D-FL-YBS)

Sinais Enviados para o LCD

O display requer três sinais de controle que devem ser enviados pelo micro controlador.
Enable (E) – Este sinal permite acessar o display através das instruções R/W e RS.
Quando enable tem nível lógico baixo o display ignora os sinais vindos de R/W e RS, quando enable tem nível lógico alto o display checa os estados desses dois controladores, e responde de acordo.
Read/Write (R/W) Ler e Escrever- Determina a direção em que os dados fluem entre o LCD e o micro controlador, quando R/W tem nível lógico baixo os dados enviados pelo micro controlador são escritos no LCD, quando R/W tem nível lógico alto os dados são lidos do LCD.
Register select (RS) Seletor de Registros – De acordo com os dados nesse controlador o display interpreta o tipo de dado que está sendo enviado pelo micro controlador.
Quando RS tem nível baixo uma instrução está sendo escrita no display, quando o nível é alto um caractere ou mais está sendo escrito.
E = 0 Acesso ao LCD desabilitado
  = 1 Acesso ao LCD habilitado
R/W = 0 Escrevendo dados no LCD
  = 1Lendo dados do LCD
RS= 0 Uma instrução foi enviada ao LCD
    = 1 Um caractere foi enviado ao LCD
Escrevendo dados no LCD
Enviar dados para o display requer alguns passos:
1) Setar o bit R/W bit como 0 (zero).
2) Setar o bit RS como 0 (zero) ou 1 (um) (instrução ou caractere).
3) Enviar dados para as linhas de dado.
4) Setar o bit E como 1 (um).
5) Setar o bit E como 0 (zero).
Lendo dados
1) Setar o bit R/W como 1 (um)
2) Setar o bit RS como 0 (zero) ou 1 (um) (instrução ou caractere).
3) Ler dados das linhas de dados
4) Setar o bit E como 1 (um).
5) Setar o bit E como 0 (zero).
 
Pinagem do LCD
Display  20×4 dimensões e pinagem (Data Sheet MGD2004D-FL-YBS – 26 de junho de 2006)
 

 

Display CD 20×4 – descrição dos pinos. (Data Sheet MGD2004D-FL-YBS – 26 de junho de 2006)
Inicialização do LCD
Antes de usar o display para nosso objetivo, ele deve ser inicializado via reset interno ou pelo envio de um conjunto de instruções. Como nosso projeto foi concebido com a idéia de conectar o display a um micro controlador, escolhemos a inicialização por instruções.
Inicializar um display LCD com instruções é um processo simples, abaixo temos um fluxograma que indica todos os passos.
Fluxograma de inicialização por instruções do Display LCD (Ajay Bhargav – http://www.8051projects.net/)
De acordo com o fluxograma podemos observar que o display LCD é inicializado conforme a seguinte seqüência
1)    Enviar o comando 0x30 – Usando a interface de 8 bits
2)    Esperar 20ms
3)    Enviar o comando 0x30 – Usando a interface de 8 bits
4)    Esperar 20ms
5)    Enviar o comando 0x30 – Usando a interface de 8 bits
6)    Esperar 20ms
7)    Enviar o conjunto de instruções.
8)    Enviar o comando 0x01 para limpar a tela
Definir o modo de incremento.


Interface com o Arduino
Prossiga montando seu circuito de acordo com o esquema abaixo.
LCD 16×2 ou 20×4 possuem físicamente os mesmos pinos, o que muda durante seu uso são as instruções enviadas aos mesmos e é claro o limite de linhas e colunas.
O potênciometro é utilizado para ajustar o contraste dos caracteres no display, o regule conforme seu próprio critério, as setas >> indicam para que pinos do arduino os pinos do LCD devem ser ligados, não se esqueça de verificar se o datasheet do seu LCD é compatível com o meu esquemático.
O código
 Código fonte: (em itálico)
 #include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
/*
Pino 12 = RS
Pino 11 = EN
Pino 05 = D4
Pino 04 = D5
Pino 03 = D6
Pino 02 = D7
*/
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!”);
lcd.setCursor(0, 1); // O Cursor iniciara na coluna zero linha 1
}
void loop()
{
//lcd.setCursor(col, row)
lcd.setCursor(0, 2); // O Cursor iniciara na coluna zero linha 1
lcd.print(millis()/1000); // Função para contar em segundos
lcd.print(”  segundos”);  // Exibe e atualiza o tempo desde a entrada no loop
}
O código acima é escrito em linguagem C, e faz uso de bibliotecas integradas do arduino como por exemplo a função LiquidCrystal lcd(); que seta os pinos do lcd que serão conectados ao arduino. 
Na pasta de instalação do arduino subpasta reference podemos consultar uma explicação básica em inglês de todas as funções padrões, vou pegar a referência LiquidCrystal função LiquidCrystal() para exemplificar.
LiquidCrystal()

 

Description

 

Creates a variable of type LiquidCrystal. The display can be controlled using 4 or 8 data lines. If the former, omit the pin numbers for d0 to d3 and leave those lines unconnected. The RW pin can be tied to ground instead of connected to a pin on the Arduino; if so, omit it from this function’s parameters.

 

Syntax

 

LiquidCrystal(rs, enable, d4, d5, d6, d7)
LiquidCrystal(rs, rw, enable, d4, d5, d6, d7)
LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7)
LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)

 

Parameters

 

rs: the number of the Arduino pin that is connected to the RS pin on the LCD
rw: the number of the Arduino pin that is connected to the RW pin on the LCD (optional)
enable: the number of the Arduino pin that is connected to the enable pin on the LCD
d0, d1, d2, d3, d4, d5, d6, d7: the numbers of the Arduino pins that are connected to the corresponding data pins on the LCD. d0, d1, d2, and d3 are optional; if omitted, the LCD will be controlled using only the four data lines (d4, d5, d6, d7).
 Neste procedimento foi utilizado um display de LCD de 20×4 com comunicação a 4 fios, portanto foi utilizada a função LiquidCrystal(rs, enable, d4, d5, d6, d7); Com os devidos valores substituídos pelos pinos do arduino.
LiquidCrystal(rs, enable, d4, d5, d6, d7);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 
Sendo:
 Pino 12 = RS
Pino 11 = ENABLE
Pino 05 = D4
Pino 04 = D5
Pino 03 = D6
Pino 02 = D7
O resultado final pode ser visto no vídeo abaixo

Posted by medigaco_wp in Arduino, 5 comments