Melexis SMBus IR Thermometer - NFI

Thank you for all the help with connecting the Melexis MLX90614. I have not been getting a response from the device whatsoever. By going through your code, I found that the code never progresses beyond the code line "i2c_start_wait(dev+I2C_WRITE);" I've yet to get a response by the MLX90614 any other method, and I would be very gracious if anyone could help explain to me what I'm doing wrong. Thanks!

I have been trying to get the i2cmaster.h library to work in my arduino development board with no success. I renamed the twinmaster.c to a .cpp file and changed the F_CPU definition as well as the SCL_CLOCK . . . However, when I include i2cmaster.h, I am not able to even get a "Hello World" program to work . . . here is some example code:

#include <i2cmaster.h>

void setup(){
Serial.begin(9600);
Serial.println("Hello World!");
i2c_init();
Serial.println("Return from i2c_init");
PORTC = (1 << PORTC4) | (1 << PORTC5);
}

Anyone have any idea why I am not able to println and have something show up on the serial monitor?

Make a folder in /{arduino root}/hardware/libraries and extract the
i2cmaster.h and twimaster.c files. Now rename the .c file of twimaster to .cpp (YES I KNOW IT SOUNDS WIERD BUT RENAME AND MAKE SURE THESE FILES ARE IN THE RIGHT LOCATION I.E. IN THE LIBRARIES FOLDER OF THE ARDUINO CODE)

Did you mean /{arduino root}/libraries ? Because there is no /{arduino root}/hardware/libraries folder . . . only /{arduino root}/hardware/arduino and /{arduino root}/hardware/tools

If you have a Arduino MEGA connect the SCL and SDA pins to 20 and 21.

Do not use Analogue pins 4 and 5.

This is just in case there is anyone else out there wondering why there comms isn´t working when the circuit and software is correct.

There must be another idiot like me??? wasted an hour on that.

The info on this thread is fantastic I would like to thank everyone who posted as it saved me a lot of time.

Neil C

Hey

I have the Melexis 90614ACC (That is the 5v version) of the sensor and i tried to read temp data from it using the i2c master library and dave eatons code as follows:

#include <i2cmaster.h>

void setup()
{
Serial.begin(9600);
Serial.println("Hello!");
i2c_init(); //Initialise the i2c bus
Serial.println("Return from i2c_init");
PORTC = (1 << PORTC4) | (1 << PORTC5);//enable pullups
}
void loop()
{
int dev = 0x5A<<1;
int data_low = 0;
int data_high = 0;
int pec = 0;
i2c_start_wait(dev+I2C_WRITE);
i2c_write(0x07);

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;
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);
tempData = (tempData * tempFactor)-0.01;
tempData = tempData - 273.15;
Serial.print((int)tempData); //Print temp in degrees C to serial
Serial.print(".");
tempData=tempData-(int)tempData;
frac=tempData*100;
Serial.println(frac);
delay(100);
}

Is there any reason the code isnt working? i tried using Serial.println to see till what stage the program executes and it stops before

i2c_rep_start(dev+I2C_READ);

doesnt go beyond that
Any ideas?
Also does the 5v version require me to pull-up to 5v or 3.3because thts SMBus spec?
Also the melexis datasheet gives a figure which shows the pin configurations and is labelled "TOP VIEW"
Does that mean it shows the pins coming out of the page or the other way round??
Im confused

hello,

i have tried the codes too, but no output appear at all. i think it is stuck in the i2cmaster. even the printf doesnt work at all but when i remove the i2cmaster.h and comment out the unnecessary codes-left only the prints--it works. so i believe it is caaused by the i2cmaster.h

anybody could help?
i guess every1 is having the same problems too

thank you

Hello,

I have purchased one of these sensors and with the help of this thread I was able to get it up and running rather quickly. Per the data sheet, changing the read address from 0x007 to 0x006 will give you the temperature of the internal device (Ta). This works great.

I'm using this sensor to measure the temperature of a steel surface, which has an emissivity of 0.35. These sensors are set at a default emissivity of 1.0. This is giving me large errors in measuring my surface.

The data sheet lists the EEPROM address for several objects that can be customized, page 11. The 0x004 address corresponds to the emissivity constant. Equal to 65535 * E.

My question is, how do I access the EEPROM on this device? Page 18 of the data sheet lists some Opcode's for certain commands. (what is an “Opcode” anyway?) 000x xxxx = RAM Access and 001x xxx is EEPROM Access.

I'm confused on how to implement the switch to EEPROM access. Could someone help me out on how to modify the code to read and write to the 0x004 address on the EEPROM?

Thanks for your help!
Steven

Any suggestions?

I'm making some progress. Slowing understanding more how this I2C communication works. I figured out that the addresses shown in table 5 on page 11, must have 20 added to them. So 0x004 becomes 0x024x. Someone can probably explain the reason why better.

So I can now read the existing emissivity coefficient correctly. High & low byte = 255, which gives you 65535 combined. Exactly what the data sheet says.

In order to write a new value you must first erase (write 0) to the cell, and then proceed to write your value. This is where I am having problems. Take a look at my code.

#include <i2cmaster.h>
void setup()
{
Serial.begin(9600);
Serial.println("Hello!");
i2c_init(); //Initialise the i2c bus
PORTC = (1 << PORTC4) | (1 << PORTC5);//enable pullups
}
void loop()
{
int dev = 0x5A<<1;
unsigned int data_low = 0;
unsigned int data_high = 0;
int pec = 0;
unsigned short data_temp = 0x0000;
double emissivity = 0x0000;
i2c_start_wait(dev+I2C_WRITE);
i2c_write(0x24); //Register Address
i2c_write(0x0000); //Erase (write 0)
i2c_write(0x5999); //Write Data
i2c_stop();
Serial.println("Write Done.");
delay(100);
i2c_start_wait(dev+I2C_WRITE);
i2c_write(0x24);
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();
Serial.print("Data Low: ");
Serial.println(data_low);
Serial.print("Data High: ");
Serial.println(data_high);
Serial.print("Data: ");
data_temp = (((data_high) << 8) + data_low);
Serial.println(data_temp);
Serial.print("Emissivity Coefficient: ");
emissivity = (data_temp/65535);
Serial.println(emissivity);
Serial.println("");
delay(5000);
}

Do I need to make seperate writes to the MSB and LSB? As of now I am not even able to erase the cell.

Thanks!

Ahh, this is frustrating. I've searched all over the net for information to help me out. So far everything I've tried has failed. What am I doing wrong?

Shouldn't this code work too?

#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(9600);
Serial.println("Hello!");
PORTC = (1 << PORTC4) | (1 << PORTC5);//enable pullups
}
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data )
{

  • int rdata = data;*
  • Wire.beginTransmission(deviceaddress);*
  • Wire.send((int)(eeaddress >> 8)); // MSB*
  • Wire.send((int)(eeaddress & 0xFF)); // LSB*
  • Wire.send(rdata);*
  • Wire.endTransmission();*
  • delay(5);*
    }
    void loop()
    {
  • i2c_eeprom_write_byte(0x5A, 0x24, 0x0000); //Erase (write 0)*
  • Serial.println("Write Done");*
  • delay(5000);*
    }

I think my problem is not properly writing to the MSB and LSB. Any feedback at all would be much appreciated. I'm just spinning my wheels right now. This shouldn't be that hard! >:(

My first post to this forum..
I just wanted to share my solution for the problem I and several others seem to have faced when trying to interface with the MLX90614.

I first tried everything suggested in this thread, then googled through a loads of other sites and forums, and also browsed through an extensive amount of documentation and other material provided by Melexis web site. I tried virtually everything without success and finally returned back here..

First of all, lots of thanks for Sensorjunkie, his(?) instructions really work if you just follow them (and adapt a bit if you are using newer version of Arduino software - mine is the Arduino 0021 which is the latest one at the moment).

Below are some comments/details/minor adaptations to Sensorjunkie's instructions..

  1. Connect as instructed (if you haven't changed the pins, of course)
    SCL --> Analog5
    SDA --> Analog4
    Vdd --> 3V3
    Vss --> Gnd

AND (this is really important!)

Use two 4K7 (4.7 KOhms) resistors to physically pull-up the SCL and SDA connecting them to Vdd on the breadboard. THIS was the reason why the connection to my sensor could not be properly started. So the analog-pull-up-PORTC-stuff on the code is definitely not enough to make things work.

  1. Download Peter Fleury's nice library...

BUT place it under /{arduino root}/libraries/"what-ever-folder" where the current Arduino software looks for the libraries when started. You also have to rename the "twimaster.c" to "twimaster.cpp" as instructed so that Arduino can build it when launched. You also have to create a "keywords.txt" file inside the "what-ever-folder" where you define the library functions (function names and KEYWORD2 only). Without doing this Arduino cannot find and build the library. You can copy and edit the keyword file from some other library or see some help at Arduino's LibraryTutorial (Sorry, but it seems I cannot mail any links - just google for it..)

  1. Modify the twimaster.cpp to reflect the Arduinos 16 MHz clock (I have Arduino UNO & Duemilanove with ATMEGA 328P). You can also scale down the speed of the SMBus to 50 KHz as instructed but mine works just fine using the 100 KHz as well. Generally, I think they suggest selecting anything b/w 10 to 100 KHz for SMBus rate.
    F_CPU 16000000UL
    SCL_CLOCK 50000L // or 100000L
    Don't otherwise touch the code if you don't really know what you are doing..

  2. Now just copy Dave Eaton's code (and remember to mention him in your file:) and it should work like a charm. I adapted the code by Martin Nawrath (Google for "Nawrath MLX90614"..) that gives you also the ambient temperature values (i.e., the temperature of the sensor itself). But you can also add that part to Dave's code as well.

Some other points:

  • you can use either the general device address 0x00 that works for all MLX90614 sensor models or the address of the specific sensor sub-model you have (0x5A in my case)
  • remember to do the "<<1" operation for the address as its not done automatically by the twimaster library
  • use 100nF capacitor (I use metallic film capacitor of type 104) between Vdd and Vss to minimize the power supply noise (keep the leads as short as possible between the pins)
  • the addresses for object temperature (0x07) and ambient temp (0x06) are correct
  • you cannot use the Wire library to interface with the SMBus protocol of the sensor, it just doesn't work

That's my two cents.. I hope this helps you to take most of the sensor.

I have the Freeduino am I right to use analogue pins 4 and 5 for the melexis?

My setup:

Pin 1 on MLX (SCC) connect to ANALOG pin 5 on Freeduino
Pin 2 on MLX (SDA) connect to ANALOG pin 4 on Freeduino
Pin 3 on MLX (VDD) connect to 3.3V on Freeduino
Pin 4 on MLX (VSS) connect to GROUND on Freeduino

Im getting this error:

Stepper_Easy_Driver_1_7_With_Cloud_detector_zip.cpp:7:23: error: i2cmaster.h: No such file or directory
Stepper_Easy_Driver_1_7_With_Cloud_detector_zip.cpp: In function 'long int readMLXtemperature(int)':
Stepper_Easy_Driver_1_7_With_Cloud_detector_zip:345: error: 'i2c_init' was not declared in this scope
Stepper_Easy_Driver_1_7_With_Cloud_detector_zip:346: error: 'I2C_WRITE' was not declared in this scope
Stepper_Easy_Driver_1_7_With_Cloud_detector_zip:346: error: 'i2c_start_wait' was not declared in this scope
Stepper_Easy_Driver_1_7_With_Cloud_detector_zip:347: error: 'i2c_write' was not declared in this scope
Stepper_Easy_Driver_1_7_With_Cloud_detector_zip:347: error: 'i2c_write' was not declared in this scope
Stepper_Easy_Driver_1_7_With_Cloud_detector_zip:349: error: 'I2C_READ' was not declared in this scope
Stepper_Easy_Driver_1_7_With_Cloud_detector_zip:349: error: 'i2c_rep_start' was not declared in this scope
Stepper_Easy_Driver_1_7_With_Cloud_detector_zip:350: error: 'i2c_readAck' was not declared in this scope
Stepper_Easy_Driver_1_7_With_Cloud_detector_zip:352: error: 'i2c_readNak' was not declared in this scope
Stepper_Easy_Driver_1_7_With_Cloud_detector_zip:353: error: 'i2c_stop' was not declared in this scope

I have the ic2mater files in the correct directory and renamed twimaster.c to twimaster.cpp

Anyone help please :slight_smile:

Here's the sketch Im using

//START OF FOCUS CONTROL INITIALISE
// include the library code:
#include <LiquidCrystal.h>
#include <Stepper.h>
#include <Servo.h>
#include <i2cmaster.h>

//Start Serial comms definitions:- arrays used for storage of strings and the detection of a string
#define MAX_COMMAND_LEN (5)
#define MAX_PARAMETER_LEN (6)
#define COMMAND_TABLE_SIZE (10)
#define TO_UPPER(x) (((x >= 'a') && (x <= 'z')) ? ((x) - ('a' - 'A')) : (x))
#define SERVO_PIN 19
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int sensorPin = 0; // select the input pin for the LCD buttons
int sensorValue = 0; // variable to store the value coming from the LCD

//Stepper.h pin definitions (incorrect?)
int Pin0 = 33; //Stepper Motor Driver Pin 1
int Pin1 = 35; //Stepper Motor Driver Pin 2
int Pin2 = 37; //Stepper Motor Driver Pin 3
int Pin3 = 39; //Stepper Motor Driver Pin 4

//Easy Driver
int dirPin = 51; // Easy Driver Direction Output Pin
int stepperPin = 53; // EasyDriver Stepper Step Output Pin
int ms1 = 26; //Easy Driver Microstepping output
int ms2 = 28; //Easy Driver microstepping output

// Focus control Variable definition
int motorSteps =200; //number if steps for the motor to turn 1 revolution
volatile int NoOfSteps = 1000; //required number of steps to make
volatile long Position = 0; //used to keep track of the current motorposition
volatile int MaxStep = 16384; //define maximum no. of steps, max travel
volatile int SPEED = 5;
volatile byte MotorType = 0; // Motortypes, default is 0, Stepper motor, 1=Servo, 2=DC motor
boolean Direction = true;//True is one way false is other...depends on motor connection
boolean IsMoving = false;
boolean Absolute = true;
volatile int MaxIncrement=16384;//not yet used

//Stepper.h control variables
Stepper myStepper = Stepper(200, 33, 35, 37, 39);
//END OF FOCUS CONTROL INITIALISE

//Cloud Sensor Setup
char st1[30];
long int tpl; //Cloud sensor variable
long int CS_ObjTemp;
long int CS_AmbTemp;

//Serial comms setup
char incomingByte = 0; // serial in data byte
byte serialValue = 0;
boolean usingSerial = true; // set to false to have the buttons control everything
char gCommandBuffer[MAX_COMMAND_LEN + 1];
char gParamBuffer[MAX_PARAMETER_LEN + 1];
long gParamValue;
volatile boolean UPDATE = true;
typedef struct {
char const *name;
void (*function)(void);
}
command_t;

//Set up a command table. when the command "IN" is sent from the PC and this table points it to the subroutine to run
command_t const gCommandTable[COMMAND_TABLE_SIZE] = {
{
"IN1", FocusINFun, }
,
{
"OUT", FocusOUTFun, }
,
{
"STP", FocusSTEPSFun, }
,
{
"SPD", FocusSPEEDFun, }
,
{
"LMT", FocusSLimitFun, }
,
{
"POS", FocusSPositionFun, }
,
{
"MDE", FocusSModeFun, }
,
{
"TYP", FocusSTypeFun, }
,
{
"TMP", CloudGetTempFun, }
,
{
NULL, NULL }
};
//Serial Comms setup end

void setup() {
if(MotorType==1){
Servo myservo;
myservo.attach(SERVO_PIN);
}
pinMode(dirPin, OUTPUT); //Initialise Easydriver output
pinMode(stepperPin, OUTPUT); //Initialise easy driver output
pinMode (ms1, OUTPUT);
pinMode (ms2, OUTPUT);
//START OF FOCUS CONTROL SETUP
lcd.begin(16, 2);
//END OF FOCUS CONTROL SETUP
Serial.begin(19200);// start the serial

PORTC = (1 << PORTC4) | (1 << PORTC5); //enable internal pullup resistors on i2c ports
myStepper.setSpeed(SPEED);
NoOfSteps=1000;
}

void loop() {

int bCommandReady = false;

digitalWrite(ms1, HIGH);
digitalWrite(ms2, HIGH);

//If There is information in the Serial buffer read it in and start the Build command subroutine
if (usingSerial && Serial.available() >= 1) {
// read the incoming byte:
incomingByte = Serial.read();
delay(250);
if (incomingByte == '#') {
/* Build a new command. */
bCommandReady = cliBuildCommand(incomingByte);
}
}
else
{
incomingByte=0;
//Serial.flush();
}

//If there is a command in the buffer then run the process command subroutine
if (bCommandReady == true) {
bCommandReady = false; // reset the command ready flag
cliProcessCommand(); // run the command
}

if (UPDATE){
UPDATE=false;
FocusPrintStepsFun(); //Print the number of steps
FocusPrintPositionFun(); //Print the Position
SerialDATAFun(); // debug mainly, gives detailed information about the current state of the machine

}

}

//***************************************************
//Start of User defined Functions **************
//
**********************************************

//START OF FOCUS CONTROL FUNCTIONS

void FocusPrintStepsFun (void) {//Print the number of steps required on the 1st line of the LCD display
lcd.setCursor(0, 0);
//lcd.clear();
lcd.print("Steps = ");
lcd.print(NoOfSteps);
lcd.print(" ");
}

void EasyDriverStep(boolean dir,int steps){
digitalWrite(dirPin,dir);
delay(100);
for(int i=0;i<steps;i++){
digitalWrite(stepperPin, HIGH);
delayMicroseconds(500);
digitalWrite(stepperPin, LOW);
delayMicroseconds(500);
}
}

void FocusPrintPositionFun (void) {//Print the current position on the second line of the LCD, this is not absolute.
lcd.setCursor(0, 1);
//lcd.clear();
lcd.print("Position = ");
lcd.print(Position);
lcd.print(" ");

}

void FocusINFun (void) {//Move the Stepper IN.
int Steps = 0;

switch (MotorType){
case 0:
//Serial.println("Stepper Focus IN"); // add stepper movement function and call it here
// will need to 'reset' the arduino via serial to invoke the motor code?
// we need to start saving data in eeprom, it will make things much easier.
// will need to use double the amount of eeprom space for the variables
// one set for the user data and 1 set for defaults. Also means we can start to pack
// some flags as bits
break;

case 1:
//Serial.println("Servo Focus IN"); // Call the servo focus in function
break;

case 2:
//Serial.println("DC Focus IN");

break;
}

if (Absolute == false) { //If not Absolute move the number of steps
if ((Position-NoOfSteps)>=0) {
//myStepper.step (NoOfSteps);
EasyDriverStep(true,NoOfSteps);
Position=Position-NoOfSteps;
}
}
else if (NoOfSteps < MaxStep) //Absolute :- work out the number of steps to take based on current position
{
if (NoOfSteps<Position){

Steps=(Position-NoOfSteps);
//myStepper.step (Steps);
EasyDriverStep(true,Steps);
Position=NoOfSteps;
}
else
{
Steps=(NoOfSteps-Position);
//myStepper.step (Steps);
EasyDriverStep(false,Steps);
Position=NoOfSteps;
}
}
// set the update flag so that the new position is displayed
IsMoving=true;
UPDATE=true;
}

void FocusOUTFun (void) {//Move the Stepper OUT.
int Steps = 0;

if (Absolute == false) { //If not Absolute move the number of steps
if ((Position+NoOfSteps)<=MaxStep) {
//myStepper.step (NoOfSteps);
EasyDriverStep(false,NoOfSteps);
Position=Position+NoOfSteps;
}
}
else if (NoOfSteps < MaxStep) //Absolute :- work out the number of steps to take based on current position
{
if (NoOfSteps<Position){

Steps=(Position-NoOfSteps);
//myStepper.step (Steps);
EasyDriverStep(true,Steps);
Position=NoOfSteps;
}
else
{
Steps=(NoOfSteps-Position);
//myStepper.step (Steps);
EasyDriverStep(false,Steps);
Position=NoOfSteps;
}
}
// set the update flag so that the new position is displayed
IsMoving=true;
UPDATE=true;
}

void FocusSTEPSFun (void) {//Set the number of Steps.
NoOfSteps = gParamValue;
// s

The errors indicate that - for some reason - your compiler cannot find the library you are trying to use.

First, I suggest that you try to place the "#include <i2cmaster.h>" line before the other includes as sometimes small things have surprisingly big consequences..

Second, you should recheck (once more) that you have put the "twimaster.cpp" and "i2cmaster.h" files it in a right place (i.e., /{arduino root}/hardware/libraries for older Arduino sw, /{arduino root}/libraries for the newer ones).

Inside the correct library folder you should see other folders, for example, "Servo", "SorftwareSerial", "Wire", etc.. I named my folder as "I2Cmaster" and put the two files inside that.

After that YOU HAVE TO create a separate file called "keywords.txt" inside the very same folder. You can copy/paste the lines that I have in my keyword file at the end of this post. Without this file the Arduino software cannot automatically figure out what you've defined in your library.. A bit stupid, yes, but that's the way it's done. The Arduino environment has to be closed (if running) as it is documented to find the new stuff only when started.

Given just a quick glance the code otherwise seems valid although it does not really show neither the readMLXtemperature(int) function nor where you call it. Just to check the other part of the code you can comment the function and the library include to see if it otherwise compiles ok.

#######################################
# Syntax I2Cmaster
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

#######################################
# Methods and Functions (KEYWORD2)
#######################################
i2c_init            KEYWORD2
i2c_stop            KEYWORD2
i2c_start            KEYWORD2
i2c_rep_start      KEYWORD2
i2c_start_wait      KEYWORD2
i2c_write            KEYWORD2
i2c_readAck            KEYWORD2
i2c_readNak            KEYWORD2
i2c_read            KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################

Thanks Jukka && SensorJunkie...followoing your instructions it works!! :slight_smile:
I'll check how to adjust it to get the info only every 10 minutes...

hi all,

new to the conversation, I am curious if anyone has tried using the PWM output mode of this device instead of the SMBus. It seems like this would be much easier. That is, assuming one would be able to correctly configure it for PWM mode. The datasheet seems to say that EEPROM value PWMCTRL at address 0x003 would need to be changed. (I do not know how to do that... new to Arduino and microcontrollers)

however, after that step, the device would appear to be quite easy to read from. Am I missing something?

I just purchased this device on a board from Parallax because I thought it might be easier to interface but after further reading I am not so sure... didn't receive the device yet.

I've tried EVERY bit of code I can find and I can't get squeak out of this sensor!
When I try the i2cmaster library, I can't get any output on the serial monitor.
I'm now trying the code sensorJunky posted and still no output on the serial monitor.
I'm going to have to get the CRO home!
I think I've been spoilt by the other I2C devices I've tried, HMC6352, eeproms, my uM FPU!

cyberteque, did you see the notes about pull-up resistors in the older posts on this thread?

This device is SMBus protocol, not I2C so that is one reason, I assume, that many are having trouble.

I am a beginner so be careful with my advice ; ) but one thing I have recently found is here:

maybe it will help. I still like the idea of setting up this device to output PWM instead of communicating on the SMBus.. however I will have to first figure out how to make it do that.

I tried the 4.7K pull up resistors, but that didn't work.
There is another document on the Melexis site, I'll post the address later, it has "preliminary" stamped all over it, but it does look hopeful.
I'm going to have another go at it when I get my Tektronics storage CRO home, I think I'll have more luck.

On thing to bare in mind is SparkFun has an evaluation board for the MLX90614

If you have a look at the schematic

They have just hooked the sensor up to the I2C port, no pull ups!

Unfortunately the link on github is broken, so I've not been able to download their source.

Has anyone found out why using the i2cmaster library prevents the UART working?
As a few people have pointed out, even a simple "Hello World" no longer works on the serial monitor!

The PWM output is going to be a "chicken and egg" problem, you'll have to make it work over I2C to set it up!

As I'm going to use this sensor in my "tricorder" thing, I was going to mount it in a "wand", along with some gas sensors.
My idea is to use a separate ATMEGA in the wand and communicate back to the main unit via serial link.

I already have 10 devices on my I2C bus, an HMC6352 digital compass, a DS1307 RTC and 8 24LC256 EEPROMS, I'll also have a temperature and humidity sensor when it arrives, that'll make 11, 12 if I put my uM-FPU V3 on the I2C bus, but I think I'll keep that on the SPI bus along with my MPL115A.

From what I've read SMB and I2C devices are going to be "difficult" to have on the same bus.
So a dedicated controller in the "wand" seems like a good idea.
I've already ordered a few ATmega328's pre-programmed with the Arduino bootloader, I've found the keypad library a bit "twitchy" when you have a lot of stuff going on.
So I was going give my keypad it's own controller to scan the keys, make the key press "beep" and do some other stuff.

This project is taking on a life of it's own!
I'll have to start documenting it now it has the beginnings of a case.
And before you ask, yes, my Mega still has a few port pins I'm not using, yet.

oh! I probably should have purchased the sparkfun board. thinking back... i probably did not do that because it runs at 3.3V and I wanted to run at 5V and because I wanted the 10degree field of view. It could be that this board works due to running at the lower voltage... it might be more compatible with SMBus at that level.

I purchased the Parallax board with this sensor but I have not actually tried it yet. One thought I had is to find another development board that could do SMBus native and use that to set it to PWM output... but in order to try that I may have to purchase a bare sensor.

here's one more off the wall thought.. sparkfun has this temp gun.

and it appears to use this sensor inside it. A person could buy this and then hack it.