Best way to store data for later comparison (after reset)?

Hi!

So I'm working on an NFC lock with an Uno R3. I've got an excellent prototype wired up - it scans the nfc chip (via the seeedstudio nfc shield v2.0) and takes the unique ID (UID) received (byte by byte in hex) and converts it to a string, which is then compared to a single, hardcoded UID string. Awesome!

Of course, I want to have the ability to add and remove tags without opening 'er up and altering the code. So usually that means a Master tag and an Erase tag. I'll be having this thing hooked up to GSM, however (when the cell unit finally arrives), so I'll leave erasing to SMS (first command makes arduino send each stored UID one by one, second command deletes a specific UID).

So what I'm having issues with is deciding on a storage medium. I'm already using a lot of the pins that SD cards seem to need (are they changeable? I'd have to alter the library I think). Of course the "simplest" solution is EEPROM. But that's complicated! I'd need to:

  • Store each new UID (after commanded to by the master card) to eeprom, byte by byte. Some of them are 4 bytes and some are 7 bytes, so I'll just add 3 zeros to the end of 4 byte UID's.
  • Every time a new card is scanned, compare it's UID to each UID in the eeprom. That would involve creating an array of 7 bytes from the eeprom and comparing that to the UID that's been scanned. Rinse, repeat. But how do I know when I've run out of stored UIDs? I was thinking an IF that looks for a new UID that's just 255,255,255,255,255,255,255, but that seems so sloppy and inefficient.
  • When I delete a tag, let's say the second tag out of 3, I'd need to move all the later tags up 7 bytes. Is there a simple way to do this?

It all seems so tedious! Is there a simpler way?

Thanks,
Naomi

How many uids are you expecting to have stored at any time? which arduino are you using. The built in eeprom sounds like the ideal medium to me. Simple to use and space for quite a lot of those uids

Uno R3, and I'd be shocked if I hit a dozen. My primary issues are what I outlined above in the list. Actually, since I posted I finished part 1, so that just leaves how to compare and how to recognize the end of the list, and also how to handle deletions.

Also, I'd ideally love to have a timestamp of when it was added - but that would require a real time clock, right? I have one of those modules here somewhere...

If you put the token code into a long long variable ( that is 8 bytes ) then a simple single if statement will test it.
A very simple function can be used to extract the token code from EEPROM into a variable for testing.

This will also help you find the end of the list simply.

You can solve your deletion problems in two ways.

  1. Zero out a deleted token. - Then when adding a token find the place to add it to the memory by looking for the first zeroed out entry or the end of the list.

  2. Implement a linked list. This is where the first byte in the data structure is a link to where the next entry is. To delete an entry simply change the link in the data slot before it so it is missed out.

Examples of most of this is used in the software for this project of mine:-
http://www.thebox.myzen.co.uk/Hardware/RFID_Sequencer.html

Allowing 1 byte each for Year, Month, Day, Hour, Minute, Second that's still only 13Bytes for each tag Rounding this up to 16bytes each, gives you enough space on the built in EEprom for 64 tags.

So you could assume that every 16th byte in eeprom to be the start of a tag record. By default, before it has been written the eeprom will hold 255 in every byte. So you could take this to be an indication that the slot is free.

When you need to add a tag to eeprom, you just need to look at every 16th memory address until you find 255. Then this will mark the start of your new storage space.

When you want to delete a tag, just find the tag record in EEPROM and write 255 to it's address.

A much more space effective way of time stamping is to use a number that is the number of minutes since a specific epoch (some known fixed point like the first of jan 2014 ).
In that way a simple 24 bit number (three bytes ) will last just short of 32 years. Extend that to four bytes and you go over 8000 years.

Question: what happens when the memory is full? By which I mean, there are 200 lines of 255 255 255, and a few UID's stored. Do the 255 lines take space? Imagining a list that's added to and subtracted to daily, wouldn't I end up taking all the possible lines?

Ohhhh... I see what you're saying. I just examine the eeprom until I find the 16 255's, then replace them with the new data.

Alright. I'll play with this for awhile.

I'm running low on arduinos - one of the cheap chinese knockoffs I have is, frankly, crap. It fails every second upload, and randomly freezes. My other two are deep in prototypes.

Regarding timestamp, I honestly just need the date.

Regarding timestamp, I honestly just need the date.

So two bytes will give you 179 years worth of just the data.

nagumi:
Ohhhh... I see what you're saying. I just examine the eeprom until I find the 16 255's, then replace them with the new data.

You don't even need to find 16 of them Just the one on a boundary of your chosen record size.

In fact, If you used the first byte to hold the day then you could use the most significant bit to hold the "record free" flag.

So to find a vacant space would be as simple as

int function findVacantSlot()
{
for (n=0; n< (1024 - recordLength); n+= recordLength)
  if (EEPROM.read(n) & 128)
   return n;
return -1; //signifies EEPROM FULL
}

This would have the benefit of being able to "undelete" any tags that were deleted by accident. (unless they've been overwritten in the meantime)

Could the UID never have a 255 in it?

nagumi:
Could the UID never have a 255 in it?

Doesn't matter if it does. The first byte of your saved record wouldn't be part of the UID it would be part of the date. It's this first byte you want to look at to decide if the record is valid

The point is there are many ways to arrange the data for what you want to do.

You will get more satisfaction if you design your own solution.

However if you have two "tag" codes in your data base to indicate free space and end of approved tags, then you can filter them out if you ever read a tag with all zeros or all ones.
I have never seen tags with these values but you never know.