EEPROM Nano ESP32 S3 disparity

Greetings to everyone onboard!

I'm struggling with a strange behavior related with EEPROM library. The idea is to store the maximum value of TDS measured by the module and compare it when the next time the device is powered on. For this purpose I'm using a library MinMax to record the highest value recorded by the TDS module.

However the issue is that the value I'm reading off the EEPROM returns to zero each time the unit is reset (using the onboard button on Arduino), or when power-cycled. I tried to constrain the EEPROM commit command by only allowing a non-zero value to be written to the memory, however the behaviour remains the same.

 if (maxTDS > 0) 

There is however a more perplexing issue. Even if I comment out the section that actually writes the variable data to the EEPROM, the EEPROM.read command still outputs the live maxTDS variable value as if it's being written by the EEPROM.write command, despite the fact it was commented out. The eepromMaxTDS is the same as maxTDS, even if nothing is written to the eeprom. Please see below:

    if (maxTDS > 0) {
      //EEPROM.write(1, maxTDS);
      //EEPROM.commit();
      eepromMaxTDS = EEPROM.read(1);
    }

I'm using the following hardware:
Arduino Nano ESP32 S3
Gravity TDS module

Here's the complete code:

#include "MINMAX.h"
#include <EEPROM.h>
#include <Wire.h>


#define VREF 1.09          // analog reference voltage(Volt) of the ADC
#define SCOUNT 30          // sum of sample point
int analogBuffer[SCOUNT];  // store the analog value in the array, read from ADC
int analogBufferTemp[SCOUNT];
int analogBufferIndex = 0, copyIndex = 0;
float averageVoltage = 0, tdsValue = 0, temperature = 29;
float tdsCompensation = 1.065934065934066;  // Divide by this value

MINMAX mm;
uint32_t start, stop;
int minTDS, maxTDS = 0;
int eepromMaxTDS = 0;

#define TdsSensorPin A1  // Gravity TDS module

void setup() {
  Serial.begin(9600);
  pinMode(TdsSensorPin, INPUT);
  if (!EEPROM.begin(512)) {
    Serial.println("EEPROM failed to initialise");
    while (true)
      ;
  } else {
    Serial.println("EEPROM initialised");
  }
}

void loop() {
  calcTDS();
  minMaxTDS();
}

void calcTDS() {
  static unsigned long analogSampleTimepoint = millis();
  if (millis() - analogSampleTimepoint > 40U)  //every 40 milliseconds,read the analog value from the ADC
  {
    analogSampleTimepoint = millis();
    analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin);  //read the analog value and store into the buffer
    analogBufferIndex++;
    if (analogBufferIndex == SCOUNT)
      analogBufferIndex = 0;
  }
  static unsigned long printTimepoint = millis();
  if (millis() - printTimepoint > 800U) {
    printTimepoint = millis();
    for (copyIndex = 0; copyIndex < SCOUNT; copyIndex++)
      analogBufferTemp[copyIndex] = analogBuffer[copyIndex];
    averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0;                                                                                                                       // read the analog value more stable by the median filtering algorithm, and convert to voltage value
    float compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0);                                                                                                                                    //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
    float compensationVolatge = averageVoltage / compensationCoefficient;                                                                                                                                 //temperature compensation
    tdsValue = ((133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5) / tdsCompensation;  //convert voltage value to tds value
  }
}

void minMaxTDS() {
  int r = tdsValue;
  if (mm.add(r) != MINMAX_NO_CHANGE)  //  changed minimum or maximum or reset
  {
    //Serial.print(mm.minimum());
    //Serial.print("\t");
    //Serial.println(mm.maximum());
    maxTDS = mm.maximum();
    // Write non-zero Max TDS value to EEPROM and update eepromMaxTDS variable
    if (maxTDS > 0) {
      EEPROM.write(1, maxTDS);
      EEPROM.commit();
      eepromMaxTDS = EEPROM.read(1);
    }
  }

  Serial.println(eepromMaxTDS);
}

int getMedianNum(int bArray[], int iFilterLen) {
  int bTab[iFilterLen];
  for (byte i = 0; i < iFilterLen; i++)
    bTab[i] = bArray[i];
  int i, j, bTemp;
  for (j = 0; j < iFilterLen - 1; j++) {
    for (i = 0; i < iFilterLen - j - 1; i++) {
      if (bTab[i] > bTab[i + 1]) {
        bTemp = bTab[i];
        bTab[i] = bTab[i + 1];
        bTab[i + 1] = bTemp;
      }
    }
  }
  if ((iFilterLen & 1) > 0)
    bTemp = bTab[(iFilterLen - 1) / 2];
  else
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
  return bTemp;
}

Of course I'm missing out some crucial aspect here for which I request your cooperation.

Thanks in advance!

maxTDS is declared as an int but EEPROM.write() writes a single byte and EEPROM.read() reads single byte

Consider using EEPROM.put() and EEPROM.get() instead

Thank you for the quick reply!

    if (maxTDS > 0) {
      EEPROM.put(1, maxTDS);
      EEPROM.commit();
      eepromMaxTDS = EEPROM.get(1, maxTDS);
    }

I made those changes, however the result is the same. Upon reset, the value read from EEPROM is zero. The thing is, even if I do not write anything to the eeprom and read from the address (1), it outputs live readings.

So,

    if (maxTDS > 0) {
      EEPROM.put(1, maxTDS);
      EEPROM.commit();
      eepromMaxTDS = EEPROM.get(1, maxTDS);
    }

and

    if (maxTDS > 0) {
      //EEPROM.put(1, maxTDS);
      //EEPROM.commit();
      eepromMaxTDS = EEPROM.get(1, maxTDS);
    }

Have the same output.

I suggest that you start by writing a simple sketch that put()s a value from a variable to the EEPROM then get()s it back to a different variable

In your main sketch you should also make sure that the calculated values are what you think they are by printing them

Thank you. As advised, i started with a basic read and write operation and the results are as expected. The EEPROM is able to hold the value upon reset. Here's the code:

#include <EEPROM.h>
byte testvalue = 7;

void setup() {
  Serial.begin(9600);
  //EEPROM.put(1, testvalue);
}

void loop() {
  Serial.println(EEPROM.get(1, testvalue));
}

The print command outputs 7 as expected, even after power-cycle.

So, put() and get() are working as expected but you really should have a commit() in there

In your original code

Agreed.
The calculated values are real, and the readings are calibrated against a standard equipment with acceptable tolerance.

However, the problem is here:

    if (maxTDS > 0) {
      //EEPROM.put(1, maxTDS);
      //EEPROM.commit();
      eepromMaxTDS = EEPROM.get(1, maxTDS);
    }

The output of this becomes zero upon reset. The for loop should specifically ignore the saving of zero value from maxTDS, however, that's not the case. Moreover, even if the following lines disabled,

EEPROM.write(1, maxTDS);
EEPROM.commit();

The output of

Serial.println(eepromMaxTDS);

remains the same, that is, it shows the maxTDS values. With "EEPROM.write(1, maxTDS)" disabled, how is the EEPROM.get able to show new values of maxTDS when nothing is being written into that eeprom location?

There may be non zero data held in the location from your previous coding efforts.

That's possible, but the variables (maxTDS and eepromMaxTDS) value printed through serial, shows Zero when the probe is not in contact with water.