MLX90615 - IR Temperature Sensor Interfacing (Code and schematic)

Hi, All

After wasting several hours reading other people's comments and code, I would like to make this writeup, which shows how to wire the MLX90615 IR temperature sensor and run the code on an Arduino Micro using SMBus (Similar to I2C).


Schematic
Look at the schematic picture.
Make sure to wire 4.7K resistors from the SDA/SCL lines up to the 3.3V output on the Arduino


Waveforms
I attached a screenshot of the waveforms. This was a successful transfer. Temperature was around 25'C.


Code

Read first -> Melexis SMBus IR Thermometer - NFI - Interfacing - Arduino Forum

Some notes...

When copying I2Cmaster files, only copy i2cmaster.h and twimaster.cpp into the library folder.
If you leave the software I2C files in, you will be ripping your hair out wondering why the Arduino keeps freezing up.

Make sure you have this in i2cmaster.h

/* define CPU frequency in Mhz here if not defined in Makefile */
#ifndef F_CPU
#define F_CPU 16000000UL
#endif

/* I2C clock in Hz */
#define SCL_CLOCK  50000L

My code (borrowed from others in the forum) works 100% with MLX90615SSG-DAA-000-TU

#include <i2cmaster.h>

void setup() 
{ 
Serial.begin(9600); 
Serial.println("Hello!"); 
i2c_init(); //Initialise the i2c bus 
Serial.println("Return from i2c_init"); 
PORTC = (0 << SDA) | (0 << SCL);//disable pullups
analogReference(EXTERNAL); //setup 3.3V

} 
void loop() 
{ 
int dev = 0x5B<<1; //Need to bit shift left. Someone said SMBus doesn't do this automatically.
int data_low = 0; 
int data_high = 0; 
int pec = 0; 
i2c_start_wait(dev+I2C_WRITE); 
i2c_write(0x27);  //Alot of people make the command 0x07
                  //In the datasheet it says 0x27 on the wave picture, but 0x07 in the text; confusing!

i2c_rep_start(dev+I2C_READ); 
data_low = i2c_readAck(); //Read 1 byte and then send ack 
data_high = i2c_readAck(); //Read 1 byte and then send ack 
pec = i2c_readNak();
i2c_stop(); 

//This converts high and low bytes together and processes temperature, MSB is a error bit and is ignored for temps 
double tempFactor = 0.02; // 0.02 degrees per LSB 
double tempData = 0x0000;
double tempDataF = 0; 
int frac; 

// This masks off the error bit of the high byte, then moves it left 8 bits and adds the low byte. 
tempData = (double)(((data_high & 0x007F) << 8) + data_low); 
//Serial.println((int)tempData,HEX); 
tempData = (tempData * tempFactor)-0.01; 
tempData = tempData - 273.15;
tempDataF = (double)tempData;

Serial.print((int)tempData); //Print temp in degrees C to serial 
Serial.print(".");
tempData=tempData-(int)tempData; 
frac=tempData*100; 
Serial.print(frac); 
Serial.println('C'); 
 

tempDataF = ((double)tempDataF * 1.8) + 32; //Convert to F
Serial.print((int)tempDataF); //Print temp in degrees F to serial 
Serial.print("."); 
tempDataF=tempDataF-(int)tempDataF; 
frac=tempDataF*100; 
Serial.print(frac);
Serial.println('F');

Serial.println();
Serial.println();

delay(250);  
}

Schematic.png