-1

I'm trying to understand how to read/write a UID struct from miguelbalboa to EEPROM to persist a card ID across system restarts on my ESP32-S3 through the Arduino IDE. I expected Put/Get/Read to be symmetrical but can't seem to prove that. Here's my test program:

/**
 * This is a simple script to experiment with reading and writing MFRC522::Uid
 * structures to eeprom.
 */

#include <MFRC522.h>
#include <EEPROM.h>

#define UID_EEPROM_LOCATION 0
#define EEPROM_SIZE 256

void setup() {
  
  Serial.begin(115200);   // Initialize serial communications with the PC
  Serial.println("Serial started.");
  EEPROM.begin(EEPROM_SIZE);
  Serial.print("EEPROM started ");
  Serial.println(EEPROM_SIZE);
  printBytesFromEeprom();
  MFRC522::Uid uidToWrite = {
    0x04,
    {B00000000, B10000000, B11100000, B01100000},
    0
  };
  Serial.print("UID Before Write: ");
  printUid(&(uidToWrite));
  storeUidInEeprom(&(uidToWrite));
  printBytesFromEeprom();
  Serial.println("UID was put.");
  MFRC522::Uid uidFromRead;
  readUidFromEeprom(&(uidFromRead));
  printBytesFromEeprom();
  Serial.print("UID from Read: ");
  printUid(&(uidFromRead));
}

void loop() {
}

void printUid(MFRC522::Uid *uid) {
  Serial.print(uid->size, HEX);
  Serial.print(F(" byte card UID:"));
  for (byte i = 0; i < uid->size; i++) {
    if(uid->uidByte[i] < 0x10)
      Serial.print(F(" 0"));
    else
      Serial.print(F(" "));
    Serial.print(uid->uidByte[i], HEX);
  } 
  Serial.println();
}

void readUidFromEeprom(MFRC522::Uid* result) {
  EEPROM.get(UID_EEPROM_LOCATION, result);
  delay(1000);
}

void storeUidInEeprom(MFRC522::Uid *uid) {
  EEPROM.put(UID_EEPROM_LOCATION, uid);
  EEPROM.commit();
  delay(1000);
}

void printBytesFromEeprom() {
  Serial.print("256 bytes from EEPROM: ");
  for (int i = 0; i < 256; i++) {
    byte myByte = EEPROM.read(UID_EEPROM_LOCATION + i);
    if(myByte < 0x10)
      Serial.print(F(" 0"));
    else
      Serial.print(F(" "));
    Serial.print(myByte, HEX);
  }
  Serial.println();
}

I'm an experienced Java developer, but new to C++. I could have made any number of basic errors.

When I run the above on my ESP32-S3-DevKitC-1, I get the following output:

ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd0108,len:0x43c
load:0x403b6000,len:0xbd0
load:0x403ba000,len:0x29c8
entry 0x403b61d8
Serial started.
EEPROM started 256
256 bytes from EEPROM:  E4 2C CE 3F FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
UID Before Write: 4 byte card UID: 00 80 E0 60
256 bytes from EEPROM:  94 2D CE 3F FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
UID was put.
256 bytes from EEPROM:  94 2D CE 3F FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
UID from Read: C0 byte card UID: 79 CD 3F 00 00 00 00 00 00 00 00 0C FA 3B C7 00 00 00 00 04 00 00 00 4C 2F CE 3F 01 00 00 80 00 00 00 00 F0 2D CE 3F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2E CE 3F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

There are two unexpected things from this output:

  • The output of readUidFromEeprom() is different than the input to storeUidInEeprom()

Any help would be welcome!

1
  • readUidFromEeprom(MFRC522::Uid& result) Commented Jul 3, 2022 at 17:34

3 Answers 3

3

You wrote:

void readUidFromEeprom(MFRC522::Uid* result) {
  EEPROM.get(UID_EEPROM_LOCATION, result);
  delay(1000);
}

The EEPROM.get() method expects a reference to the variable you are setting. Here, you are providing a pointer instead. The outcome is that this call is updating the result local variable (the pointer), rather than the memory region pointed by it.

You may try this:

void readUidFromEeprom(MFRC522::Uid* result) {
  EEPROM.get(UID_EEPROM_LOCATION, *result);  // notice the `*' operator
  delay(1000);
}

Same thing for EEPROM.put().

Edit: As suggested by Juraj in a comment, it can make more sense to have readUidFromEeprom() accept a reference rather than a pointer:

void readUidFromEeprom(MFRC522::Uid &result) {
  EEPROM.get(UID_EEPROM_LOCATION, result);
  delay(1000);
}

But then you have to also change the caller:

readUidFromEeprom(uidFromRead);
0
0

Well...

I still don't know why the above wasn't working. But if I switch to my own byte encoding in EEPROM (the obvious one that I assumed put() used, then I get the right behavior:

/**
 * This is a simple script to experiment with reading and writing MFRC522::Uid
 * structures to eeprom.
 */

#include <MFRC522.h>
#include <EEPROM.h>

#define UID_EEPROM_LOCATION 0
#define EEPROM_SIZE 256

void setup() {
  
  Serial.begin(115200);   // Initialize serial communications with the PC
  Serial.println("Serial started.");
  EEPROM.begin(EEPROM_SIZE);
  Serial.print("EEPROM started ");
  Serial.println(EEPROM_SIZE);
  printBytesFromEeprom();
  MFRC522::Uid uidToWrite = {
    0x04,
    {B00000000, B10000000, B11100000, B01100000},
    0
  };
  Serial.print("UID Before Write: ");
  printUid(&(uidToWrite));
  storeUidInEeprom(&(uidToWrite));
  printBytesFromEeprom();
  Serial.println("UID was put.");
  MFRC522::Uid uidFromRead;
  readUidFromEeprom(&(uidFromRead));
  printBytesFromEeprom();
  Serial.print("UID from Read: ");
  printUid(&(uidFromRead));
}

void loop() {
}

void printUid(MFRC522::Uid *uid) {
  Serial.print(uid->size, HEX);
  Serial.print(F(" byte card UID:"));
  for (byte i = 0; i < uid->size; i++) {
    if(uid->uidByte[i] < 0x10)
      Serial.print(F(" 0"));
    else
      Serial.print(F(" "));
    Serial.print(uid->uidByte[i], HEX);
  } 
  Serial.println();
}

void readUidFromEeprom(MFRC522::Uid* result) {
  byte uidSize = EEPROM.read(UID_EEPROM_LOCATION);
  for (byte i = 0; i < uidSize; i++) {
    result->uidByte[i] = EEPROM.read(UID_EEPROM_LOCATION + 1 + i);
  }
  byte uidSak = EEPROM.read(UID_EEPROM_LOCATION + 2 + uidSize);
  result->size = uidSize;
  result->sak = uidSak;
}

void storeUidInEeprom(MFRC522::Uid *uid) {
  EEPROM.write(UID_EEPROM_LOCATION, uid->size);
  for (byte i = 0; i < uid->size; i++) {
    EEPROM.write(UID_EEPROM_LOCATION + 1 + i, uid->uidByte[i]);
  } 
  EEPROM.write(UID_EEPROM_LOCATION + 2 + uid->size, uid->sak);
  EEPROM.commit();
}

void printBytesFromEeprom() {
  Serial.print("256 bytes from EEPROM: ");
  for (int i = 0; i < 256; i++) {
    byte myByte = EEPROM.read(UID_EEPROM_LOCATION + i);
    if(myByte < 0x10)
      Serial.print(F(" 0"));
    else
      Serial.print(F(" "));
    Serial.print(myByte, HEX);
  }
  Serial.println();
}

And output as expected is:

ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd0108,len:0x43c
load:0x403b6000,len:0xbd0
load:0x403ba000,len:0x29c8
entry 0x403b61d8
Serial started.
EEPROM started 256
256 bytes from EEPROM:  04 00 80 E0 60 FF 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
UID Before Write: 4 byte card UID: 00 80 E0 60
256 bytes from EEPROM:  04 00 80 E0 60 FF 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
UID was put.
256 bytes from EEPROM:  04 00 80 E0 60 FF 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
UID from Read: 4 byte card UID: 00 80 E0 60

-1

On the ESP23 platform, consider using the Preferences library. EEPROM in arduino-esp32 is emulated using the Preferences library. Might mess up the calls to MFRC522 lib though.

Preferences docs include the API and tutorial.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.