MLX90614 and setting emissivity - bad values for temperature returned

Hi all-

Anyone working with the MLX90614 and try to set the emissivity on the fly? I’m trying to see how to modify the emissivity on the fly so if you’ve got a known temperature object, you can tweak the emissivity on the fly when measuring with some other device.

With two different units, and two different Arduino boards, I occasionally get odd temperatures (wildly negative) values are returned when switching between emissivities. I’m using a raw MLX90614ESF-DAA-000-SP (3.3 V, but medical grade). The Sparkfun version is MLX90614ESF-BAA, and still 3.3V.

Thoughts? I’m using 4.7K pullups; would 10K pullups (Adafruit suggestion- they sell this sensor as well, but their library doesn’t have emissivity reading/setting) make a difference (using short jumpers to the Arduino)? A 0.1 uF cap across 3.3V and GND at the sensor still occasionally gives the same errors:

737,Emissivity: 0.99,152710,-103.17,-625.87
738,Emissivity: 0.99,152813,-103.69,-625.87
739,Emissivity: 0.99,152915,-103.69,-625.87
740,Emissivity: 0.99,153019,-103.69,-625.87
Changing emissivity.
741,Emissivity: 0.50,154145,-100.15,-625.87
742,Emissivity: 0.50,154248,-99.53,-625.87
743,Emissivity: 0.50,154351,-99.85,-625.85
744,Emissivity: 0.50,154455,-100.15,-625.89

I noticed in the data sheet it says to set the register (0x04) to zero first, then send the emissivity value, then read it back, but the Sparkfun code doesn’t seem to set it to zero first.

Note:

https://www.melexis.com/en/documents/do … ty-setting

Code is below. This flips between two different emissivities every reads. When the values get bad, and I download the Sparkfun emissivity code, the bad temperature values still remain.

/******************************************************************************
  MLX90614_Serial_Demo.ino
  Serial output example for the MLX90614 Infrared Thermometer

  This example reads from the MLX90614 and prints out ambient and object
  temperatures every half-second or so. Open the serial monitor and set the
  baud rate to 9600.

  Hardware Hookup (if you're not using the eval board):
  MLX90614 ------------- Arduino
  VDD ------------------ 3.3V
  VSS ------------------ GND
  SDA ------------------ SDA (A4 on older boards)
  SCL ------------------ SCL (A5 on older boards)

  An LED can be attached to pin 8 to monitor for any read errors.

  Jim Lindblom @ SparkFun Electronics
  October 23, 2015
  https://github.com/sparkfun/SparkFun_MLX90614_Arduino_Library

  Development environment specifics:
  Arduino 1.6.5
  SparkFun IR Thermometer Evaluation Board - MLX90614

  Arduino Pro or Pro Mini
  AT mega328 (3.3V 8 MHz)

******************************************************************************/

#include <Wire.h> // I2C library, required for MLX90614
#include <SparkFunMLX90614.h> // SparkFunMLX90614 Arduino library

IRTherm therm; // Create an IRTherm object to interact with throughout

const byte LED_PIN = 8; // Optional LED attached to pin 8 (active low)
float fEmissivity = 0.99;
float fEmissivityA = 0.99;
float fEmissivityB = 0.5;
long nCounter = 0;
boolean bValue;

void(* resetFunc) (void) = 0;  // declare reset fuction at address 0

void setup()
{
  Serial.begin(9600); // Initialize Serial to log output
  therm.begin(); // Initialize thermal IR sensor
  therm.setUnit(TEMP_C); // Set the library's units to C
  // Alternatively, TEMP_F can be replaced with TEMP_C for Celsius or
  // TEMP_K for Kelvin.
  therm.setEmissivity(fEmissivity);
  delay(1000);

  pinMode(LED_PIN, OUTPUT); // LED pin as output
  setLED(LOW); // LED OFF
}

void loop()
{

  // readEmissivity() can be called to read the device's
  // configured emissivity -- it'll return a value between
  // 0.1 and 1.0.
  Serial.print(nCounter);
  Serial.print(",");
  Serial.print ("Emissivity: " + String(therm.readEmissivity()));
  Serial.print(",");

  setLED(HIGH); //LED on

  // Call therm.read() to read object and ambient temperatures from the sensor.
  if (therm.read()) // On success, read() will return 1, on fail 0.
  {
    // Use the object() and ambient() functions to grab the object and ambient
    // temperatures.
    // They'll be floats, calculated out to the unit you set with setUnit().
    Serial.println(String(millis()) + "," + String(therm.object(), 2) + "," + String(therm.ambient(), 2));
  }
  setLED(LOW);
  delay(100);

  if ((nCounter % 10) == 0)
  {
    Serial.println("Changing emissivity.");
    if (fEmissivity == fEmissivityA)
      fEmissivity = fEmissivityB;
    else
      fEmissivity = fEmissivityA;

    // Call setEmissivity() to configure the MLX90614's
    // emissivity compensation:
    bValue=therm.setEmissivity(fEmissivity);
    if(bValue==true)
    {
      
    }
    else
    {  
      Serial.println("failing to set emissivity.");
    }
 
    
    delay(1000);
  }

  // reset if bad values
  //if(therm.object()<-40)
  //{
  //  resetFunc();
  //}

  nCounter = nCounter + 1;

}



void setLED(bool on)
{
  if (on)
    digitalWrite(LED_PIN, LOW);
  else
    digitalWrite(LED_PIN, HIGH);
}