EEPROM Read/Load and memcpy of array of structs

Hello,

I'm working on trying to understand how to read/write to the EEPROM and use the memcpy function but am having trouble. I've looked up a lot of examples and tried to read and understand what I'm doing. I can get the code below to compile but it gives a warming that says I have something wrong. I can't seem to get the memcpy to work either which is also in the warning so I assume it's all related. I'd appreciate any help or pointers to get me in the right direction. I ultimately want to incorporate this code into a bigger project I'm making for a temperature controller set. I have the menu code working and this test code is so I can get this memory functions working.

Thanks!

Warning:

In file included from src/main.cpp:2:
In member function 'T& EEPROMClass::get(int, T&) [with T = tempCtrlSets]',
inlined from 'void memSetsLoad()' at src/main.cpp:90:30:
C:/Users/dclap/.platformio/packages/framework-arduinoespressif32/libraries/EEPROM/src/EEPROM.h:57:13: warning: 'void* memcpy(void*, const void*, size_t)' writing 24 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
memcpy((uint8_t*) &t, _data + address, sizeof(T));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In member function 'const T& EEPROMClass::put(int, const T&) [with T = tempCtrlSets]',
inlined from 'void memSetsSave()' at src/main.cpp:97:30:
C:/Users/dclap/.platformio/packages/framework-arduinoespressif32/libraries/EEPROM/src/EEPROM.h:66:13: warning: 'void* memcpy(void*, const void*, size_t)' reading 24 bytes from a region of size 0 [-Wstringop-overflow=]
memcpy(_data + address, (const uint8_t*) &t, sizeof(T));

Code:

#include <Arduino.h>
#include <LiquidCrystal_I2C.h> // Library for LCD
#include <EEPROM.h>

// ******************************************************************************************************************************
// Defines
// ******************************************************************************************************************************

#define SET_CHECK_VAL 123456789



// ******************************************************************************************************************************
// Project structures
// ******************************************************************************************************************************

struct tempCtrlSets {
  float tempF_SP; // Temperature setpoint (F)
  float heatHyst; // Hysteresis for heating temperature control (F)
  float coolHyst; // Hysteresis for cooling temperature control (F)
  boolean heatEnbl; // Enable heating control
  boolean coolEnbl; // Enable cooling control
  uint8_t heatDelay; // Heating control cycle delay (min)
  uint8_t coolDelay; // Cooling control cycle delay (min)
  uint8_t switchDelay; // Heating/Cooling switchover delay (min)
  uint32_t settingCheckValue; // Setting validation value
};


// ******************************************************************************************************************************
// Global variables
// ******************************************************************************************************************************

tempCtrlSets controlSets[3]; // Controller settings
tempCtrlSets defaultSets[3]; // Default settings



// ******************************************************************************************************************************
// Function forward declarations
// ******************************************************************************************************************************

void memSetsDefaults(); // Set default settings values
void memSetsLoad(); // Load settings values
void memSetsSave(); // Save settings values

// ******************************************************************************************************************************
// Setup loop
// ******************************************************************************************************************************

void setup() {
  
  // Initialize serial port
  Serial.begin(115200);  


  // Default settings
  defaultSets[0] = {38.0, 1.0, 1.0, false, true, 1, 10, 1, SET_CHECK_VAL};
  defaultSets[1] = {68.0, 1.0, 1.0, true, true, 1, 10, 1, SET_CHECK_VAL};
  defaultSets[2] = {68.0, 1.0, 1.0, true, true, 1, 10, 1, SET_CHECK_VAL};

  // Load settings from memory
  memSetsLoad();

 
}

// ******************************************************************************************************************************
// Main loop
// ******************************************************************************************************************************

void loop() {
  
  memcpy(&defaultSets[3], &controlSets[3], sizeof(controlSets[3]));

  Serial.println(defaultSets[0].tempF_SP);
  Serial.println(defaultSets[1].tempF_SP);
  Serial.println(defaultSets[2].tempF_SP);

  Serial.println(controlSets[0].tempF_SP);
  Serial.println(controlSets[1].tempF_SP);
  Serial.println(controlSets[2].tempF_SP);
  delay(1000);

  memSetsSave();

}


// Set default settings values
void memSetsDefaults() {
  
  controlSets[3] = defaultSets[3];

}

// Load settings values
void memSetsLoad() {
  EEPROM.get(0,controlSets[3]);
  if (controlSets[0].settingCheckValue != SET_CHECK_VAL) {memSetsDefaults();}

}

// Save settings values
void memSetsSave() {
  EEPROM.put(0,controlSets[3]);
}

From the error, it appears you are using an esp32 but are using the syntax for an avr eeprom

Look more closely at the library examples.

You will need specify a size for the "EEPROM" with EEPROM.begin(size )and call EEPROM.commit() to save the values.

Thank you for all of the really quick feedback! In my mind I was using the [3] the same as when I initially set up the 3 members but wasn't thinking about that being a 4th member which didn't exist. It made perfect sense as soon as you said it!

I did recently switch over to an ESP32 board from an older Arduino Mega so I can eventually add WiFi to this project and didn't realize I had to do some things different with EEPROM functions! I got it working now with dropping the [] from the array when working with the whole thing and adding in the EEPROM.Begin(). I'll need to read up on the other differences and then go from there.

Thank you both again! This forum is incredibly helpful!

A little more searching and I found Preferences.h which seems to be what I want to use. I tried it out and it seems to work like I would like. Would this be the better solution for an ESP32 board?

Thanks!

#include <Arduino.h>
#include <LiquidCrystal_I2C.h> // Library for LCD
#include <Preferences.h>

// ******************************************************************************************************************************
// Defines
// ******************************************************************************************************************************

#define SET_CHECK_VAL 123456789

Preferences prefs;

// ******************************************************************************************************************************
// Project structures
// ******************************************************************************************************************************

struct tempCtrlSets {
  float tempF_SP; // Temperature setpoint (F)
  float heatHyst; // Hysteresis for heating temperature control (F)
  float coolHyst; // Hysteresis for cooling temperature control (F)
  boolean heatEnbl; // Enable heating control
  boolean coolEnbl; // Enable cooling control
  uint8_t heatDelay; // Heating control cycle delay (min)
  uint8_t coolDelay; // Cooling control cycle delay (min)
  uint8_t switchDelay; // Heating/Cooling switchover delay (min)
  uint32_t settingCheckValue; // Setting validation value
};


// ******************************************************************************************************************************
// Global variables
// ******************************************************************************************************************************

tempCtrlSets controlSets[3]; // Controller settings
tempCtrlSets defaultSets[3]; // Default settings



// ******************************************************************************************************************************
// Function forward declarations
// ******************************************************************************************************************************

void memSetsDefaults(); // Set default settings values
void memSetsLoad(); // Load settings values
void memSetsSave(); // Save settings values

// ******************************************************************************************************************************
// Setup loop
// ******************************************************************************************************************************

void setup() {
  
  // Initialize serial port
  Serial.begin(115200); 

  //EEPROM.begin(EEPROM_SIZE);
  prefs.begin("Settings", false); 


  // Default settings
  defaultSets[0] = {38.0, 1.0, 1.0, false, true, 1, 10, 1, SET_CHECK_VAL};
  defaultSets[1] = {69.0, 1.0, 1.0, true, true, 1, 10, 1, SET_CHECK_VAL};
  defaultSets[2] = {70.0, 1.0, 1.0, true, true, 1, 10, 1, SET_CHECK_VAL};

  // Load settings from memory
  //memSetsLoad();

 
}

// ******************************************************************************************************************************
// Main loop
// ******************************************************************************************************************************

void loop() {
  
  memSetsLoad();

  Serial.println(defaultSets[0].tempF_SP);
  Serial.println(defaultSets[1].tempF_SP);
  Serial.println(defaultSets[2].tempF_SP);

  Serial.println(controlSets[0].tempF_SP);
  Serial.println(controlSets[1].tempF_SP);
  Serial.println(controlSets[2].tempF_SP);
  delay(1000);

  memSetsSave();

}


// Set default settings values
void memSetsDefaults() {
  
memcpy(&controlSets, &defaultSets, sizeof(controlSets));

}

// Load settings values
void memSetsLoad() {
  prefs.getBytes("Settings", &controlSets, sizeof(controlSets));
  if (controlSets[0].settingCheckValue != SET_CHECK_VAL) {memSetsDefaults();}

}

// Save settings values
void memSetsSave() {
  prefs.putBytes("Settings", &controlSets, sizeof(controlSets));
}

Yes. Preferences.h is the best way to go. The library has inbuilt wear leveling and address management.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.