Erratic error on mqtt and min / max array values

Hello,

I'm running the program below on an arduino mega with an ethernet shield.

The purpose of the program is to :

  • Read temperature and humidity
  • Store the min & max temperature of the last 8 hours
  • Send those 4 information on mqtt local server and on adafruit
  • Record temperature on SD card

All is working fine except the min & max value that is returning -1000 and +1000.

I can't understand why, and the code was running fine a month sending consistent values on the mqtt local (but always sent -1000 and +1000 on Adafruit). I had to replace the sensor so it was off for a little while and since it's back in service I have -1000 and +1000 on local and adafruit. Very strange.

Any clue why ?

Thanks.

/************************* Library ***************************/
#include <SPI.h>
#include "Adafruit_MQTT_Client.h"
#include <Ethernet.h>
#include <SD.h>
#include "DFRobot_SHT20.h"
#include <Wire.h>

/************************* Ethernet Client Setup *****************************/
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEC};
IPAddress myDns(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

/************************* SD *********************************/
const int chipSelect = 4;

/************************* MQTT brokers *********************************/
#define Local_SERVER      "192.168.1.65"
#define Local_SERVERPORT  1883
#define Local_USERNAME    "xxxxxxx"
#define Local_KEY         "xxxxxxx"

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883
#define AIO_USERNAME    "xxxxxxxx"
#define AIO_KEY         "xxxxxxxx"

/************************* Time global *********************************/
unsigned long action_AIO = 0;
unsigned long action_Local = 0;
unsigned long action_SD = 0;
#define intervale_publication_AIO 10000 // 	10secs 	Between each publication on internet 
#define intervale_publication_Local 5000 //  	4secs	Between each publication on local network 
#define intervale_publication_SD 1800000 //	30mins	Between each publication on SD card
unsigned long temps = 0;



/************************* Array & tests *********************************/
#define interval_array 3600000         // Time between update of each value
#define interval_update_array 5000  // Time between each update of the same value of the array 
#define size_array 10                // Number of value of the array 

long time_array = 0 ;
long time_update =0 ; 
byte index = 1 ;
float temp_max_tempo ; 
float temp_min_tempo ; 
float array_max [size_array];
float array_min [size_array];
float temperature_loop ; 
float global_max_val ;
float global_min_val ;

/************ Global State ******************/

//Set up the ethernet client
EthernetClient client;
EthernetClient client2;
Adafruit_MQTT_Client mqtt_Local(&client, Local_SERVER, Local_SERVERPORT, Local_USERNAME, Local_KEY);
Adafruit_MQTT_Client mqtt_AIO(&client2, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

// You don't need to change anything below this line!
#define halt(s) { Serial.println(F( s )); while(1);  }


/************************* Input Setup *********************************/

//#define adresseI2CduBME280  0x76          
//Adafruit_BME280 bme;
//unsigned long action = 0;
DFRobot_SHT20    sht20;

/****************************** Feeds ***************************************/

Adafruit_MQTT_Publish Local_publi_temperature = Adafruit_MQTT_Publish(&mqtt_Local,  Local_USERNAME "/feeds/temperature");
Adafruit_MQTT_Publish Local_publi_humidite = Adafruit_MQTT_Publish(&mqtt_Local,  Local_USERNAME "/feeds/humidite");
Adafruit_MQTT_Publish Local_publi_max_temp = Adafruit_MQTT_Publish(&mqtt_Local,  Local_USERNAME "/feeds/max_temp");
Adafruit_MQTT_Publish Local_publi_min_temp = Adafruit_MQTT_Publish(&mqtt_Local,  Local_USERNAME "/feeds/min_temp");

Adafruit_MQTT_Publish AIO_publi_temperature = Adafruit_MQTT_Publish(&mqtt_AIO,  AIO_USERNAME "/feeds/temperature");
Adafruit_MQTT_Publish AIO_publi_humidite = Adafruit_MQTT_Publish(&mqtt_AIO,  AIO_USERNAME "/feeds/humidite");
Adafruit_MQTT_Publish AIO_publi_max_temp = Adafruit_MQTT_Publish(&mqtt_AIO,  AIO_USERNAME "/feeds/max_temp_2");
Adafruit_MQTT_Publish AIO_publi_min_temp = Adafruit_MQTT_Publish(&mqtt_AIO,  AIO_USERNAME "/feeds/min_temp");

/*------------------------------------ Setup ------------------------------------*/


void setup() 
{
  Serial.begin(9600);
  Serial.println(F("Debut programme"));
  Serial.print(F("\nInit the Client..."));
  Ethernet.begin(mac);
  delay(500); //give the ethernet time to initialize
  //bme.begin(adresseI2CduBME280);
  sht20.initSHT20();                                  
  delay(100);
  sht20.checkSHT20();    

  
  temp_min_tempo = sht20.readTemperature() ; 
  temp_max_tempo = sht20.readTemperature() ; 
  temp_min_tempo = sht20.readTemperature() ;  
  temp_max_tempo = sht20.readTemperature() ;  
  global_max_val = sht20.readTemperature() ; 
  global_min_val = sht20.readTemperature() ;
  for (int i=0; i < size_array; i++)
   {
    array_max [i] = sht20.readTemperature();
    array_min [i] = sht20.readTemperature();
   }

  if (!SD.begin(chipSelect)) 
  {
    Serial.println("Card failed, or not present");
    return;
  }

  Serial.println(F("Setup all good"));
  }




/*------------------------------------ Loop ------------------------------------*/

void loop() 
{

  temps = millis();
  temperature_loop = sht20.readTemperature();
  global_max_val = -1000;
  global_min_val = 1000;
  MQTT_AIO_connect() ;
  MQTT_Local_connect() ;



    if((millis() - time_update) > interval_update_array) // Update of the current array position if temperature > / <
    {
      //Serial.print("Check value #");Serial.println(index);

      if (temp_max_tempo < temperature_loop)
        {
          array_max[index] = temperature_loop;
          temp_max_tempo = temperature_loop; 
          //Serial.println("UPDATE");
        }
        
        if (temp_min_tempo > temperature_loop)
        {
          array_min[index] = temperature_loop;
          temp_min_tempo = temperature_loop; 
        }
        for (int i=0; i < size_array; i++)  // Check what is the biggest vallue in both array    
        {
          if (array_max[i] > global_max_val)
          {
            global_max_val=array_max[i];
          }
          if (array_min[i] < global_min_val)
          {
            global_min_val=array_min[i];
          }
        }

        time_update = millis(); 
    }   
    
  if((millis() - time_array) > interval_array) //Switch of array position and reset of old values
    {
      index = index + 1; 
      if(index >= size_array) 
       {
         index = 0 ;
       }

      temp_max_tempo = temperature_loop; ;
      temp_min_tempo = temperature_loop; ;
      array_max[index] = temperature_loop;
      array_min[index] = temperature_loop;

      time_array = millis(); 

    }   

    if ( ( temps - action_Local ) > intervale_publication_Local ) //Publication toutes les x secondes sur le MQTT Local
    {
 
        action_Local = temps ;
        Local_publi_temperature.publish(sht20.readTemperature()) ;
        Local_publi_humidite.publish(sht20.readHumidity()) ;
        Local_publi_max_temp.publish((float)global_max_val);
        Local_publi_min_temp.publish((float)global_min_val);

    }

    if ( ( temps - action_AIO ) > intervale_publication_AIO ) //Publication toutes les x secondes sur le MQTT Internet
    {
 
        action_AIO = temps;
        AIO_publi_temperature.publish(sht20.readTemperature()) ;
        AIO_publi_humidite.publish(sht20.readHumidity()) ;
        AIO_publi_max_temp.publish((float)global_max_val);
        AIO_publi_min_temp.publish((float)global_min_val);
 
    }

    if ( ( temps - action_SD ) > intervale_publication_SD ) //Publication toutes les x secondes sur la carte SD
    {

      File dataFile = SD.open("Temp_log.txt", FILE_WRITE);
      if (dataFile) 
      {
        dataFile.println(temperature_loop);
        dataFile.close();
        Serial.println("Ecriture SD");

      }
      else 
      {
        Serial.println("error opening datalog.txt");
      }
    }

  if(! mqtt_AIO.ping()) // ping the server to keep the mqtt connection alive
  {
    mqtt_AIO.disconnect();
  }

  if(! mqtt_Local.ping()) 
  {
    mqtt_Local.disconnect();
  }

}

/************************* Voids *****************************/


void MQTT_AIO_connect() 
{
  int8_t ret;

  // Stop if already connected.
  if (mqtt_AIO.connected()) 
  {
    return;
  }

  Serial.print("Connecting to MQTT AIO... ");

  while ((ret = mqtt_AIO.connect()) != 0) { // connect will return 0 for connected
       Serial.println(mqtt_AIO.connectErrorString(ret));
       Serial.println("Retrying MQTT AIO connection in 5 seconds...");
       mqtt_AIO.disconnect();
       delay(5000);  // wait 5 seconds
  }
  Serial.println("MQTT AIO Connected!");
}


void MQTT_Local_connect() 
{
  int8_t ret2;

  // Stop if already connected.
  if (mqtt_Local.connected()) 
  {
    return;
  }

  Serial.print("Connecting to MQTT Local... ");

  while ((ret2 = mqtt_Local.connect()) != 0) { // connect will return 0 for connected
       Serial.println(mqtt_Local.connectErrorString(ret2));
       Serial.println("Retrying MQTT Local connection in 5 seconds...");
       mqtt_Local.disconnect();
       delay(5000);  // wait 5 seconds
  }
  Serial.println("MQTT Local Connected!");
}

Time to add some debugging serial prints.

I can extract the bit of code that runs the arrays and check for min & max.

But the code was running fine for smth like 25 days, publishing consistent values on the local mqtt.

  temps = millis();
  temperature_loop = sht20.readTemperature();
  global_max_val = -1000;
  global_min_val = 1000;


    if((millis() - time_update) > interval_update_array) // Update of the current array position if temperature > / <
    {
      //Serial.print("Check value #");Serial.println(index);

      if (temp_max_tempo < temperature_loop)
        {
          array_max[index] = temperature_loop;
          temp_max_tempo = temperature_loop; 
          //Serial.println("UPDATE");
        }
        
        if (temp_min_tempo > temperature_loop)
        {
          array_min[index] = temperature_loop;
          temp_min_tempo = temperature_loop; 
        }
        
        for (int i=0; i < size_array; i++)  // Check what is the biggest vallue in both array    
        {
          if (array_max[i] > global_max_val)
          {
            global_max_val=array_max[i];
          }
          if (array_min[i] < global_min_val)
          {
            global_min_val=array_min[i];
          }
        }

        time_update = millis(); 
    }   
    
  if((millis() - time_array) > interval_array) //Switch of array position and reset of old values
    {
      index = index + 1; 
      if(index >= size_array) 
       {
         index = 0 ;
       }

      temp_max_tempo = temperature_loop; ;
      temp_min_tempo = temperature_loop; ;
      array_max[index] = temperature_loop;
      array_min[index] = temperature_loop;

      time_array = millis(); 

    }

Personally, I'd add debug code to what you have. Extracting the bit where you think the problem is would be asking for trouble.