Learn

An MLX90614 on an Arduino: a no-touch thermometer

Beginner

Or see every lesson.

  • 505parts on the bench
  • 45boards running now
  • 1.00xreal time, on every board
Arduino Uno: an MLX90614 fever thermometerlive0.000 s 0.00x
Click to open it in the editor
The Fever thermometer example: drag the object temperature on the GY-906 past 38 C and the LCD says FEVER.

The MLX90614 reads the temperature of whatever it points at without touching it. It is the sensor inside many forehead thermometers and the little "IR thermometer" guns, and it comes on a small GY-906 board with four pins that plug straight into an Arduino’s I2C bus.

The circuit above is an Uno, an MLX90614 and a 16x2 LCD with an I2C backpack, sharing one bus, plus a piezo on pin 8. Twice a second the LCD shows the forehead’s temperature and the room’s; over 38.0 C (100.4 F) the first line says FEVER and the piezo beeps. Press Run, then drag the object slider on the sensor past 38 and listen.

What you need

  • An Arduino Uno
  • An MLX90614 module (GY-906)
  • A 16x2 LCD with an I2C backpack (address 0x27)
  • A passive piezo
  • A breadboard and jumper wires

Wiring

Part and pinGoes toNote
MLX90614 VIN5 VThe GY-906 runs on 3 to 5 V
MLX90614 GNDGND
MLX90614 SDASDA (A4)Shares the bus with the LCD
MLX90614 SCLSCL (A5)
LCD VCC and GND5 V and GND
LCD SDA and SCLA4 and A5The same two bus wires
PiezoPin 8Other leg to GND

How a thermometer reads without touching

Everything warmer than absolute zero gives off infrared light, and the warmer it is, the more it gives off. Behind the MLX90614’s window is a thermopile, a stack of tiny junctions that warm up a little when infrared falls on them. A second sensor inside measures the can itself. The chip compares the two and works out the temperature of what is in front of it.

So you get two numbers: the object temperature (what it sees) and the ambient temperature (its own, which is about the room’s). The chip keeps both in memory, and an Arduino reads them over I2C at address 0x5A. The value is stored in fiftieths of a kelvin; the library turns it into degrees Celsius for you.

The sketch

The sketch reads both temperatures, multiplies by 10 and rounds, so it can work in whole tenths of a degree: 36.6 C becomes 366. That makes the fever check a plain whole-number comparison, object > 380, and keeps the display to one decimal place.

When the forehead is over 380 tenths, the first line reads FEVER and tone(PIEZO, 2000, 150) gives a short 2000 Hz beep, once for each reading while the fever lasts. At exactly 38.0 there is no beep; at 38.1 there is. Run it and drag the slider to see.

The serial monitor gets the same reading, "forehead 36.6 C" at the start, with "FEVER" on the end of the line when it is over.

The fever thermometer’s loop, trimmed
#include <Wire.h>
#include <Adafruit_MLX90614.h>
#include <LiquidCrystal_I2C.h>

const int PIEZO = 8;
const int FEVER_TENTHS = 380;

Adafruit_MLX90614 mlx = Adafruit_MLX90614();
LiquidCrystal_I2C lcd(0x27, 16, 2);

void loop() {
  int object = (int)(mlx.readObjectTempC() * 10.0 + 0.5);
  int ambient = (int)(mlx.readAmbientTempC() * 10.0 + 0.5);
  bool fever = object > FEVER_TENTHS;

  lcd.setCursor(0, 0);
  lcd.print(fever ? "FEVER " : "Temp  ");
  printTenths(object);
  lcd.print(" C   ");
  lcd.setCursor(0, 1);
  lcd.print("Room  ");
  printTenths(ambient);
  lcd.print(" C   ");

  if (fever) tone(PIEZO, 2000, 150);
  delay(500);
}

Two sensors on one I2C bus

The LCD backpack is at 0x27 and the MLX90614 at 0x5A, so both hang on the same two wires and the Uno talks to each by its address. That is the point of I2C: up to dozens of parts on two pins, as long as no two share an address.

Watch for parts that do share 0x5A. The MPR121 touch sensor lives there too, so the two cannot share a bus unless you move the MPR121’s address. If you are not sure what is on your bus, run an I2C scanner first (see the I2C page below).

Getting a real reading

A real MLX90614 sees a cone, not a dot. The common GY-906 (the MLX90614ESF-AAA) has a 90 degree field of view, so at 10 cm it averages a circle about 20 cm wide. Hold it a couple of centimeters from a forehead, or it reads the wall behind as well.

Shiny things lie. The chip assumes the surface gives off infrared like skin does (an emissivity of 1.0, close to skin’s 0.98). Polished metal gives off much less, so it reads far too cold. The library can change the emissivity with writeEmissivity(), but it is stored in the chip’s memory, so most people leave it alone and put tape on a metal part instead.

Also, a forehead reads cooler than the inside of your body, so a medical thermometer adds a correction. This project is a demo for learning, not a medical device.

Common mistakes

The sensor not found. With SDA pulled out, mlx.begin() fails, the LCD says "No MLX90614" and the sketch stops. Check SDA, SCL and power.

Measuring from too far away, so the reading is the room’s average, not the object’s.

Another part at 0x5A on the same bus, such as an MPR121.

Pointing it at glass or shiny metal and believing the number. Infrared does not pass through glass, so through a window it reads the glass.

Comparing floats for the alarm and getting a beep that flickers at the limit. Rounding to whole tenths, as this sketch does, keeps the check steady.

Open this circuit in the editor. Arduino Uno: an MLX90614 fever thermometer, wired as it runs at the top of this page. Change a part or a value and run it again.

Open the circuit

Questions

What library do I need for the MLX90614?

The Adafruit MLX90614 Library. Call mlx.begin(), then mlx.readObjectTempC() for what it points at and mlx.readAmbientTempC() for its own temperature. There are F versions for Fahrenheit.

What is the MLX90614 I2C address?

0x5A by default. It can be changed in the chip’s memory, which is how two of them share a bus.

How accurate is the MLX90614?

About 0.5 C around room and body temperature, by the datasheet, for a surface that fills its field of view. The medical grade version is better, around 0.2 C.

Can it measure through glass?

No. Glass blocks the infrared it reads, so it measures the glass.

Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.