problems saving current structure to eeprom then retrieving the saved data.

Hi guys

I'm working on a game for my game console and libraries and I'm having trouble saving and retrieving the current player structure data when saved and loaded. as it stands I can save and load but the load is not what was saved. For example.....

I want to save player structure....

struct Player
{
  int player_x;
  int player_y;
  int w;
  int h;
  int room;
  int player_direction;
  int player_directionRepeat;
};

Player player = { 160, 170, 16, 16, 3, 2, 0};

serial says it saved but when I load the game after saving I end up with the player in a room of the same size but no room graphics and I actually have to move the player before he appears on the screen. Also the players x and y coordinates wont save or load.

The last part is that I need the save to save current player data.

void setup() {
  while (!Serial && (millis() < 4000)) ;
  Serial.begin(115200);
  tft.begin();
  tft.setRotation(3);
  tft.fillScreen(BLACK);
  //tft.setFrameRate(60);
  tft.persistence = false;
  ////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////
  if (!ss1.begin(0x49)) {
    Serial.println("ERROR!");
    while (1);
  }
  if (!ss2.begin(0x4a)) {
    Serial.println("ERROR!");
    while (1);
  }
  else {
    Serial.println("seesaw started");
    Serial.print("version: ");
    Serial.println(ss1.getVersion(), HEX);
  }
  /////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////
  ss1.pinModeBulk(button_mask, INPUT_PULLUP);
  ss1.setGPIOInterrupts(button_mask, 1);
  pinMode(IRQ_PIN1, INPUT);
  /////////////////////////////////////////////////////////
  ss2.pinModeBulk(button_mask2, INPUT_PULLUP);
  ss2.setGPIOInterrupts(button_mask2, 1);
  pinMode(IRQ_PIN2, INPUT);
  /////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////
  if (!EEPROM.begin(EEPROM_SIZE))
  {
    Serial.println("failed to initialise EEPROM"); delay(1000000);
  }
  Serial.println(" bytes read from Flash . Values are:");
  for (int i = 0; i < EEPROM_SIZE; i++)
  {
    Serial.print(byte(EEPROM.read(i))); Serial.print(" ");
  }
  Serial.println();
  Serial.println("writing random n. in memory");

  tft.useFrameBuffer(use_fb);
}

byte saveKey = 121;
int val = byte(random(10020));
 
void save()
{
  int address = 0;

  EEPROM.put(4, saveKey);
  Serial.print(val); Serial.print(" ");
  EEPROM.put(28, player);
  Serial.print(val); Serial.print(" ");
  Serial.print("saved");
}

bool checkLoad()
{
  byte nr;
  EEPROM.get(0, nr);
  Serial.print("checkload");
  return (nr == saveKey);
}

void load()
{
    EEPROM.get(28, player);
    Serial.print(val); Serial.print(" ");
    Serial.print("loaded");
}
vRect rectA {0, 0, 136, 20};
  Rect rectB {0, 20, 136, 40};
  Rect rectC {0, 60, 136, 40};
  Rect rectD {0, 100, 136, 40};
  Rect rectE {0, 140, 136, 40};
  Rect rectF {0, 180, 136, 40};
  Rect rectG {0, 220, 136, 20};
  Rect rectH {cursora.cursorA_x, cursora.cursorA_y, 32, 32};
  /////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////
  tft.fillRoundRect(0, 0, 136, 240, 4, WHITE);
  tft.fillRoundRect(4, 4, 128, 232, 4, BLUE);
  tft.setCursor(24, 24);
  tft.setTextColor(WHITE);
  tft.setTextSize(3);
  tft.println("Item");
  tft.setCursor(24, 64);
  tft.setTextColor(WHITE);
  tft.setTextSize(3);
  tft.println("Equip");
  tft.setCursor(24, 104);
  tft.setTextColor(WHITE);
  tft.setTextSize(3);
  tft.println("Weird");
  tft.setCursor(24, 144);
  tft.setTextColor(WHITE);
  tft.setTextSize(3);
  tft.println("Stats");
  tft.setCursor(24, 184);
  tft.setTextColor(WHITE);
  tft.setTextSize(3);
  tft.println("Save");
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  int y = ss1.analogRead(2);
  int x = ss1.analogRead(3);

  /// if(tft.Bpressed(BTN_UP)){
  if (x > 600 && last_x < 600) {
    tft.writeRectNBPP(cursora.cursorA_x, cursora.cursorA_y, 32, 32, 4, cursor3, palette);
    cursora.cursor_direction = 1;
    cursora.cursorA_y -= 40;
  }
  if (cursora.cursorA_y <= 27) {
    cursora.cursorA_y = 27;
  }

  //////////////////////////////////////////////////////////////////////////////
  ///////////////////////////////Down///////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////
  /// if(tft.Bpressed(BTN_DOWN)){
  if (x < 400 && last_x > 400) {
    tft.writeRectNBPP(cursora.cursorA_x, cursora.cursorA_y, 32, 32, 4, cursor3, palette);
    cursora.cursor_direction = 1;
    cursora.cursorA_y += 40;
  }
  if (cursora.cursorA_y >= 188) {
    cursora.cursorA_y = 188;
  }

  last_x = x;
  /////////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////
  if (cursora.cursor_direction == 1) {
    tft.writeRectNBPP(cursora.cursorA_x, cursora.cursorA_y, 32, 32, 4, cursor3, palette);
  }

  //////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////exit menu////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////
  if (!digitalRead(IRQ_PIN2)) {
    uint32_t buttons = ss2.digitalReadBulk(button_mask2);
    if (! (buttons & (1 << BUTTON_A))) {
      state = STATE_Player;
    }oid Menu() {
  EEPROM.put(4, saveKey);

You are saving saveKey starting at location 4

  EEPROM.get(0, nr);
  Serial.print("checkload");
  return (nr == saveKey);

but seem to be checking it against the value starting at location 0

Just as an exercise I tried this and it works OK

#include <EEPROM.h>

struct Player
{
  int player_x;
  int player_y;
  int w;
  int h;
  int room;
  int player_direction;
  int player_directionRepeat;
};

Player player1 = { 160, 170, 16, 16, 3, 2, 0};
Player player2;

void setup()
{
  Serial.begin(115200);
  EEPROM.put(0, player1);
  EEPROM.get(0, player2);
  Serial.println(player2.player_x);
  Serial.println(player2.player_y);
  Serial.println(player2.w);
  Serial.println(player2.h);
  Serial.println(player2.room);
  Serial.println(player2.player_direction);
  Serial.println(player2.player_directionRepeat);
}

void loop()
{
}

well halfway there. I changed my load and save and dropped check load. thank you for the serial prints by the way. Any way I changed back to this....

struct Player
{
  int player_x;
  int player_y;
  int w;
  int h;
  int room;
  int player_direction;
  int player_directionRepeat;
};

Player player = { 160, 170, 16, 16, 3, 2, 0};

then changed my progress functions to this...

void save()
{
  EEPROM.put(0, player);
  Serial.print("saved");
}
void load()
{
    EEPROM.get(0, player);
  Serial.println(player.player_x);
  Serial.println(player.player_y);
  Serial.println(player.w);
  Serial.println(player.h);
  Serial.println(player.room);
  Serial.println(player.player_direction);
  Serial.println(player.player_directionRepeat);
}

While the console is on and in state player I can get it to save and load just fine. But if I turn the console off and and back on then try to load the saved data. I get black screen again.

But if I turn the console off and and back on then try to load the saved data. I get black screen again.

Are the values loaded correctly from the EEPROM when you turn it back on ?

What does eeprom.begin do? It's not a method of the standard library.

I'm currently using a cell phone and that's maybe why I can't see where you call load(). Ain't you calling load in setup() to get the initial player?

You are posting snippets, and I see this in your first post

if (!EEPROM.begin(EEPROM_SIZE))

This is syntax for ESP8266. Is that what this code is for?

Did you read Libraries — ESP8266 Arduino Core 3.1.2-21-ga348833 documentation

EEPROM
This is a bit different from standard EEPROM class. You need to call EEPROM.begin(size) before you start reading or writing, size being the number of bytes you want to use. Size can be anywhere between 4 and 4096 bytes.

EEPROM.write does not write to flash immediately, instead you must call EEPROM.commit() whenever you wish to save changes to flash. EEPROM.end() will also commit, and will release the RAM copy of EEPROM contents.

EEPROM library uses one sector of flash located just after the SPIFFS.

Three examples included.

Library examples at Arduino/libraries/EEPROM at master · esp8266/Arduino · GitHub

Sorry I should have mentioned that my board is actually an ESP32. No after powering off the console it seems to wipe the eeprom. I get serial prints of 0 for each variable.

Should commit be listed in save, load or both?

Edit::

Commit did the trick!!! Thank you.

I'm having problems again. Now I can save two structures but only player restores after the power off. Slots will not restore after power up. Theres no sketch or example to show how to restore but there is one to write. So kind of don't know what to do in order to restore both structures. Ive tried read too but no luck.

void setup() {
  while (!Serial && (millis() < 4000)) ;
  Serial.begin(115200);
  tft.begin();
  tft.setRotation(3);
  tft.fillScreen(BLACK);
  //tft.setFrameRate(60);
  tft.persistence = false;
  ////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////
  if (!ss1.begin(0x49)) {
    Serial.println("ERROR!");
    while (1);
  }
  if (!ss2.begin(0x4a)) {
    Serial.println("ERROR!");
    while (1);
  }
  else {
    Serial.println("seesaw started");
    Serial.print("version: ");
    Serial.println(ss1.getVersion(), HEX);
  }
  /////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////
  ss1.pinModeBulk(button_mask, INPUT_PULLUP);
  ss1.setGPIOInterrupts(button_mask, 1);
  pinMode(IRQ_PIN1, INPUT);
  /////////////////////////////////////////////////////////
  ss2.pinModeBulk(button_mask2, INPUT_PULLUP);
  ss2.setGPIOInterrupts(button_mask2, 1);
  pinMode(IRQ_PIN2, INPUT);
  /////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////
  if (!EEPROM.begin(EEPROM_SIZE))
  {
    Serial.println("failed to initialise EEPROM"); delay(1000000);
  }
  Serial.println(" bytes read from Flash . Values are:");
  for (int i = 0; i < EEPROM_SIZE; i++)
  {
    Serial.print(byte(EEPROM.read(i))); Serial.print(" ");
  }
  Serial.println();
  Serial.println("writing random n. in memory");

  tft.useFrameBuffer(use_fb);
}

struct Player
{
  int player_x;
  int player_y;
  int w;
  int h;
  int attack;
  int defense;
  int health;
  int room;
  int cameraX;
  int cameraY;
  int player_direction;
  int player_directionRepeat;
};

  Player player = { 160, 170, 16, 16, 20, 15, 100, 3, -128, -254, 2, 0};

struct Slot {
  int slot_x;
  int slot_y;
  int slot_w;
  int slot_h;
  uint8_t itemId;
  uint8_t quantity;
};

Slot slots[NUMBER_OF_SLOTS] = {
  { 180, 16,  81, 16, SLOT_AVAILABLE},
  { 180, 34,  81, 16, SLOT_AVAILABLE},
  { 180, 52,  81, 16, SLOT_AVAILABLE},
  { 180, 70,  81, 16, SLOT_AVAILABLE},
  { 180, 88,  81, 16, SLOT_AVAILABLE},
  { 180, 106, 81, 16, SLOT_AVAILABLE},
  { 180, 124, 81, 16, SLOT_AVAILABLE},
  { 180, 142, 81, 16, SLOT_AVAILABLE},
  { 180, 160, 81, 16, SLOT_AVAILABLE},
  { 180, 178, 81, 16, SLOT_AVAILABLE},
  { 180, 196, 81, 16, SLOT_AVAILABLE},
  { 180, 214, 81, 16, SLOT_AVAILABLE},
};

int addr = 0;
#define EEPROM_SIZE 64  

void save()
{
  EEPROM.put(0, player);
  EEPROM.put(36, slots);
  EEPROM.commit();
  Serial.println(player.player_x);
  Serial.println(player.player_y);
  Serial.println(player.w);
  Serial.println(player.h);
  Serial.println(player.cameraX);
  Serial.println(player.cameraY);
  Serial.println(player.player_direction);
  Serial.println(player.player_directionRepeat);
  Serial.print("saved");
}

void load()
{
    EEPROM.get(0, player);
    EEPROM.get(36, slots);
  Serial.println(player.player_x);
  Serial.println(player.player_y);
  Serial.println(player.w);
  Serial.println(player.h);
  Serial.println(player.cameraX);
  Serial.println(player.cameraY);
  Serial.println(player.player_direction);
  Serial.println(player.player_directionRepeat);
}

From https://www.arduino.cc/en/Reference/EEPROMPut

address: the location to write to, starting from 0 (int)

data: the data to write, can be a primitive type (eg. float) or a custom struct

You are trying to save an array, which will not work. You could, however, put your data in a struct and put/get that

Ok but it is saving the array. As long as the board is powered. Shut it off and it wipes the slots array. Keeps player either way though.

but it is saving the array

I bet it's not. If it was saving it then you would be able to load the values.

Write a small program that saves an array and loads it back to a different array and print the contents of the second array.

An example saving and loading a struct (written for a Uno)

#include <EEPROM.h>

struct theStruct
{
  int arrayA[2][2];
};

theStruct structA;
theStruct structB;

void setup()
{
  structA.arrayA[0][0] = 100;
  structA.arrayA[0][1] = 101;
  structA.arrayA[1][0] = 102;
  structA.arrayA[1][1] = 103;
  
  Serial.begin(115200);
  EEPROM.put(0, structA);
  EEPROM.get(0, structB);
  Serial.println(structB.arrayA[0][0]);
  Serial.println(structB.arrayA[0][1]);
  Serial.println(structB.arrayA[1][0]);
  Serial.println(structB.arrayA[1][1]);
}
void loop()
{
}