MLX90614 emissivity error

Hello, my code is for an MLX90614 sensor. I'm measuring the temperature and changing the emissivity setting for different surfaces. But sometimes, about 1 in 10 times, when I click to set the emissivity, the temperature read by the sensor is absurd—either in the hundreds or even negative. I'm having difficulty finding the problem because it happens randomly.



This is my code:


#include <Wire.h>
#include <Adafruit_MLX90614.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>

#define i2c_Address 0x3c

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_MLX90614 mlx = Adafruit_MLX90614();


const long interval = 1000;
const long interval_SET_E = 1000;
unsigned long lastDebounceTime = 0;
unsigned long dernierTemps = 0;
unsigned long dernierTemps_SET_E = 0;
const int delaiDebounce = 50;


int lastButtonState_CF = HIGH;
int compteur_temp = 0;


float object_temp_C;
float object_temp_c;
float object_temp_f;
int ambient_temp_c;
int ambient_temp_f;


const int BD_LASER = 2;
const int B_CF = 3;
const int B_E = 4;

const int DIODE_LASER = 12;
float pin_pot = A3;

int BD_State = 0;



float Valeur_E = 1;
double emissivity = 1;
double new_emissivity = 1;
double new_emissivity_2;

bool lastButtonState_BE = LOW;
bool etatMODE_BE = LOW;


enum Etat {
  INITIALISATION,
  ATTENTE,
  AQUISITION,
  SETE
};

Etat etatActuel = AQUISITION;
bool etatMODE_CF = LOW;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  mlx.begin();

  delay(250);
  display.begin(i2c_Address, true);
  mlx.writeEmissivity(1.0);


  pinMode(DIODE_LASER, OUTPUT);
  pinMode(BD_LASER, INPUT_PULLUP);
  pinMode(B_CF, INPUT_PULLUP);
  pinMode(B_E, INPUT_PULLUP);

  display.clearDisplay();
  display.setTextColor(SH110X_WHITE);
  display.setTextSize(1);
  display.setCursor(0, 20);
  display.print("Thermometre 2.3");
  display.display();

  delay(2000);
}


void mesureIR() {
  object_temp_c = mlx.readObjectTempC();
  object_temp_f = mlx.readObjectTempF();
}


void affichage_c() {

  display.clearDisplay();
  display.setTextColor(SH110X_WHITE);
  display.setTextSize(2);

  display.setCursor(28, 20);
  display.print(object_temp_c);
  display.print((char)247);
  display.print("C");


  display.setTextSize(1);
  display.setCursor(8, 55);
  display.print("Temp Ambiante: ");
  display.print(ambient_temp_c);
  display.print((char)247);
  display.print("C");

  display.setCursor(8, 0);
  display.print("E:");
  display.print(new_emissivity);

  display.display();

  // Serial.println(object_temp_c);
}

void affichage_f() {

  display.clearDisplay();
  display.setTextColor(SH110X_WHITE);
  display.setTextSize(2);

  display.setCursor(28, 20);
  display.print(object_temp_f);
  display.print((char)247);
  display.print("F");


  display.setTextSize(1);
  display.setCursor(8, 55);
  display.print("Temp Ambiante: ");
  display.print(ambient_temp_f);
  display.print((char)247);
  display.print("F");

  display.setCursor(8, 0);
  display.print("E:");
  display.print(new_emissivity);

  display.display();

  // Serial.println(object_temp_f);
}


void affichage_k() {

  float object_temp_k = (object_temp_c + 273);
  int ambient_temp_k = (ambient_temp_c + 273);

  display.clearDisplay();
  display.setTextColor(SH110X_WHITE);
  display.setTextSize(2);

  display.setCursor(28, 20);
  display.print(object_temp_k);
  display.print("K");


  display.setTextSize(1);
  display.setCursor(8, 55);
  display.print("Temp Ambiante: ");
  display.print(ambient_temp_k);
  display.print((char)247);
  display.print("K");

  display.setCursor(8, 0);
  display.print("E:");
  display.print(new_emissivity);

  display.display();

  // Serial.println(object_temp_k);
}

void affichage_set_e() {
  display.clearDisplay();
  display.setTextColor(SH110X_WHITE);
  display.setTextSize(2);

  display.setCursor(28, 20);
  display.print("E:");
  display.print(new_emissivity);

  display.setTextSize(1);
  display.setCursor(8, 55);
  display.print("Temp Ambiante: ");
  display.print(ambient_temp_c);
  display.print((char)247);
  display.print("C");

  display.display();
}

void diode() {
  digitalWrite(DIODE_LASER, true);
}

void loop() {


  ambient_temp_c = mlx.readAmbientTempC();
  ambient_temp_f = mlx.readAmbientTempF();


  BD_State = digitalRead(BD_LASER);
  bool BE_State = digitalRead(B_E);
  bool B_CF_State = digitalRead(B_CF);
  unsigned long tempsActuel = millis();

  //------------------------------------------------------- etat bouton d'affichage CFK
  if (B_CF_State == LOW && lastButtonState_CF == HIGH && (tempsActuel - dernierTemps > delaiDebounce)) {
    compteur_temp++;
  }
  dernierTemps = tempsActuel;

  lastButtonState_CF = B_CF_State;

  // -------------------------------------------------------- etat bouton de mesure avec emissivité
  if ((millis() - lastDebounceTime) > delaiDebounce) {
    if (BE_State == LOW && lastButtonState_BE == HIGH) {
      etatMODE_BE = !etatMODE_BE;
      lastDebounceTime = millis();
    }
  }
  lastButtonState_BE = BE_State;


  switch (compteur_temp) {
    case 0:
      affichage_k();
      if (etatMODE_BE == true) {
        compteur_temp = 4;
      }
      break;
    case 1:
      affichage_c();
      if (etatMODE_BE == true) {
        compteur_temp = 4;
      }
      break;
    case 2:
      affichage_f();
      if (etatMODE_BE == true) {
        compteur_temp = 4;
      }
      break;
    case 3:
      affichage_k();
      compteur_temp = 0;
      break;
    case 4:
      affichage_set_e();
      if (etatMODE_BE == false) {
        compteur_temp = 1;
      }
      break;
  }

  switch (etatActuel) {

    case INITIALISATION:
      digitalWrite(DIODE_LASER, false);
      etatActuel = ATTENTE;
      Serial.println("INTITIALISATION");
      break;


    case ATTENTE:

      digitalWrite(DIODE_LASER, false);

      if (BD_State == true) {
        etatActuel = AQUISITION;
      }

      if (etatMODE_BE == true) {
        etatActuel = SETE;
      }


      break;



    case AQUISITION:

      if (BD_State == false) {
        etatActuel = ATTENTE;
        digitalWrite(DIODE_LASER, false);
      }
      mesureIR();

      if (compteur_temp == 1) {
        affichage_c();
      } else if (compteur_temp == 2) {
        affichage_f();
      } else if (compteur_temp == 3) {
        affichage_k();
      }


      diode();

      break;


    case SETE:

      int valeur_pot = analogRead(pin_pot);
      new_emissivity = 0.09 + (float(valeur_pot) / 1023) * 0.9;
      Serial.println(new_emissivity);
      affichage_set_e();

      if (etatMODE_BE == 0) {

        mlx.writeEmissivity(new_emissivity);
        Serial.print("Emissivité appliquée: ");
        Serial.println(new_emissivity);

        etatActuel = ATTENTE;
      }

      break;
  }
}```

Please translate the pictures to ordianry schematics. I strongly doubt any helper will decrypt the pictures and make schematics.

Emissivity correction is tricky as it can overflow. Write a very short program just reports some temperatures, with adjustable emissivity values, and debug that with lots of Serial.print statements.

I have already tried that, but the error is random. I also tried adding a delay but it does not work.

The picture are not for the schematics but are for what the screen shows.

Keep a debug log and check the values of key variables when the "random" error occurs.

99% of the posted program is irrelevant to the error.

There's no use for them else then gerally show the build.

I found a solution! If you hard reset the sensor by unplugging it, the new emissivity value is retained. So, we can perform the hard reset by connecting the sensor's VIN to a digital pin and setting that pin HIGH. When you send the new value, set the pin LOW, wait 50ms, and then set it HIGH again.