Código de Pesquisa

Usando um termômetro infravermelho Melexis MLX90614 com um Arduino LCD1602

Usando um termômetro infravermelho Melexis MLX90614 com um Arduino LCD1602

Medir a temperatura sem contato físico é uma capacidade fascinante que abre portas para muitos projetos práticos e criativos. O termômetro infravermelho Melexis MLX90614 torna isso possível ao detectar a radiação térmica emitida pelos objetos, permitindo medir a temperatura a uma distância segura. Este guia mostrará como conectar este sensor versátil a um Arduino e exibir tanto a temperatura do objeto quanto a ambiente em uma tela LCD I2C (um display de caracteres 16x2 ou 20x4).

Este projeto é perfeito para uma ampla gama de aplicações, como:

  • Construir uma estação de triagem de febre sem toque para uma clínica ou entrada de escritório.
  • Monitorar a temperatura da mesa ou do hot-end de uma impressora 3D sem interferir na impressão.
  • Criar um verificador de temperatura de alimentos seguro e sem contato para cozinhar ou fazer cerveja.
  • Desenvolver um detector simples de presença humana medindo assinaturas de calor corporal.
  • Verificar a temperatura de peças móveis de máquinas ou painéis elétricos a uma distância segura.

O sensor MLX90614 comunica-se pelo protocolo I2C, o que significa que requer apenas dois pinos de dados (SDA e SCL) além de alimentação e terra. Isso torna a fiação simples e deixa muitos pinos livres para outros componentes. Ao final deste tutorial, você terá um display de temperatura funcional que pode mostrar leituras em Celsius, Fahrenheit ou Kelvin, e entenderá como personalizar o código para suas necessidades específicas.

Hardware Necessário

Para construir este projeto, você precisará dos seguintes componentes:

  • Placa Arduino (Uno, Nano, Mega, etc.)
  • Módulo sensor de temperatura infravermelho MLX90614
  • Display LCD I2C (16x2 ou 20x4 caracteres)
  • Fios jumper
  • Protoboard (opcional, para conexões mais fáceis)

Guia de Fiação

A fiação para este projeto é simples porque tanto o sensor MLX90614 quanto o display LCD usam o protocolo de comunicação I2C. Isso significa que eles podem compartilhar as mesmas duas linhas de dados (SDA e SCL), que são conectadas em paralelo. O sensor opera com lógica de 3,3V, mas pode ser alimentado pela saída de 3,3V do Arduino. O módulo LCD, no entanto, normalmente requer 5V para o backlight e lógica (no vídeo em 03:15).

Aqui está a divisão das conexões:

  • MLX90614 VCC → Arduino 3.3V
  • MLX90614 GND → Arduino GND
  • MLX90614 SCL → Arduino A5 (SCL)
  • MLX90614 SDA → Arduino A4 (SDA)
  • LCD VCC → Arduino 5V
  • LCD GND → Arduino GND
  • LCD SCL → Arduino A5 (SCL)
  • LCD SDA → Arduino A4 (SDA)

Como o I2C é um protocolo de barramento, você pode conectar até 128 dispositivos nas mesmas duas linhas (no vídeo em 03:44). Se você estiver usando um Arduino Uno ou Nano, os pinos SDA e SCL estão localizados em A4 e A5, respectivamente. Para outras placas como o Mega, esses pinos estão em locais diferentes (20 e 21), então verifique o pinout da sua placa.

MLX90614 LCD wiring

Configurando as Bibliotecas

Antes de enviar o código, você precisa instalar duas bibliotecas essenciais. A primeira é a biblioteca Adafruit MLX90614, que lida com a comunicação com o sensor de temperatura. A segunda é a biblioteca LiquidCrystal I2C, que simplifica o controle do display LCD pelo barramento I2C. Essas bibliotecas podem ser instaladas pelo Gerenciador de Bibliotecas do Arduino, pesquisando por seus nomes.

Após instalar as bibliotecas, você deve determinar os endereços I2C dos seus dispositivos conectados. Este é um passo crítico porque tanto o sensor quanto o LCD têm seus próprios endereços únicos. O código fornecido inclui um esboço especial de "Scanner I2C" que você pode enviar ao seu Arduino para encontrar esses endereços. Quando você executar o scanner com ambos os dispositivos conectados, ele imprimirá dois endereços no Monitor Serial. No vídeo, o LCD foi encontrado em 0x3F e o sensor MLX90614 em 0x5A (no vídeo em 06:28). Seus dispositivos podem ter endereços diferentes, então é essencial executar o scanner e anotar os valores.

Explicação do Código

O código é projetado para ser flexível, permitindo que você personalize facilmente quais unidades de temperatura são exibidas e como a informação é apresentada no LCD. Aqui estão as partes principais configuráveis pelo usuário no código (no vídeo em 04:31):

Configuração do LCD

No topo do código, você encontrará as configurações para o seu display LCD específico. Você precisa ajustar esses valores para corresponder ao seu hardware:

const uint8_t I2C_ADDRESS = 0x3f;  // Endereço I2C do seu LCD
const uint8_t LCD_CHAR = 16;       // Número de caracteres por linha (16 ou 20)
const uint8_t LCD_ROW = 2;         // Número de linhas no display (2 ou 4)

Altere I2C_ADDRESS para o endereço que você encontrou usando o scanner I2C. Se você estiver usando um LCD 20x4, defina LCD_CHAR para 20 e LCD_ROW para 4.

Exibindo Unidades de Temperatura

O código usa um sistema inteligente de letras para representar diferentes leituras de temperatura. A função principal printTemp('X') recebe um único argumento de caractere para determinar o que exibir. O mapeamento é o seguinte:

  • 'C' - Temperatura do objeto em Celsius
  • 'D' - Temperatura ambiente em Celsius
  • 'F' - Temperatura do objeto em Fahrenheit
  • 'G' - Temperatura ambiente em Fahrenheit
  • 'K' - Temperatura do objeto em Kelvin
  • 'L' - Temperatura ambiente em Kelvin

Na função loop(), você pode escolher quais leituras exibir descomentando as linhas necessárias. Por exemplo, para mostrar apenas leituras em Celsius tanto para a temperatura do objeto quanto para a ambiente, seu loop ficaria assim:

void loop() {
  printTemp('C'); // temperatura do objeto em C
  delay(2000);
  printTemp('D'); // temperatura ambiente em C
  delay(2000);
}

Se você quiser exibir tanto Fahrenheit quanto Celsius, basta descomentar as linhas adicionais. O atraso de 2000 milissegundos (2 segundos) entre as leituras dá tempo para você ler o display.

Personalizando os Rótulos do Display

Você pode alterar os rótulos de texto que aparecem no LCD. O array typeName[] contém os rótulos para as temperaturas do objeto e ambiente:

char *typeName[]={"Objeto:","Ambiente:"};

Você pode modificar essas strings para exibir texto no seu idioma preferido, desde que use caracteres latinos (no vídeo em 05:08).

Adicionando Ações Condicionais

O código também inclui uma função útil getTemp('X') que retorna a temperatura como um número de ponto flutuante. Isso permite que você execute ações com base em limites de temperatura. Por exemplo, você poderia ligar um relé ou buzzer se a temperatura exceder um certo valor:

if( getTemp('C') > 40)
{
  // faça algo aqui, como ligar um relé ou buzzer
}

Isso é particularmente útil para criar sistemas de alarme ou respostas automatizadas a mudanças de temperatura.

Demonstração

Depois que o código é carregado e a fiação está correta, o LCD começará a exibir as leituras de temperatura. Na demonstração, o sensor foi apontado para diferentes objetos para mostrar como ele responde. Quando apontado para a testa de uma pessoa, o sensor mediu a temperatura corporal em torno de 33-34°C (no vídeo em 09:39). Quando apontado para uma superfície mais fria, as leituras caíram para cerca de 26°C para o objeto e 28°C para a temperatura ambiente (no vídeo em 09:52).

O sensor é bastante estável e fornece leituras consistentes. O vídeo também demonstra como modificar o código para exibir apenas leituras em Celsius, comentando as linhas para Fahrenheit e Kelvin. Isso é feito selecionando as linhas e usando o recurso de comentário da IDE Arduino (Ctrl+/ ou Cmd+/), que adiciona barras duplas (//) no início de cada linha.

Por padrão, o código exibe leituras em Celsius tanto para a temperatura do objeto quanto para a ambiente. Você pode facilmente alternar para Fahrenheit ou Kelvin descomentando as linhas apropriadas na função loop(). O LCD então alternará entre as leituras do objeto e ambiente a cada dois segundos.

Capítulos

  • [00:00] Introdução ao projeto MLX90614 com LCD
  • [01:20] Opções de display: LCD2004 e LCD1602
  • [02:29] Fiação explicada
  • [04:28] Código explicado
  • [04:53] Encontrando os endereços I2C
  • [08:35] Demonstração
  • [10:47] Considerações finais e créditos

Imagens

MLX90614 LCD wiring
MLX90614 LCD wiring
MLX90614 4
MLX90614 4
MLX90614 3
MLX90614 3
MLX90614 2
MLX90614 2
MLX90614 1 ESF
MLX90614 1 ESF
335-Using MLX90614 Infrared Temperature Sensor with LCD1602
Idioma: C++
++
/*************************************************** 
  This is a library example for the MLX90614 Infrared Temperature Sensor with LCD1602 
Original Library and code source: https://github.com/adafruit/Adafruit-MLX90614-Library

This code has been mostly updated.
It displays the temperature on LCD1602 or LCD2004 in C, F, and K for object and for ambient.

 * 
 * Watch video instructions for this code:  https://youtu.be/_iO2L4P_irw
Updated/written by Ahmad Shamshiri on June 28, 2020 
 
 * in Ajax, Ontario, Canada. www.robojax.com

Introduction to MLX90614 Infrared Temperature Sensor: https://youtu.be/cFDSqiEIunw

 * Get this code and other Arduino codes from Robojax.com
Learn Arduino step by step in a structured course with all material, wiring diagrams, and libraries
all in one place. Purchase My course on Udemy.com http://robojax.com/L/?id=62

If you found this tutorial helpful, please support me so I can continue creating 
content like this. 

or make a donation using PayPal http://robojax.com/L/?id=64

 *  * This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.* 
 * This code has been downloaded from Robojax.com
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

Origin
  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include <Wire.h>
#include <Adafruit_MLX90614.h>
char *typeName[]={"Object:","Ambient:"};

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

#include <LiquidCrystal_I2C.h>
const uint8_t I2C_ADDRESS =0x3f;
const uint8_t LCD_CHAR= 16;
const uint8_t LCD_ROW= 2;
LiquidCrystal_I2C lcd(I2C_ADDRESS, LCD_CHAR,LCD_ROW);


void setup() {
  Serial.begin(9600);

  Serial.println("Robojax MLX90614 test");  

   if (!mlx.begin()) //Begin returns 0 on a good init
  {
      lcd.print("MLX90614 Failed");
      lcd.setCursor(0,1);
      lcd.print("check wiring!");      
    while (1)
      ;
  }  
  Wire.begin();
  lcd.begin();
  lcd.backlight();  
      lcd.print("Robojax MLX90614");
      lcd.setCursor(0,1);
      lcd.print("Infrared Temp.");          
      delay(2000);       
      clearCharacters(LCD_ROW-1,0, LCD_CHAR-1);
       
  
}//setup() end

void loop() {
  //Robojax Example for MLX90614 with LCD
  printTemp('C');//object temperature in C
  delay(2000);
  
  printTemp('D');//ambient temperature in C
  delay(2000);
//    
//  printTemp('F'); //object temperature in F
//  delay(2000);
//     
//  printTemp('G'); //ambient temperature in F
//  delay(2000);  
//  if( getTemp('C')>40)
//  {
//    //do something here
//  }
//  
//  printTemp('K'); //object temperature in K
//  delay(2000);    
//  printTemp('L');//ambient temperature in K  
//  delay(2000);  


  //Robojax Example for MLX90614
}

/*
 * @brief returns temperature or relative humidity
 * @param "type" is a character
 *     C = Object Celsius
 *     D = Ambient Celsius
 *     
 *     K = Object Kelvin
 *     L = Ambient Kelvin
 *     
 *     F = Object Fahrenheit
 *     G = Ambient Fahrenheit

 * @return returns one of the values above
 * Usage: to get Fahrenheit type: getTemp('F')
 * to print it on serial monitor Serial.println(getTemp('F'));
 * Written by Ahmad Shamshiri on March 30, 2020. 
 * in Ajax, Ontario, Canada
 * www.Robojax.com 
 */
float getTemp(char type)
{
   // Robojax.com MLX90614 Code
  float value;
    float tempObjec = mlx.readObjectTempC();//in C object
    float tempAmbient = mlx.readAmbientTempC();
   if(type =='F')
   {
    value = mlx.readObjectTempF(); //Fahrenheit Object
   }else if(type =='G')
   {
    value = mlx.readAmbientTempF();//Fahrenheit Ambient
   }else if(type =='K')
   {
    value = tempObjec + 273.15;// Object Kelvin
   }else if(type =='L')
   {
    value = tempAmbient + 273.15;//Ambient Kelvin
   }else if(type =='C')
   {
    value = tempObjec;
   }else if(type =='D')
   {
    value = tempAmbient;
   }
   return value;
    // Robojax.com MLX90614 Code
}//getTemp

/*
 * @brief nothing
 * @param "type" is a character
 *     C = Object Celsius
 *     D = Ambient Celsius
 *     
 *     K = Object Kelvin
 *     L = Ambient Kelvin
 *     
 *     F = Object Fahrenheit
 *     G = Ambient Fahrenheit

 * @return prints temperature value in serial monitor
 * Usage: to get Fahrenheit type: getTemp('F')
 * to print it on serial monitor Serial.println(getTemp('F'));
 * Written by Ahmad Shamshiri on March 30, 2020 at 21:51
 * in Ajax, Ontario, Canada
 * www.Robojax.com 
 */
void printTemp(char type)
{
 clearCharacters(1,0, LCD_CHAR-1 );  
  // Robojax.com MLX90614 Code
  float tmp =getTemp(type);
      lcd.setCursor(0,1);
      
  if(type =='C')
  {

      lcd.print(typeName[0]);  
      lcd.print(" ");
      lcd.print(tmp);        
      lcd.print((char)223);// 
      lcd.print("C");      
              

  }else if(type =='D')
  {
      lcd.print(typeName[1]); 
      lcd.print(" ");
      lcd.print(tmp);        
      lcd.print((char)223);// 
      lcd.print("C");        
  }else if(type =='F')
  {
      lcd.print(typeName[0]); 
      lcd.print(" ");
      lcd.print(tmp);        
      lcd.print((char)223);// 
      lcd.print("F");        
  }else if(type =='G')
  {
      lcd.print(typeName[1]);
      lcd.print(" ");
      lcd.print(tmp);        
      lcd.print((char)223);// 
      lcd.print("F");        
  }

  else if(type =='K')
  {
      lcd.print(typeName[0]); 
      lcd.print(" ");
      lcd.print(tmp);        
      lcd.print((char)223);// 
      lcd.print("K");        
  }  
  else if(type =='L')
  {
      lcd.print(typeName[1]);
      lcd.print(" ");
      lcd.print(tmp);        
      lcd.print((char)223);// 
      lcd.print("K");        

  }

// Robojax.com MLX90614 Code
}//printTemp(char type)


/*
   clearCharacters(uint8_t row,uint8_t start, uint8_t stop)
 * @brief clears a line of display (erases all characters)
 * @param none
 * @return does not return anything
 * Written by Ahmad Shamshiri
 * www.Robojax.com code May 28, 2020 at 16:21 in Ajax, Ontario, Canada
 */
void clearCharacters(uint8_t row,uint8_t start, uint8_t stop )
{
    for (int i=start; i<=stop; i++)
    {
    lcd.setCursor (i,row); //  
    lcd.write(254);
    } 

}//clearCharacters

Coisas que você pode precisar

Recursos e referências

Arquivos📁

Outros arquivos