adafruit / Adafruit-MLX90614-Library

Arduino library for the MLX90614 sensors in the Adafruit shop
Other
128 stars 97 forks source link

MLX90614 reports large negative values (ie -178 celsius) after setting emissivity #32

Closed dmalawey closed 1 year ago

dmalawey commented 3 years ago

Error of Large Negative Temperatures

This issue takes place using either library (adafruit or sparkfun) and has details posted in the issue below.

The basic behavior:

caternuson commented 3 years ago

Change or even reset MLX sensor

By change, do you mean just change emissivity?

dmalawey commented 3 years ago

Change or even reset MLX sensor

By change, do you mean just change emissivity?

Oops! I meant: Set the emissivity value (to the SAME or DIFFERENT) value. Both of these actions can produce the error.

caternuson commented 3 years ago

Just ran this:

#include <Adafruit_MLX90614.h>

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

void setup() {
  Serial.begin(9600);
  while(!Serial);

  Serial.println("Adafruit MLX90614 test");

  if (!mlx.begin()) {
    Serial.println("Error connecting to MLX sensor. Check wiring.");
    while (1);
  };

  Serial.println("Emissivity = default");
  Serial.print("Ambient = "); Serial.print(mlx.readAmbientTempC());
  Serial.print("*C\tObject = "); Serial.print(mlx.readObjectTempC()); Serial.println("*C");
  Serial.println("Emissivity = 0.8");
  mlx.writeEmissivity(0.8);
  Serial.print("Ambient = "); Serial.print(mlx.readAmbientTempC());
  Serial.print("*C\tObject = "); Serial.print(mlx.readObjectTempC()); Serial.println("*C"); 
}

void loop() {
}

And it ran as expected. Screenshot from 2021-08-05 14-56-12

Can you provide a simple example sketch that demonstrates the issue?

dmalawey commented 3 years ago

Sure thing.

Here is a .ino file that's based on the plain adafruit library. The difference is that we set the emissivity several times.

Link to the code on gist

Characteristics

  1. The error takes place at random. Not every change of emissivity results in error.
  2. The recovery takes place at random. Sometimes it recovers by writing the emissivity again.
  3. The recovery may also take place just by reading the temp a few more times, without re-writing emissivity. But this is more rare.

Output that I get:

At the first upload, using my code linked above. image

caternuson commented 3 years ago

Thanks for the example. I'm seeing the same thing.

Is there a reason you need to continuously change the emissivity like that?

dmalawey commented 3 years ago

Is there a reason you need to continuously change the emissivity like that?

Ha ha not at all. I only want to change the emissivity on occasion and when I do, it can cause the error with just one change. In my engineering application, I need the device to boot, set emissivity, and log data. Since I can't trust the data to be clean after a given emissivity change, I can't deploy the device yet.

Additional Clue for Root Cause

Does the library perform the writing of 0's to the emissivity register as instructed in the datasheet?

image

caternuson commented 3 years ago

Checkout this app note: https://www.melexis.com/en/documents/documentation/application-notes/application-note-mlx90614-changing-emissivity-setting

EEPROM is persistent memory, so the value will remain with each power cycle. Per that app note, you also need to reset after setting for the new value to take effect. So it doesn't seem like you can change this value dynamically. But this should be OK for your application. Make a sketch that sets the emissivity to the value you want and nothing else. Then power cycle and change to your real application to use the new value. emis

dmalawey commented 3 years ago

Is it possible to "restart" the module using a function in the library? Is a full power cycle necessary? With the MLX tied to 3.3v and GND of my microcontroller, I don't think I could power cycle unless I unplug the whole MCU.

caternuson commented 3 years ago

It doesn't look there is a reliable way other than power on/off.

Entering/exiting sleep mode might work: image

But that is only available for the 3V version: image

Could maybe try that second bullet approach, but those pins are already in use by the I2C bus.

As another idea - could set emissivity=1.0 on the MLX and then do your own compensation in user code for other emissivity values.

dmalawey commented 3 years ago

Thank you for these suggestions. Thanks even more for your attention and fast responses.

For an immediate countermeasure, I am tying the MLX90614 GND pin to a digital output pin D4 on my MCU. After writing the emissivity, I raise D4 high, wait 50ms, and lower D4 again.

This appears to be working so far. If there is no further action to be taken I can close the issue.

caternuson commented 1 year ago

Closing. Seems resolved.

TheStranger25 commented 1 year ago

Hi all, I'm having the same problem but setting the 0x04 register to 0 doesn't work for me. Also I saw that it is already done inside the MLX SetEmissivity function. How can I solve it?