Hi All,
This is part of an personal RFID door lock project.
I am using external eeprom Microchip 24LC128 and arduino nano. Comparing it with the built-in eeprom I get much lower reading results. I connected it as shown below:
The result is:
11:55:47.503 -> START
11:55:53.030 -> STOP
5.5sec for 10000bytes / 1000 RFID tags. With the built-in eeprom I achieved a result of 16ms for 1000 bytes, ie for 10000 bytes it should be 160ms. I guess no one will be happy to wait 5-6 seconds until the device decides whether to open the door or not.
I've also tried an external library such as SparkFun external eeprom but the result is worse.
Is this speed normal for external EEPROM? What can limit the reading speed? Can I improve the speed?
#include <I2C_eeprom.h> // https://github.com/RobTillaart/I2C_EEPROM
I2C_eeprom storage(0x50, I2C_DEVICESIZE_24LC256); // AT24C256 @ 0x50
const uint32_t cardCount = 1000;
bool addressOfCardID(uint32_t cardID, uint32_t& cardAddress) {
bool foundCard = false;
uint32_t idBuffer;
uint32_t t0 = micros();
for (uint32_t cID = 1, cAdd = 0; cID <= cardCount; cID++, cAdd += sizeof(uint32_t)) {
storage.readBlock(cAdd, (uint8_t*) &idBuffer, sizeof idBuffer);
if (idBuffer == cardID) {
cardAddress = cAdd;
foundCard = true;
Serial.print((micros() - t0) / 1000.0, 0);
Serial.print(F(" ms\tto find card #")); Serial.print(cardID);
Serial.print(F(".\taddress: ")); Serial.println(cardAddress);
break;
}
}
return foundCard;
}
void setup() {
Serial.begin(115200);
Wire.setClock(400000); // 400KHz is fast mode, Max. Clock Freq. for 24LC128 (otherwise use 100KHz (standard mode) )
storage.begin();
if (! storage.isConnected()) {
Serial.println(F("external EEPROM error."));
while (true) yield();
}
// initalize the memory
for (uint32_t cardID = 1, cardAddress = 0; cardID <= 1000; cardID++, cardAddress += sizeof(uint32_t)) {
storage.writeBlock(cardAddress, (uint8_t*) &cardID, sizeof(uint32_t));
}
uint32_t cardAddress = 0;
if (! addressOfCardID(1 , cardAddress)) Serial.println(F("No card with ID #1")); // best case
if (! addressOfCardID(500 , cardAddress)) Serial.println(F("No card with ID #500")); // middle point
if (! addressOfCardID(1000, cardAddress)) Serial.println(F("No card with ID #1000")); // worst case
// random access
Serial.println(F("------------------------------"));
for (uint32_t test = 0; test <= 10; test++) {
uint32_t cardID = random(1, 1001);
if (! addressOfCardID(cardID, cardAddress)) {
Serial.print(F("No card with ID #")); Serial.println(cardID);
}
}
}
void loop() {}
that's the output
1 ms to find card #1. address: 0
435 ms to find card #500. address: 1996
868 ms to find card #1000. address: 3996
------------------------------
701 ms to find card #808. address: 3228
217 ms to find card #250. address: 996
64 ms to find card #74. address: 292
572 ms to find card #659. address: 2632
808 ms to find card #931. address: 3720
237 ms to find card #273. address: 1088
473 ms to find card #545. address: 2176
763 ms to find card #879. address: 3512
802 ms to find card #924. address: 3692
616 ms to find card #710. address: 2836
383 ms to find card #441. address: 1760
so for 1000 cards using 4 bytes for their ID, the worst case scenario (looking at card #1000) is 868 ms.
Less than one second is likely acceptable. of course this is a worst time, if you have a low rank, then that will be faster. if this is still too slow, then a hash strategy on where to store cards based on their ID could be implemented to start searching from a different address. but in my view this is not needed
Sorry for the delay. Unfortunately, it's not exactly as you described. In short, if you want a fast read speed (about 10 times compared to I2C), use EEPROM on SPI. Probably a little harder, but only until you make a method of writing and reading.