Getting an Uno to Recognize Different RFID Card Numbers

Hello everyone,
I am constructing a beer vending machine that uses RFID cards to allow users to retrieve a beer from the vending machine. (Just for personal use at home not for business purposes) The code is still a work in progress, but the program I have at the moment works fine except for the following issue...

When a card is read by the RFID shield, it doesn't seem to recognize that the cards are different. It just keeps displaying the "Hello Admin" message even though the card numbers are different. I've tried using different IF/ELSE statements but it hasn't seemed to make any difference. I've also tried searching Google but that didn't seem to turn up anything.

Could someone please tell me what I'm doing wrong here? Or point me in the right direction?
Any help is greatly appreciated :slight_smile:

Parts used: Arduino Uno, Adafruit RFID shield, Adafruit LCD shield

This is the chunk of code that is giving me the issue (There are 11 cards in total):

uint8_t i=0;
void loop(void) {
  uint8_t success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
    
  // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
  // 'uid' will be populated with the UID, and uidLength will indicate
  // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
  
  
 if (uidLength == 0xE1,0x46,0x50,0x23){
    lcd.setCursor(0, 0);
    lcd.print("Hello Admin    ");
    lcd.setCursor(0, 1);
    lcd.print("Enjoy the Beer!");
    delay (5000);
    lcd.setCursor(0, 0);
    lcd.print("Waiting for ");
    lcd.setCursor(0, 1);
    lcd.print("Next Card      ");
 }

 else if (uidLength == 0xC9,0xED,0x8A,0x0A){
    lcd.setCursor(0, 0);
    lcd.print("Hello Colin    ");
    lcd.setCursor(0, 1);
    lcd.print("Enjoy the Beer!");
    delay (5000);
    lcd.setCursor(0, 0);
    lcd.print("Waiting for ");
    lcd.setCursor(0, 1);
    lcd.print("Next Card      ");
 }

Also, is it possible to run 11 different counters on an Uno?

 if (uidLength == 0xE1,0x46,0x50,0x23){

uidLength is a value like 6. How can it possible equal that? The comma operator will evaluate the right side of that statement, and return 0x23. I'm nearly certain that your uids are NOT 35 bytes long.

uid is an array. That array might, using memcmp() compare favorably to another array containing those 4 hex values.

Colin_42:
Also, is it possible to run 11 different counters on an Uno?

Yes.

Also, is it possible to run 11 different counters on an Uno?

As Nick says, yes. But, if the goal of doing that is to keep track of who drank how much (nothing wrong with that), keep in mind that, unless you do something, that data will be lost if the Arduino looses power for any reason.

Excellent, thank you.

PaulS:

 if (uidLength == 0xE1,0x46,0x50,0x23){

uidLength is a value like 6. How can it possible equal that? The comma operator will evaluate the right side of that statement, and return 0x23. I'm nearly certain that your uids are NOT 35 bytes long.

uid is an array. That array might, using memcmp() compare favorably to another array containing those 4 hex values.

The uid is 4 bytes long, using the example sketch that came with the RFID shield, it displayed the uid in the serial monitor like this "0xE1 0x46 0x50 0x23". I tried putting it in the sketch like that and it didn't like it. it gave me the error code;

"Beer_Machine.ino: In function 'void loop()':
Beer_Machine:51: error: expected ')' before numeric constant
expected ')' before numeric constant"

But if I put the commas in instead of the spaces, it verifies the program no problem.
Should I try converting the card numbers into decimal?

And if I use "memcmp()" you're saying can have the card numbers stored on the uno and use that to compare them?

PaulS:
As Nick says, yes. But, if the goal of doing that is to keep track of who drank how much (nothing wrong with that), keep in mind that, unless you do something, that data will be lost if the Arduino looses power for any reason.

I'm planning on using a datalogging shield with a RTC chip to store that as well as date, time, and temperature

Thank you very much for all the help!

Suppose that you had written some code that output the uid like "zero x e one space...". Would you really expect to define an array using the exact format of that output?

byte oneTag[] = { 0xE1, 0x46, 0x50, 0x23 };

Should I try converting the card numbers into decimal?

So the compiler can covert from base 10 to base 2? Don't bother.

And if I use "memcmp()" you're saying can have the card numbers stored on the uno and use that to compare them?

if(memcmp(uid, oneTag, 4) == 0)
{
   // found a known tag
}

Yes, that is what I am saying.

I'm planning on using a datalogging shield with a RTC chip to store that as well as date, time, and temperature

You might consider saving counts in EEPROM, instead of having to write code to read the entire log file on start-up, to recreate history.

PaulS:
Suppose that you had written some code that output the uid like "zero x e one space...". Would you really expect to define an array using the exact format of that output?

Sorry I'm fairly new to programming, so I don't fully understand the array concept, I'll have to read up on that.

PaulS:
Yes, that is what I am saying.

Ok, excellent.

PaulS:
You might consider saving counts in EEPROM, instead of having to write code to read the entire log file on start-up, to recreate history.

I wanted to do the datalogger because that way I could easily remove the sd card, and have a file of who got got beer, how many times, at what time, what temperature it was at, etc. But I will look into that option as well.

Thank you for all your help Paul. Very much appreciated.

Got it figured out!

Thank you again Paul, and Nick.