Help, I'm struggling with EEPROM!


(Matthew Vicaradge) #1

Hi everyone, I’m new here, I’ve been following the tutorials on here and I think they’re all great, I could never have got as far as I have without them.

I was lucky enough to receive an Arduboy for Christmas and I’ve been playing about with it but I can’t seem to get the EEPROM to store my data. I’ve got a basic first game up and running and would really like to add a saved High score feature but i can’t for the life of me work out what I’m doing wrong. I was hoping someone would take a look at my example code and spot my error. it seems to store the data as long as I don’t switch off the Arduboy. I know very little but I don’t think that’s how NVM is meant to work.

I’ll try and copy my code below, but I’m not entirely sure how to do that even!.. it might take me a couple of goes, bear with me.

#include <Arduboy2.h>
#include <EEPROM.h>

Arduboy2 arduboy;

#define EEPROM_START_C1   EEPROM_STORAGE_SPACE_START+1
#define EEPROM_START_C2   EEPROM_START_C1+1
#define EEPROM_SCORE      EEPROM_START_C2 +1

void initEEPROM()
{
unsigned char c1 = EEPROM.read(EEPROM_START_C1);
unsigned char c2 = EEPROM.read(EEPROM_START_C2);

if((c1 != 'M')||(c2 != 'V'))
  {
    EEPROM.update(EEPROM_START_C1, 'M');
    EEPROM.update(EEPROM_START_C1, 'V');  
    EEPROM.put(EEPROM_SCORE, (unsigned int)7);
  }  
}
int count = 0; 
int MEM = 0;

void setup() {
  // put your setup code here, to run once:
  arduboy.begin();
  initEEPROM();
  arduboy.clear();
}

void loop() {
  // put your main code here, to run repeatedly:
arduboy.clear();
    if (arduboy.pressed(UP_BUTTON))
      {
          count ++;
        
      }
       if (arduboy.pressed(DOWN_BUTTON))
      {
          count --;
      }


if (arduboy.pressed(A_BUTTON))
      {
          EEPROM.put(EEPROM_SCORE,count);
      }
if (arduboy.pressed(B_BUTTON))
      {
          EEPROM.get(EEPROM_SCORE,MEM);
      }
arduboy.setCursor (0,0);
arduboy.print(count);

arduboy.setCursor (0,30);
arduboy.print("Memory:");
arduboy.print(MEM);

arduboy.display();
}

#2

Use update instead of put when you’re updating to a new score.

Also use justPressed(). Your code will continuously write that block of memory while the button is pressed.

I’m not sure why it’s not saving correctly though. You’re using physical hardware and not projectAbe correct?


(Matthew Vicaradge) #3

Hi, thanks, yes I’m using hardware. Will the update function write an int correctly?


#4

Update will only write if it needs too
Edit: I miss remembered, as put is also “intelligent”. The justPressed vs pressed is still an important distinction though.

It’s best practice to minimize the writes as eeprom has a limited life. That’s also why you should use justPressed as it will only call that update function once.


(Scott) #5

To format code, place the code after a line containing three backticks and cpp. At the end of the code, put a line containing three backticks.

```cpp
Your code goes here
```

The backtick is usually on the key below the Esc key (at least on US keyboards).

I’ve done this for your post.


(Scott) #6

It’s a simple (but hard to spot) mistake.

In initEEPROM()

EEPROM.update(EEPROM_START_C1, 'V');

should be:

EEPROM.update(EEPROM_START_C2, 'V');

You’re writing both the M and V to the same location in EEPROM. EEPROM always looks uninitialized when you power up, so EEPROM_SCORE is always reset.

However, as @Freezingsnail said, it would be better to use justPressed() for writing to EEPROM, so you don’t call EEPROM.put() continually while the button is down (even though EEPROM.put() will only write the same data once).


Here’s my modified working version of your code, using pollButtons() and justPressed() for the EEPROM operatons. (I moved the EEPROM storage location farther up because I had data that I didn’t want destroyed at the location you were using.)

#include <Arduboy2.h>
#include <EEPROM.h>

Arduboy2 arduboy;

#define EEPROM_START_C1   EEPROM_STORAGE_SPACE_START + 500
#define EEPROM_START_C2   EEPROM_START_C1+1
#define EEPROM_SCORE      EEPROM_START_C2 +1

void initEEPROM()
{
  unsigned char c1 = EEPROM.read(EEPROM_START_C1);
  unsigned char c2 = EEPROM.read(EEPROM_START_C2);

  if((c1 != 'M')||(c2 != 'V'))
  {
    EEPROM.update(EEPROM_START_C1, 'M');
    EEPROM.update(EEPROM_START_C2, 'V');  
    EEPROM.put(EEPROM_SCORE, (int)7);
  }  
}

int count = 0; 
int MEM = 0;

void setup() {
  // put your setup code here, to run once:
  arduboy.begin();
  initEEPROM();
  arduboy.setFrameRate(10);
  arduboy.clear();
}

void loop() {
  if (!arduboy.nextFrame()) return;

  arduboy.pollButtons();
  
  arduboy.clear();
  if (arduboy.pressed(UP_BUTTON))
  {
    count ++;
  }
  if (arduboy.pressed(DOWN_BUTTON))
  {
    count --;
  }

  if (arduboy.justPressed(A_BUTTON))
  {
    EEPROM.put(EEPROM_SCORE,count);
  }
  if (arduboy.justPressed(B_BUTTON))
  {
    EEPROM.get(EEPROM_SCORE,MEM);
  }

  arduboy.setCursor(0,0);
  arduboy.print(count);

  arduboy.setCursor (0,30);
  arduboy.print("Memory:");
  arduboy.print(MEM);

  arduboy.display();
}

(Pharap) #7

put uses update.

(For the record, EEPROMClass is not an example of good code. There’s a laundry list of problems with it.)


(Matthew Vicaradge) #8

Thanks everyone for the help, I can’t believe I couldn’t see that! I must have been suffering coding fatigue! I hope to get my game finished off today, so I’ll put a post up later with it on.

Thanks again everyone, this seems like a great community!