EEPROM Memory Layout
This section describes how the system stores authorized cards in the Arduino’s EEPROM memory.
Memory Map Overview
EEPROM Memory Organization (1024 bytes total)
The EEPROM uses a simple flat structure optimized for fast sequential access and minimal wear.
Memory Regions
Header Section
Addresses 0-2 (3 bytes)
Magic Number (0xABCD): Validates EEPROM has been initialized
Card Count: Number of stored cards (0-40)
Card Data Section
Addresses 3-322 (320 bytes = 40 cards × 8 bytes)
Each card entry is 8 bytes:
Example 4-byte UID entry:
04 AB 12 CD 34 FF FF FF
Example 7-byte UID entry:
07 04 AB 12 34 56 CD EF
Memory Operations
Read Operation Flow
Card Authorization Check Process
Write Operation Flow
Card Registration Process
Memory Wear Leveling
The Arduino Nano’s EEPROM (ATmega328P) has a rated endurance of 100,000 write cycles per cell.
Write Frequency Estimation
Most-Written Locations:
Address 2 (Card Count): Modified on every card add/delete operation
Assume 10 cards added/deleted per day
100,000 writes / 10 writes per day = ~27 years lifespan
Least-Written Locations:
Card entry addresses: Written only when card is registered
Deleted cards are marked invalid, not erased (reduces writes)
Best Practices
To maximize EEPROM lifespan:
Minimize Deletions: Prefer keeping cards registered when possible
Batch Operations: Register multiple cards in one session
Avoid Frequent Resets: Don’t clear EEPROM unnecessarily
Monitor Usage: Track write cycles in critical applications
Memory Initialization
First-Time Setup
Code Example
Initialization code in AccessControlSystem.cpp:
void AccessControlSystem::initEEPROM() {
// Check magic number
uint16_t magic = (EEPROM.read(0) << 8) | EEPROM.read(1);
if (magic != 0xABCD) {
// First time - initialize
EEPROM.write(0, 0xAB);
EEPROM.write(1, 0xCD);
EEPROM.write(2, 0); // Zero cards
// Clear card storage area
for (int i = 3; i < 323; i++) {
EEPROM.write(i, 0xFF);
}
}
}
Memory Debugging
To inspect EEPROM contents, add debug code:
void dumpEEPROM() {
Serial.println("=== EEPROM Dump ===");
// Header
Serial.print("Magic: 0x");
Serial.print(EEPROM.read(0), HEX);
Serial.println(EEPROM.read(1), HEX);
Serial.print("Count: ");
Serial.println(EEPROM.read(2));
// Cards
uint8_t count = EEPROM.read(2);
for (uint8_t i = 0; i < count; i++) {
int addr = 3 + (i * 8);
Serial.print("Card ");
Serial.print(i + 1);
Serial.print(": ");
uint8_t len = EEPROM.read(addr);
Serial.print("Len=");
Serial.print(len);
Serial.print(" UID=");
for (uint8_t j = 0; j < 7; j++) {
Serial.print(EEPROM.read(addr + 1 + j), HEX);
Serial.print(" ");
}
Serial.println();
}
}
Summary
The EEPROM storage system provides:
Simple Structure: Easy to understand and debug
Efficient Access: Direct addressing for fast lookups
Durable: Designed for long-term reliability
Scalable: Supports up to 40 cards with room for expansion
Robust: Magic number validation prevents corruption
Total memory usage: 323 bytes of 1024 bytes (31.5%)