Go Down

Topic: MLX90614 Infrared Sensor data capture (Read 2983 times) previous topic - next topic


I have a Melix MLX 90614 Infrared Thermometer.  The datasheet is here http://www.melexis.com/Assets/IR_sensor_thermometer_MLX90614_Datasheet_5152.aspx

I also found some code (below), from Sparkfun comments, that is supposed to pull data off the sensor.  But it doesn't explain setup.  

By looking at various other posts and stuff on Internet I hooked up the ground (device Pin 4) to Analog 2 and Power (device Pin 3) to Analog 3.  I then attached Pin 2 of the device (PWM/SDA) to Digital 4 and Pin 1 of the device (SCL/Vz) to Digital 5.

I then run the code.  It transmits "Start Read" That it doesn't give back a temperature doesn't surprise me, so out of my depth am I.  But it doesn't even return any printlns in the i2c_read_temperature_f() function.  Is there a reason that function never executes to that point?

Code: [Select]

#include <Wire.h>

static void nunchuck_setpowerpins()
#define pwrpin PORTC3 // or Analog 3
#define gndpin PORTC2 // or Analog 2
DDRC |= _BV(pwrpin) | _BV(gndpin);  //DDRC - The Port C Data Direction Register - read/write
PORTC &=~ _BV(gndpin); //PORTC - The Port C Data Register - read/write
PORTC |= _BV(pwrpin);
delay(100); // wait for things to stabilize

void i2c_start() {
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // send start condition
while (!(TWCR & (1 << TWINT)));

void i2c_write_byte(char byte) {
TWDR = byte;
TWCR = (1 << TWINT) | (1 << TWEN); // start address transmission
while (!(TWCR & (1 << TWINT)));

char i2c_read_byte() {
TWCR = (1 << TWINT) | (1 << TWEA) | (1 << TWEN); // start data reception, transmit ACK
while (!(TWCR & (1 << TWINT)));
return TWDR;

void i2c_receive_pec() {
TWCR = (1 << TWINT) | (1 << TWEN); // start PEC reception, transmit NACK
while (!(TWCR & (1 << TWINT)));

void i2c_stop() {
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); // send stop condition

//Returns 100 times the temperature read by the sensor giving a 0.01 degree resolution.
long i2c_read_temperature_f() {long low_byte, high_byte;

// DDRC = 0; // all inputs
// PORTC = (1 << PORTC4) | (1 << PORTC5); // enable pull-ups on SDA and SCL, respectively

TWSR = 0; // clear bit-rate prescale bits
TWBR = 192; // produces an SCL frequency of 50 kHz with a 20 MHz CPU clock speed.

// The expected value of TWSR & 0xF8 is now 0x08 (Start condition transmitted).

i2c_write_byte(0);// 0 is the universal write address for slaves.
// The expected value of TWSR & 0xF8 is now 0x18 (SLA+W transmitted ACK received).

i2c_write_byte(0x07); // read TObj1 (0x07) from RAM
// The expected value of TWSR & 0xF8 is now 0x28 (Data transmitted ACK received).

// The expected value of TWSR & 0xF8 is now 0x10 (Repeated start has been transmitted).

i2c_write_byte(1); // 1 is the universal read address for slaves.
// The expected value of TWSR & 0xF8 is now 0x40 (SLA+R transmitted ACK received).

low_byte = i2c_read_byte();
// The expected value of TWSR & 0xF8 is now 0x50 (Data received ACK received).

high_byte = i2c_read_byte();
// The expected value of TWSR & 0xF8 is now 0x50 (Data received ACK received).

i2c_receive_pec(); // read packet error code (PEC)
// The expected value of TWSR & 0xF8 is now 0x58 (Data received NOT ACK received).


// Tk is temperature in Kelvin, Tf is temperature in degrees Fahrenheit, To is the raw
// value of the object temperature as returned by the sensor
// 100 Tk = To × 2 (from the datasheet section 8.7.2--To has the units 0.02K)
// Tf = Tk × 9/5 - 459.67 (conversion from Kelvin to Farenheit)

// 100 × Tf = 100 × Tk × 9/5 - 45967
// 100 × Tf = To × 2 × 9/5 - 45967
// 100 × Tf = To × 18/5 - 45967

long total = 256*high_byte+low_byte;
Serial.print("final: ");

return (256*high_byte+low_byte) * 18/5 - 45967; // return temperature in units of 0.01°F

void setup()


void loop()
Serial.println("Start Read");

long object_temperature_f = 0;
object_temperature_f = i2c_read_temperature_f();




I don't know how to help you with the wiring. But, as to why you aren't getting any print statements being executed, that's easy. The i2c_read_temperature_f function calls i2c_start which waits for a response from the i2c device. No response == no return.
The art of getting good answers lies in asking good questions.


Hi Thanks.  I sense there are 2 schools of thoughts 2-wire communications in Arduino, no pun intended ;).  Those that say you have to go straight to hardware, like this example, and those that use a 2-wire library.  For learning, I'm going to try 2-wire first, but anyone's thoughts on this would be appreciated.

Also, this device is 3 volt.  I read that Arduino has built-in pull up resistors.  Do I need resistors between it and the Arduino?


You need to supply the device with 3 volts. It may tolerate 3.3V, which the Arduino (some of them, anyway) could supply.

It's outputs will also be 3 volts (or 3.3 if that's what you supply it). The Arduino will work with that. If the output is to an analog pin on the Arduino, you might want to supply Vref with 3 (or 3.3) volts, too. The voltage on the analog pin is compared to Vref. The ratio between Vpin and Vref is multiplied by 1024, and returned by analogRead.

If the output is to a digital pin, anything over Vref/2 is HIGH. Anything below Vref/2 is LOW. If Vref remains at the default value (5V), 3 (or 3.3) will be HIGH.

I question this:
I hooked up the ground (device Pin 4) to Analog 2

Why? I would expect that ground on the sensor would be connected to ground on the Arduino. I haven't any experience with that device, and I haven't looked at the data sheet, but connecting ground to an analog pin just feels wrong.
The art of getting good answers lies in asking good questions.


Hi, I found another thread on this forum, from 2008, that will supposedly work with this device http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1214872633

I followed his instructions (though didn't know what to make of changing the cpp file so left it alone).  Unfortunately, he doesn't explain hooking up the device to the board.

From posts about 2-wire I assume that pin 0 should be SCL, so I put that on pin 1 of my device, and pin 1 on the Arduino should be SDA, so I put that on pin 2 of my device.  I then clumsly stepped down the voltage from the Arduino (though a LED and transistor) to around 3 volts and put that on the VDD pin, and put VSS into Arduino ground.

It doesn't get any readings.  Does the wiring seem okay to you?  THANK!!!!

Go Up