Código de búsqueda

Usando un termómetro infrarrojo Melexis MLX90614 con un Arduino LCD1602

Usando un termómetro infrarrojo Melexis MLX90614 con un Arduino LCD1602

Medir la temperatura sin contacto físico es una capacidad fascinante que abre la puerta a muchos proyectos prácticos y creativos. El termómetro infrarrojo Melexis MLX90614 hace esto posible al detectar la radiación térmica emitida por los objetos, permitiéndote medir la temperatura desde una distancia segura. Esta guía te mostrará cómo conectar este versátil sensor a un Arduino y mostrar tanto la temperatura del objeto como la ambiental en una pantalla LCD I2C (ya sea una pantalla de caracteres 16x2 o 20x4).

Este proyecto es perfecto para una amplia gama de aplicaciones, tales como:

  • Construir una estación de detección de fiebre sin contacto para la entrada de una clínica u oficina.
  • Monitorear la temperatura de la cama o del extremo caliente de una impresora 3D sin interferir con la impresión.
  • Crear un comprobador de temperatura de alimentos seguro y sin contacto para cocinar o preparar cerveza.
  • Desarrollar un simple detector de presencia humana midiendo las firmas de calor corporal.
  • Verificar la temperatura de piezas de maquinaria en movimiento o paneles eléctricos desde una distancia segura.

El sensor MLX90614 se comunica mediante el protocolo I2C, lo que significa que solo requiere dos pines de datos (SDA y SCL) además de alimentación y tierra. Esto hace que el cableado sea sencillo y deja muchos pines libres para otros componentes. Al final de este tutorial, tendrás una pantalla de temperatura funcional que puede mostrar lecturas en Celsius, Fahrenheit o Kelvin, y entenderás cómo personalizar el código para tus necesidades específicas.

Hardware Requerido

Para construir este proyecto, necesitarás los siguientes componentes:

  • Placa Arduino (Uno, Nano, Mega, etc.)
  • Módulo sensor de temperatura infrarroja MLX90614
  • Pantalla LCD I2C (16x2 o 20x4 caracteres)
  • Cables de puente
  • Protoboard (opcional, para conexiones más fáciles)

Guía de Cableado

El cableado para este proyecto es simple porque tanto el sensor MLX90614 como la pantalla LCD utilizan el protocolo de comunicación I2C. Esto significa que pueden compartir las mismas dos líneas de datos (SDA y SCL), que se conectan en paralelo. El sensor opera con lógica de 3.3V, pero puede ser alimentado desde la salida de 3.3V del Arduino. El módulo LCD, sin embargo, típicamente requiere 5V para su retroiluminación y lógica (en el video en 03:15).

Aquí está el desglose de las conexiones:

  • 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)

Dado que I2C es un protocolo de bus, puedes conectar hasta 128 dispositivos en las mismas dos líneas (en el video en 03:44). Si estás usando un Arduino Uno o Nano, los pines SDA y SCL están ubicados en A4 y A5 respectivamente. Para otras placas como la Mega, estos pines están en ubicaciones diferentes (20 y 21), así que asegúrate de verificar el pinout de tu placa.

MLX90614 LCD wiring

Configuración de las Librerías

Antes de subir el código, necesitas instalar dos librerías esenciales. La primera es la librería Adafruit MLX90614, que maneja la comunicación con el sensor de temperatura. La segunda es la librería LiquidCrystal I2C, que simplifica el control de la pantalla LCD a través del bus I2C. Estas librerías se pueden instalar a través del Administrador de Librerías de Arduino buscando sus nombres.

Después de instalar las librerías, debes determinar las direcciones I2C de tus dispositivos conectados. Este es un paso crítico porque tanto el sensor como la pantalla LCD tienen sus propias direcciones únicas. El código proporcionado incluye un boceto especial de "Escáner I2C" que puedes subir a tu Arduino para encontrar estas direcciones. Cuando ejecutes el escáner con ambos dispositivos conectados, imprimirá dos direcciones en el Monitor Serial. En el video, la pantalla LCD se encontró en 0x3F y el sensor MLX90614 en 0x5A (en el video en 06:28). Tus dispositivos pueden tener direcciones diferentes, por lo que es esencial ejecutar el escáner y anotar los valores.

Explicación del Código

El código está diseñado para ser flexible, permitiéndote personalizar fácilmente qué unidades de temperatura se muestran y cómo se presenta la información en la pantalla LCD. Aquí están las partes clave configurables por el usuario del código (en el video en 04:31):

Configuración de la Pantalla LCD

En la parte superior del código, encontrarás la configuración para tu pantalla LCD específica. Necesitas ajustar estos valores para que coincidan con tu hardware:

const uint8_t I2C_ADDRESS = 0x3f;  // Dirección I2C de tu pantalla LCD
const uint8_t LCD_CHAR = 16;       // Número de caracteres por línea (16 o 20)
const uint8_t LCD_ROW = 2;         // Número de líneas en la pantalla (2 o 4)

Cambia I2C_ADDRESS a la dirección que encontraste usando el escáner I2C. Si estás usando una pantalla LCD 20x4, establece LCD_CHAR a 20 y LCD_ROW a 4.

Mostrando Unidades de Temperatura

El código utiliza un sistema inteligente de letras para representar diferentes lecturas de temperatura. La función principal printTemp('X') toma un solo argumento de carácter para determinar qué mostrar. El mapeo es el siguiente:

  • 'C' - Temperatura del objeto en Celsius
  • 'D' - Temperatura ambiental en Celsius
  • 'F' - Temperatura del objeto en Fahrenheit
  • 'G' - Temperatura ambiental en Fahrenheit
  • 'K' - Temperatura del objeto en Kelvin
  • 'L' - Temperatura ambiental en Kelvin

En la función loop(), puedes elegir qué lecturas mostrar descomentando las líneas que necesites. Por ejemplo, para mostrar solo lecturas en Celsius tanto de la temperatura del objeto como del ambiente, tu bucle se vería así:

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

Si deseas mostrar tanto Fahrenheit como Celsius, simplemente descomenta las líneas adicionales. El retardo de 2000 milisegundos (2 segundos) entre lecturas te da tiempo para leer la pantalla.

Personalización de las etiquetas de visualización

Puedes cambiar las etiquetas de texto que aparecen en la LCD. El arreglo typeName[] contiene las etiquetas para las temperaturas del objeto y del ambiente:

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

Puedes modificar estas cadenas para mostrar texto en tu idioma preferido, siempre que use caracteres latinos (en el video en 05:08).

Añadir acciones condicionales

El código también incluye una función útil getTemp('X') que devuelve la temperatura como un número de punto flotante. Esto te permite realizar acciones basadas en umbrales de temperatura. Por ejemplo, podrías activar un relé o un zumbador si la temperatura supera cierto valor:

if( getTemp('C') > 40)
{
  // haz algo aquí, como activar un relé o un zumbador
}

Esto es particularmente útil para crear sistemas de alarma o respuestas automatizadas a cambios de temperatura.

Demostración

Una vez que el código esté cargado y el cableado sea correcto, la LCD comenzará a mostrar lecturas de temperatura. En la demostración, el sensor se apuntó a diferentes objetos para mostrar cómo responde. Cuando se apuntó a la frente de una persona, el sensor midió la temperatura corporal alrededor de 33-34°C (en el video en 09:39). Cuando se apuntó a una superficie más fría, las lecturas bajaron a aproximadamente 26°C para el objeto y 28°C para la temperatura ambiente (en el video en 09:52).

El sensor es bastante estable y proporciona lecturas consistentes. El video también demuestra cómo modificar el código para mostrar solo lecturas en Celsius comentando las líneas para Fahrenheit y Kelvin. Esto se hace seleccionando las líneas y usando la función de comentario del IDE de Arduino (Ctrl+/ o Cmd+/), que añade dobles barras (//) al inicio de cada línea.

Por defecto, el código muestra lecturas en Celsius tanto para el objeto como para el ambiente. Puedes cambiar fácilmente a Fahrenheit o Kelvin descomentando las líneas apropiadas en la función loop(). La LCD alternará entre las lecturas del objeto y del ambiente cada dos segundos.

Capítulos

  • [00:00] Introducción al proyecto MLX90614 con LCD
  • [01:20] Opciones de pantalla: LCD2004 y LCD1602
  • [02:29] Cableado explicado
  • [04:28] Código explicado
  • [04:53] Encontrar las direcciones I2C
  • [08:35] Demostración
  • [10:47] Comentarios finales y créditos

Imágenes

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

Cosas que podrías necesitar

Recursos y referencias

Archivos📁

Otros archivos