fabriziop / EEWL

The EEWL library allows to extend the EEPROM life by distributing data writes along a circular buffer.
GNU Lesser General Public License v3.0
10 stars 1 forks source link

Problem with multiple EEWL objects #5

Closed fulvioalessio closed 1 year ago

fulvioalessio commented 1 year ago

Hi,

I have some problems with multiple EEWL objects, the same problem occour with arduino nano and esp32.

I've replicated the problem with this code, derived from countPowerCycles:

#include "eewl.h"

unsigned long powerCycles = 0;
unsigned long powerCycles2 = 0;
EEWL pC(powerCycles, 10, 10);
EEWL pC2(powerCycles2, 10, 200); // start is high enough to avoid conflict with pC

void setup()
{
  Serial.begin(9600);
  delay(1000);
  pC.begin();
  pC2.begin();
  if (!pC.get(powerCycles))
    Serial.println("setup: first time ever");
  if (!pC2.get(powerCycles2))
    Serial.println("setup2: first time ever");
  powerCycles++;
  powerCycles2++;
  pC.put(powerCycles);
  pC2.put(powerCycles2);
  Serial.print("power cycles = ");
  Serial.println(powerCycles);
  Serial.print("power cycles2 = ");
  Serial.println(powerCycles2);
}
void loop()
{
  delay(1000);
}

Here the output: 1st reset:

setup: first time ever
setup2: first time ever
power cycles = 1
power cycles2 = 1

2nd reset:

setup2: first time ever
power cycles = 2
power cycles2 = 1

3rd reset:

setup2: first time ever
power cycles = 3
power cycles2 = 1

If I try original powerCycles.ino code, the "powerCycles" variable is incremented correctly. I've tried to comment "pC2.begin();", without success.

UPDATE: found an error on code, corrected. With nano the code works, with esp32 the problem persists.

fabriziop commented 1 year ago

Hi Fulvio,

I tested your corrected code on a node32s and it works as expected for me without any changes, but I suggest you to modify it to follow the instructions in the README for ESP32 processors:

... ESP8266, ESP32 and RISC-V caveat

Since ESP8266, ESP32 and RISC-V processor boards simulate EEPROM using a RAM buffer and FLASH EPROM, they needs same sort of begin call before reading or writing the EEPROM. This code is embedded into the begin method of EEWL. This means that EEWL::begin must be called before any other EEWL method.

Moreover, if multiple instances of EEWL are used and/or if other program parts needs their own EEPROM buffer, an explicit EEPROM begin call must be put in the application before any access to the EEPROM. This must be done defining the symbol EEPROM_PROGRAM_BEGIN before any include involving the EEPROM and with the call EEPROM.begin() in the arduino setup function.

AVR processor boards have a true EEPROM, so they do not need any EEPROM begin and multiple instances of EEWL and/or other program parts using EEPROM do not need any special provision to coexist in the same program. ...

fulvioalessio commented 1 year ago

Hi Fabrizio, before your answer I've tried to change at little your library introducing a init(size) method, without working with defines:

` void init(int eepromSize=0) {

#if !defined(EEWL_RAM) && !defined(__AVR__)
    if (eepromSize > 0) {
      Serial.print("begin ");
      Serial.println(eepromSize);
      EEPROM.begin(eepromSize);
    }
#endif

} `

With processors that need specific initialization, the change could be simple, while on AVR the code remains as it is now. What do you think ?

Thanks, Fulvio

fabriziop commented 1 year ago

Hi Fulvio, I automated the management of multiple instances for 32 bits CPUs (v. 0.6.0). You can try it to help me in some debug :) .

Fabrizio

fulvioalessio commented 1 year ago

Hi Fabrizio, trying with esp32s2 seems to work :)

-- power cycles = 2 power cycles2 = 2

--> reset

power cycles = 3 power cycles2 = 3

--> reset power cycles = 4 power cycles2 = 4

Only one thing: I receive these warning compiling under platformio:

-- eewl.h:66:21: warning: inline variables are only available with -std=c++17 or -std=gnu++17 static inline int highest_end_addr = 0; ^~~~ eewl.h:67:22: warning: inline variables are only available with -std=c++17 or -std=gnu++17 static inline bool eepromBeginDone = false; ^~~~~~~

Thanks, Fulvio