I have programmed an RFID reader: I can erase the list of all my authorized cards/tags, add them , validated if a card is authorized or not, etc ... Everything works fine.
my problem, is that as soon as I power off the Nano, everything is lost ! So I figured I could save the authorized list in EEPROM.
IDs read from the RFID tag are 12 bytes long that are transformed into a string for comparison, etc ... I have provision for a max of 50 tags (MyTags[0] to MyTags[49], type = String).
even if the length is 12 bytes long, I want to store the last 10 bytes, as the first ones are always the same: that way, each tag's byte would be store as address xx0 to xx9 (I like when things are aligned ...). So 50 Tags X 10 Bytes = 500 bytes...it would fit in the internal EEPROM !
I am totally lost on how to do that !!!
I need help, to :
on boot, load the list of authorized tag's ID that are allowed (as MyTags[0] to MyTags[49})
When a button is pressed, re-write the whole list of who's authorized to the EEPROM
eventually, I want to use an external EEPROM (so it can be replaced when written/read too many times) but for now, if someone can help me with the internal one, I can probably figure out the external one !!!
Just write the bytes of each string one at a time to the EEPROM. There is nothing difficult about it.
If you have n characters then you have n / 1024 slots in the EEPROM to store the data. Just look at my RFID sequencer project for a code example but I used only four bytes and had it has a number not a string, this made it more efficient.
No it is 8 bits, a number like 0x12 is just an 8 bit number.
To split up the number it depends on how it is stored, with MyTags[5] assuming it is a char array then just
EPROMaddress = MyTag[0]
EEPROM address + 1 = MyTag[1]
And so on. Only you use the EEPROM write function.
Have you looked at the code in that project? There is a function that does this.
jouellet:
I thought that every element extracted from a string, would be considered as an ASCII character, therefore taking the full 8 bits ...
It's only an ASCII character if you decide it's an ASCII character. A byte (unsigned, so we don't have to worry about negative numbers), is simply a small unit of memory that will hold the numbers 0 through 255, or in another base, 0x00 through 0xff.
A string consisting of two ASCII numbers can definitely be held in a single byte, making it far better for storage in an EEPROM.
The Arduino is fast enough to do the conversion, both for making a string into a series of bytes for storage, and for making it into a string of bytes for comparison, without you sensing a slow operation
unsigned long tokenInVar(){
unsigned long number = 0;
for(int i=0; i<8; i++) number = (number << 4) | convertFromHex(int(token[i]));
return(number);
}
unsigned long convertFromHex(int ascii){
if(ascii > 0x39) ascii -= 7; // adjust for hex letters upper or lower case
return(ascii & 0xf);
}
To convert a token in a string into a long int, note this gives you 4 bytes or 32 bits, good for most RFID tokens.
If you want more then use a long long, that gives you 64 bit numbers. Once in number form they are compared just like you compare any other number.
The token is in and array of chr token or C string ( note this is not String ) Then to store use:- * *void saveToken(int point){ // saves the token in EEprom memory at point EEPROM.write(point, (tokensOnBoard[0] >> 24) & 0xff); EEPROM.write(point+1, (tokensOnBoard[0] >> 16) & 0xff); EEPROM.write(point+2, (tokensOnBoard[0] >> 8) & 0xff); EEPROM.write(point+3, tokensOnBoard[0] & 0xff); EEPROM.write(point+4,value[6]); EEPROM.write(point+5,value[7]); EEPROM.write(point+6,value[8]); }* * This stores the token as 4 bytes plus three other values that my program needed to store, you might not need this. They were the MIDI channel, note number and velocity associated with each token. The EEPROM is split up into slots of 7 bytes each and that function takes in a pointer to that slot or EEPROM address called point. Note how the big number is split up into bytes using the >> shift right operator and the bitwise AND operator & to mask off parts of the word just leaving a byte. Another function you will have to implement is one to find the next free slot in the EEPROM when storing a new token. * *int findFreeEntry(){ int i = 0; boolean found = false; while( found == false && i < 1000){ if( EEPROM.read(i) == 0xff && EEPROM.read(i+1) == 0xff && EEPROM.read(i+2) == 0xff && EEPROM.read(i+3) == 0xff ) found = true; if(!found) i +=7; } if(found) return i; else return -1; }* * Also this searches the EEPROM for a match to a given token:- ```
int matchToken(unsigned long token){
int i = 0;
boolean found = false;
while( found == false && i < 1000){
if( EEPROM.read(i) == ((token >> 24)& 0xff) && EEPROM.read(i+1) == ((token >> 16)& 0xff)
&& EEPROM.read(i+2) == ((token >> 8)& 0xff) && EEPROM.read(i+3) == (token & 0xff) ){
found = true;
}
if(!found) i +=7; // move on to the start of the next entry
}
if(found) return i; else return -1;
}* ```
lar3ry:
A string consisting of two ASCII numbers can definitely be held in a single byte, making it far better for storage in an EEPROM.
That's a little confusing.
In C, as string is a null-terminated character array - only an empty string could be held in a single byte.
The ASCII digit '1' has the value 49 (0x31), and would therefor fill a byte.
lar3ry:
A string consisting of two ASCII numbers can definitely be held in a single byte, making it far better for storage in an EEPROM.
That's a little confusing.
In C, as string is a null-terminated character array - only an empty string could be held in a single byte.
The ASCII digit '1' has the value 49 (0x31), and would therefor fill a byte.
In the context of the thread, you can store "12" in a single byte by making it 12, whih is clearly able to be crammed into a byte.
Pardon the late reply. I am catching up on unread replies.
Like you, I do not have a lot of experience with writing code, and have difficulty understanding some advanced concepts.
Here is some simple code reading and writing 2d character arrays into the internal eeprom. It may not be efficient, it may not be concise, and it is not generic since it leverages off your 10 byte data. On the other hand, it doesn't use Strings, or pointers. It may get criticism from the more advance folks on the board, but it puts your id data in and pulls it out, and it may help get you get started in the right direction.