Foreheads and Fahrenheits
During the COVID-19 pandemic, most of us have encountered the gun-style infrared thermometer. In this article, Jeff explains how thermopiles work, and how they enable Melexis’ MLX90614 IR sensor to perform non-contact body temperature monitoring.
Gun violence is a concern of every citizen. Eliminating our right to bear arms is not the solution. If the use of a gun is required, one will be found. Defuse the hate and eliminate the situation. We have bigger issues right now and they may, in fact, be the cause of much frustration today. We’ve been living with COVID-19 now for well over a year, and vaccines have begun to help us regain some semblance of life as we knew it.
With all that said, let’s focus on a different kind of gun—the “temperature gun”—or more accurately termed, the gun-style infrared thermometer. Since the COVID-19 pandemic began, we’ve gotten used to masking up and getting our temperatures taken before entering buildings or doing certain activities—from attending live meetings to airline travel to dentist appointments. Temperature checking now is possible from a distance, thanks to gun-style infrared thermometers [1]. Point the gun at a forehead, pull the trigger and voila—the surface temperature of the skin is read, while keeping everyone social distanced (Figure 1).
![Figure 1 Typical IR gun for non-contact temperature measurements [1]. Measurements can be displayed in degrees Celsius or Fahrenheit.](https://i0.wp.com/circuitcellar.com/wp-content/uploads/2021/09/374_Bachiochi_Figure_2.jpg?resize=810%2C486&ssl=1)
Typical IR gun for non-contact temperature measurements [1]. Measurements can be displayed in degrees Celsius or Fahrenheit.
About a year ago, I looked at color through the eyes of a semiconductor device in my article “White Hot: Measuring Color Temperature” (Circuit Cellar 363, October 2020). This month, I’m looking into a specific part of the color spectrum, infrared (IR), just below the visible spectrum. IR is most widely identified with TV remotes. We don’t normally think of “heat” when we think of these remotes, and that’s because of the IR spectrum is broad. As shown in Figure 2, IR is nestled in between the microwave spectrum and the visual light spectrum. The IR spectrum is divided into multiple sub-spectra: near, short, intermediate, long and far.

This view of the electromagnetic spectrum breaks down IR into multiple fields that exist just below the visual spectrum, encompassing approximately 700nm to 10,000nm [2]. This range relates to temperatures from 3,591°C to −270.15°C.
Looking at the temperature ranges shown in Table 1, much of life on Earth—at least those entities that produce their own heat—falls into the long-wavelength IR spectrum. Scientists believe our bodies produce heat to keep nasty fungal infections at bay. For us, normal is 98.6°F (37°C), but we all have our own “normal.” Our internal body temperature is regulated by a part of our brain called the hypothalamus. The hypothalamus raises the body’s temperature to fight off infections and viruses, with a temperature of 100.4°F or more considered to be “fever.”
COVID-19 SCREENING
Temperature checks alone are an inefficient screening tool for COVID-19, because a fever may not develop until days after exposure—sometimes not at all. However, body temperature is an indication that someone ought not be out and about, and it can be checked quickly by unskilled personnel. Chances are your company requires you to submit to this testing every time you walk through its front doors. You may be lucky enough to work at home and avoid this. However, when I attend any non-virtual event, I get scanned. When our local scout troop camps, scouts must get scanned before they can participate. For now, we play by the rules.
Along with protective personal equipment (PPE), the sale of IR thermometers has flourished during the pandemic. What makes them so useful? Non-contact sensing is clean, fast and repeatable. Thermopiles and thermocouples enable these sensors to determine temperature without contact.
— ADVERTISMENT—
—Advertise Here—
A thermopile is an electronic device that converts thermal energy into electrical energy. Thermopiles are normally composed of several thermocouples connected in series. Thermocouples work on the principle of the thermoelectric effect. In other words, they generate a voltage when exposed to a temperature difference. Each thermocouple consists of two dissimilar metals with their ends joined to form a junction. A tiny voltage is produced, based on the metals used. The magnitude of the voltage depends on the types of wire being used. Generally, the voltage is in the microvolt range, and once joined in series, a temperature-dependent voltage large enough to be read using an ADC is produced (Figure 3).

At an IR sensor’s core is a thermopile made up of multiple thermocouples [5]. The dissimilar metals that make up each thermocouple produce a tiny voltage across each junction. One set of junctions is exposed to external IR, while the other is insulated from it. A difference in temperature between the two sets of junctions can be seen by measuring the thermopile’s voltage with some additional electronics.
The thermoelectric effect was named after Physicist Thomas Johann Seebeck, who showed that this voltage varies with temperature. One company that’s putting this phenomenon to good use is Melexis. It is a global supplier of micro-electronic semiconductor solutions, including the MLX90614 IR sensor/thermometer. The MLX90614 integrates a thermopile and other electronics to produce a factory-calibrated IR temperature sensing IC, meeting the medical temperature accuracy of ±0.2°C. As this month’s project, we will use the MLX90614 to achieve non-contact body temperature monitoring.
Figure 4 shows the MLX90614 has an internal state machine that controls the measurements and calculations of the external object and ambient temperatures. Post-processing is required to output them through the PWM (pulse width modulation) output or the SMBus compatible interface. For this project, I’ll be using the SMBus, which is similar to I2C running at 100kHz. An application note, “SMBus communication with MLX90614,” is available at [3]. Figure 5 shows the pinout of the four device pins, power (3V/5V) and SMBus (SCL and SDA). It has a single SMBus address. However, since it has internal EEPROM registers and one of these holds its SMBus address (new devices default to 0x5A), the user can change this, to allow up to 127 devices on one bus. Note: Use this with care, because once changed, if you forget it, you’ll need to use a search algorithm to find it.

The Melexis MLX90614 contains all the elements necessary to measure ambient temperature and an external temperature due to IR radiation from the subject [6]. There are multiple temperature output formats, SMBus and PWM. Note: As an alternative to measuring a PWM output, a simple low-pass filter allows this to become analog voltage.

The MXL90614 sensor is housed in TO-39 can packaging with only four legs, shown here in a bottom view. The top of the can exposes the sensor through an optical filter, which removes visible light. The field of view is controlled via pre-attached tubular shields of different lengths, depending on the part number purchased.
MLX90614 REGISTERS
The MLX90614 contains both RAM and EEPROM registers. The 32 RAM registers are read-only, and many are reserved registers. There are only five registers of interest: Two of these are raw data from the two IR thermopiles, and three are computed temperatures—ambient and each IR thermopile. The 32 EEPROM registers contain reserved, configuration and information registers. Refer to Table 2 and Table 3 for explanations of both the EEPROM and RAM registers, respectively.
Since this device has addressable registers, the command format is more than just the SMBus address. It must contain address and command bytes. Remember, the address byte used is actually the SMBus address, which is 7 bits shifted left 1 bit, with the new bit0 controlling reading (bit0=0) or writing (bit0=0). Command bytes will be used as a pointer to a particular register. The commands available are shown in Table 4.
To read RAM or EEPROM requires 6 bytes. Perform an address write and the Command byte, which sets the pointer. Then, perform an address read to retrieve 16 bits of data followed by an 8-bit PEC (Packet Error Code).
To write EEPROM requires 5 bytes. Perform an address write and the Command byte, which sets the pointer, and append 16 bits of data and an 8-bit PEC. (Note: Writing data to the EEPROM actually requires 10 bytes or two write cycles. In the first write cycle your data should be 0x00. This will erase the EEPROM. The second cycle should contain your new data.) It’s always a good practice to read back this register to be assured that it was updated correctly.
To read the flags requires 5 bytes. Perform an address read and the Command byte (0xF0), and retrieve 16-bits of data followed by an 8-bit PEC. To enter sleep mode requires 3 bytes. Perform an address write and the Command byte (0xFF), and an 8-bit PEC.
REGISTER DUMP
In the past, my SMBus (I2C) experimentation has been Arduino-based, and I have a “go-to” circuit that’s wired for I2C devices. A simple protoboard circuit (Figure 6) to house the MLX90614 was wired with a 4-pin connector to match the permanent I2C connection on an Arduino proto shield. The first thing my universal I2C application does is to scan the bus and report any device address that acknowledges its address. I can then look at the devices on the bus and choose one. If there is only one device found, its address is automatically set to this, and you can then do a register dump of any number of registers.
— ADVERTISMENT—
—Advertise Here—
You need to know if the device is a registered device. If not, and you write to set the pointer and there is none, so your write will change register 0. If it is a registered device and you don’t specifically write to the pointer, you will not know which register the data is coming from. In this case, the device is a registered device, and so a write with data = the register of interest sets the pointer to that register, and a read data will give us that register’s data.
Scanning I2C…
Found address: 0 (0x0)
Found address: 90 (0x5A)
Finished and found 2 device(s)
Two devices were found. Actually, these responses are from the same device. Remember: It was discussed earlier that one of the EEPROM registers held the SMBus address. If this was changed, then the default address 0x5A (second address located above) would be something else, and if you tried to communicate at 0x5A there would be no response. All MLX90614 IR thermometers respond to address 0x00 and to the address in EEPROM. If there is more than one device on the bus, address 0x00 will cause bus contention, as all devices respond. With a single device you would be able to use address 0x00 temporarily to find the address located in the EEPROM.
So, we know this device responds to its default address 0x5A and it hasn’t been changed. We just can’t dump the registers with this simple application, since the format is device specific. So, let’s begin with a simple application that will communicate as described earlier. This application is detailed and explained in Listing 1.
Listing 1
My I2C communication application
We begin with the Wire Library for I2C communications and a definition of all the registers of interest. Note that the EEPROM registers are offset by 0x20. All registers not listed are reserved and of no particular interest.
#include <Wire.h>
const byte MLX90614_I2CADDR = 0x5A;
//RAM
const byte MLX90614_RAWIR = 0x04;
const byte MLX90614_RAWIR2 = 0x05;
const byte MLX90614_TA = 0x06;
const byte MLX90614_TOBJ1 = 0x07;
const byte MLX90614_TOBJ2 = 0x08;
//EEPROM
const byte MLX90614_TOMAX = 0x20;
const byte MLX90614_TOMIN = 0x21;
const byte MLX90614_PWMCTRL = 0x22;
const byte MLX90614_TARANGE = 0x23;
const byte MLX90614_EMISS = 0x24;
const byte MLX90614_CONFIG = 0x25;
const byte MLX90614_ADDR = 0x2E;
const byte MLX90614_ID1 = 0x3C;
const byte MLX90614_ID2 = 0x3D;
const byte MLX90614_ID3 = 0x3E;
const byte MLX90614_ID4 = 0x3F;
//
byte PEC;
byte registerOfInterest;
int registerArray[0x40];
//
We start out with a sign on message:
void setup()
{
Serial.begin(9600);
Serial.println(“ftb374 IR Thermometer”);
Serial.println(“ using the MLX90614”);
Serial.println(“”);
Wire.begin();
}
//
In the main loop we ask for each register one at a time:
void loop()
{
for(registerOfInterest = 4; registerOfInterest<9; registerOfInterest++)
{
readRegister();
}
.
(EEPROM registers)
.
}
Each MLX90614 register consists of 16 bits of data or 2 bytes, and this (return) value is saved in registerArray[] for future use.
//
void readRegister()
{
registerArray[registerOfInterest] = read16(registerOfInterest);
}
//
Next, Listing 2 is where the actual SMBus communications happen. Start by writing the device address and command, then read the data using the device address and a request for 3 bytes (2 data bytes and 1 PEC). The 2 data bytes are combined LSB first and returned as an integer by the routine. The third or extra byte is the PEC and holds the Packet Error Code for verifying the integrity of the communications. The routine in Listing 2 produces a list of the registers and the values reported by the device as shown in Listing 3.
Listing 2
This routine produces a list of the registers and the values reported by the device as shown in Listing 3.
int read16(byte a)
{
Serial.println(“Register: 0x” + String(a,HEX));
int ret;
Wire.beginTransmission(MLX90614_I2CADDR); // start transmission to device
Wire.write(a); // sends register address to read from
Wire.endTransmission(false); // end transmission
//
Wire.requestFrom(MLX90614_I2CADDR, 3); // send data n-bytes read
ret = Wire.read(); // receive DATA
PEC = Wire.read(); // receive DATA
Serial.println(“LSB = 0x” + String(ret,HEX));
Serial.println(“MSB = 0x” + String(PEC,HEX));
ret = (PEC*256) + ret;
PEC = Wire.read(); // receive DATA
Serial.println(“PEC = 0x” + String(PEC,HEX));
return ret;
}
Listing 3
List of registers and their values produced by the routine in Listing 2
Register = 0x4
LSB = 0x1
MSB = 0x0
PEC = 0x29
Register = 0x5
LSB = 0x4
MSB = 0x0
PEC = 0x7e
Register = 0x6
LSB = 0x54
MSB = 0x3a
PEC = 0xee
Register = 0x7
LSB = 0x50
MSB = 0x3a
PEC = 0xac
Register = 0x8
LSB = 0x61
MSB = 0x3a
PEC = 0x92
Register = 0x20
LSB = 0x93
MSB = 0x99
PEC = 0xb2
Register = 0x21
LSB = 0xe3
MSB = 0x62
PEC = 0xe9
Register = 0x22
LSB = 0x1
MSB = 0x2
PEC = 0x9d
Register = 0x23
LSB = 0x1c
MSB = 0xf7
PEC = 0xf0
Register = 0x24
LSB = 0xff
MSB = 0xff
PEC = 0xd6
Register = 0x25
LSB = 0x75
MSB = 0xb7
PEC = 0xb
Register = 0x2e
LSB = 0x5a
MSB = 0xbe
PEC = 0xd3
Register = 0x3c
LSB = 0x19
MSB = 0xc0
PEC = 0x81
Register = 0x3d
LSB = 0x42
MSB = 0x51
PEC = 0xf2
Register = 0x3e
LSB = 0x24
MSB = 0x63
PEC = 0xdd
Register = 0x3f
LSB = 0xc
MSB = 0xe1
PEC = 0x4a
A quick check of register 0x2E shows the device’s address register’s LSB data is in fact 0x5A. So we now have a scan of all the registers of interest in registerArray[]
. You may be interested in the optional ways in which this device could be used. I’ll briefly touch on these.
ALTERNATE CONFIGURATIONS
If we look at the EEPROM register 0x22, PWRCTRL, we can see some alternate ways this device could be configured (Table 5). The MLX90614 can produce a PWM output on the SDA pin. The connected microcontroller (MCU) could then determine the ambient or IR temperature based on the pulse width of the PWM output. Registers 0x20 (TMAX) and 0x21 (TMIN) can set the maximum and minimum IR temperatures relating to the maximum and minimum pulse widths, to improve resolution of the 10-bit PWM. Ambient temperature max and min are set through the TRANGE register 0x23. A (single) temperature or dual (extended) temperatures can be transmitted, set by the PWM mode. The time period of each PWM bit can be stretched via the PWM period multiplier.
A second alternate use would be the thermal relay mode, to place a temperature state on the SDA pin—high output for temperatures above max, and low for temperatures below min. In this case, hysteresis of the output is set by the distance between max and min.
Configuration Register 0x25 holds additional control bits for the analog and digital blocks of the sensor circuitry. These include a gain adjustment for the sensor signal amplifier, and settings for the two filters of the DSP section. An IIR (infinite impulse response) controls rapid sensor temperature changes, while the FIR (finite impulse response) is primarily implemented for noise control. A Melexis application note [4] goes into detail of the filters, for those who wish to know more.
TEMPERATURE READINGS
The RAM registers 0x04 through 0x08 contain the raw temperature data and computed temperatures. The ambient (sensor die) linearized temperature is available in register 0x06 (Ta). This (and all temperature values) are represented by 0.02K (kelvins)/bit. The ambient temperature is confined to a minimum of -38.2°C (0x2DE4) and a maximum of +125°C (0x4DC4). To convert the register value to a temperature, multiply the value by 0.02. For example, the minimum temperature value would be calculated as 0x2DE4 × 0.02 = 11,748 × 0.02 = 234.96K.
°C = degrees K – 273.15
°C = 234.96 – 273.15
°C = -38.19
°F = (°C × 9/5) +32
°F = ((-38.19 × 9) /5) + 32
°F = (-343.71 / 5) + 32
°F = -68.74 + 32
°F = -36.74
The RAM registers 0x07 through 0x08 contain the computed temperatures for the two sensors (Tobj1 and Tobj2.) TheMLX90614 is available in various configurations of voltage range, sensor count, and field of view (FOV). I chose the MLX90614ESF-DCI-000-SP, because it is the 3V medical-grade sensor with a 5-degree FOV. Process these two sensor temperatures as you did the ambient temperature.
The first two RAM registers Rawobj1 (0x00) and Rawobj2 (0x01) are post-filter values before temperature calculations. These values are useful if you want to adjust the gain and filter parameters to determine saturation levels.
— ADVERTISMENT—
—Advertise Here—
FIELD OF VIEW
Field of view (FOV) is a critical component of the IR sensing system. Take a look out your window. If you get close to the glass, you’ll have a wide field of view of life on the other side of the glass. As you back away from the glass, the window frame begins to block some of your view, reducing your view’s field. The FOV is referenced as the angle between your eye and the window sashes. Because most windows are not square, your vertical and horizontal FOVs will probably be different for any distance from the window.
For the standard MLX90614, the FOV is 90 degrees. If we determine that the target of interest (area on the forehead) will be an area of 1” in diameter, then for the standard sensor with an FOV of 90 degrees, we would need to be 0.5” from the sensor. While that’s not contact, it’s really close! So why not just back up a few inches? The spot or area of coverage that the sensor will detect becomes inches in diameter. Since the sensor will be averaging the temperature over that area, other things in the FOV—such as hair, eye glasses and nose—will affect the average temperature. So, it’s best to use the smallest area possible, and aim the sensor accurately.
Using a sensor with a smaller FOV, like the one I’m using, will allow taking temperatures at a greater distance. This comes at a cost multiplier of about 3×. To create a smaller FOV, the sensor is partially blinded by placing the sensor at the end of a short tube. Like moving away from the windows sash, this reduces the FOV.
EXPANDING THE APPLICATION
Up to this point, we’ve only confirmed communications with the sensor. I like a lot of debug information spit out the serial port. It always helps to have feedback on what’s actually going on. But after a while, the stream of data gets to be overwhelming. I use a variable myDebug
to enable and disable different output. The 8 bits allow control over eight functions. I’ll assign bit0 to all the print statements in the routine read16() in this way:
if(myDebug & 2)
{
Serial.println(“Register: 0x” + String(a,HEX));
}
If myDebug
= 0, then no output will be produced.
So, let’s get right to it. Look at Listing 4. The registerOfInterest
is 0x06, ambient Temperature. We can do the same for registers 0x07 (sensor1 Temperature) and 0x08 (sensor2 Temperature). The last two routines will apply the conversion formulas (mentioned earlier) to the register temperature, which is in Kelvins.
Listing 4
Code with routines to read the temperature values and do the conversion formulas. Output from this code is also shown.
Serial.println(“ Ta[K] =”);
Serial.print(“ “);
temperatureInK = registerArray[registerOfInterest] * 0.02;
Serial.print(temperatureInK);
Serial.println(“ degrees K”);
calculateCFromK();
calculateFFromC();
The code above produces an output like this:
Ta =299.88 degrees K
26.73 degrees C
80.11 degrees F
TO1=299.68 degrees K
26.53 degrees C
79.75 degrees F
TO2=299.80 degrees K
26.65 degrees C
79.97 degrees F
Additional routines have been added to this application to give a verbose explanation to each register’s values. That’s a lot of text, but if you wish to begin looking into alternate configurations, this will help you understand the values without going back through the datasheet.
This is a good place to stop for this column. Next time, in Part 2, we’ll delve into actual temperature readings and discuss some of the other factors you should be aware of. Too much to do, so little time.
RESOURCES
References:
[1] Applications flyer for medical thermometers
https://www.melexis.com/en/documents/documentation/application-flyers/applications-flyer-medical-thermometer
[2] Cahyadi, Willy & Chung, Yeon-Ho & Ghassemlooy, Zabih & Bani Hassan, Navid. (2020). Optical Camera Communications: Principles, Modulations, Potential and Challenges. Electronics. 9. 1339. 10.3390/electronics9091339.
https://www.researchgate.net/figure/The-electromagnetic-spectrum_fig1_343755508
[3] Application Note: SMBus communication with MLX90614
www.melexis.com/en/documents/documentation/application-notes/application-note-mlx90614-smbus-communication
[4] Application Note: Understanding MLX90614 on-chip digital signal filters
www.melexis.com/en/documents/documentation/application-notes/application-note-mlx90614-onchip-digital-signal-filters
[5] Demystifying Thermopile Sensors by T.K. Hareendran. Founder and promoter of TechNode Protolabz—an electronics R&D Lab
www.electronicsforu.com/resources/demystifying-thermopile-sensors
[6] MLX90614 Data Sheet
https://www.melexis.com/en/documents/documentation/datasheets/datasheet-mlx90614
Melexis | www.melexis.com
PUBLISHED IN CIRCUIT CELLAR MAGAZINE • September 2021 #374 – Get a PDF of the issue
Sponsor this ArticleJeff Bachiochi (pronounced BAH-key-AH-key) has been writing for Circuit Cellar since 1988. His background includes product design and manufacturing. You can reach him at: jeff.bachiochi@imaginethatnow.com or at: www.imaginethatnow.com.