mfrc522 - Mifare UID issues

Hi, I'm trying to make a Mifare reader, but I've run into an issue with the UID. When I read a card with either my Omnimax or PcProx reader, I get a 10 decimal UID number; 3098013506.

However, when I read the same card with my mfrc522 on an Arduino Uno, I get an output of 11 very different decimal digits; 66239167184.

Here is the code I use:

#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN         9          
#define SS_PIN          10         

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

void setup() {
	Serial.begin(9600);		// Initialize serial communications with the PC
	while (!Serial);		// Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
	SPI.begin();			// Init SPI bus
	mfrc522.PCD_Init();		// Init MFRC522
	mfrc522.PCD_DumpVersionToSerial();	// Show details of PCD - MFRC522 Card Reader details
	Serial.println(F("Scan PICC to see UID."));
}

void loop() {
	// Look for new cards
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial())
  {
    //Serial.print("Card UID:");
    for (byte i = 0; i < mfrc522.uid.size; i++) {
      //Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
      Serial.print(mfrc522.uid.uidByte[i], DEC);
    }
    Serial.println();
    delay(5000);
  }
}

Can anyone tell me why this is happening? And is there a way to make the mfrc522 display it like the brand readers do?

Any help is much appreciated.

However, when I read the same card with my mfrc522 on an Arduino Uno, I get an output of 11 very different decimal digits; 66239167184.

A clue might present itself if you printed spaces between the bytes.

Thanks for answering. Yes, I see that it corresponds to the hex values if I print them out in dec, but where does the number 3098013506 that the brand readers print out come from? I don't get what kind of conversion I need to do to get to that number.

Yes, I see that it corresponds to the hex values if I print them out in dec

Well, you are the only one that can see that.

I can see that the 4 hex digits; 42 EF A7 B8 converts to the 4 set decimals; 66 239 167 184 by looking at a standard binary conversion chart. The question is how I get to the 10 digit decimal number the brand readers print out(and manufacturer prints on the card)?

B8A7EF42= ?

Swap the first and last byte? Doesn't that just produce the 4 decimal sets; 184 239 167 66 ? I don't understand how I can convert that into the 10 digit UID that both card mannufacturer and brand readers id it by.

Your commercial reader (and tag print) is 3098013506. Converted to hex it is B8 A7 EF 42

Your mfrc522 reader code first gave you 66239167184, which actually was 4 numbers (0-255) next to each other. Hex reading was 42 EF A7 B8. Opposite order of the tags true ID. In your code you have to swap the values you read.

Neither you can't convert hex to decimal piece by piece and put them next to each other and think you get the real number.

Thank you so much, now I understand! I'll get right on messing about with it :slight_smile:

Ok, I'm almost there now, but there is a final issue that I can't resolve. I can store the UID as hex forward, hex backwards and decimals forward, but for some reason the backwards hex does not convert into the right decimal number, even though I use the exact same method as I do when it's forward and working. I'm using strtol() and I am printing out the variables to the serial monitor to see what happens to the data along the way.

Here is my code:

#include <SPI.h>
#include <MFRC522.h>
#include <stdlib.h>


#define RST_PIN         9          
#define SS_PIN          10       

String inStringDec = "";
String inStringHex = "";
String inStringHexRev = "";

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

void setup() {
	Serial.begin(9600);		// Initialize serial communications with the PC
	while (!Serial);		// Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
	SPI.begin();			// Init SPI bus
	mfrc522.PCD_Init();		// Init MFRC522
	mfrc522.PCD_DumpVersionToSerial();	// Show details of PCD - MFRC522 Card Reader details
	Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}

void loop() {
	// Look for new cards
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial())
  {
    //Serial.print("Card UID:");
    for (byte i = 0; i < mfrc522.uid.size; i++) {
      //Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
      Serial.print(mfrc522.uid.uidByte[i], HEX);
      inStringHex += String(mfrc522.uid.uidByte[i], HEX);
      inStringHexRev += String(mfrc522.uid.uidByte[mfrc522.uid.size - (i + 1)], HEX);
    }

    //convert to decimal UID
    String WorkingStringA = inStringHex;
    long unsigned A = strtol(WorkingStringA.c_str(),NULL,16);
    Serial.println();
    Serial.println(F("long unsigned A:"));
    Serial.print(A);
    WorkingStringA = String(A);
    String WorkingStringB = inStringHexRev;
    Serial.println();
    Serial.println(F("(NOT!)WorkingStringB:"));
    Serial.print(WorkingStringB);
    long unsigned B = strtol(WorkingStringB.c_str(),NULL,16);
    Serial.println();
    Serial.println(F("long unsigned B:"));
    Serial.print(B);
    WorkingStringB = String(B);
    Serial.println();
    Serial.println(F("Hex normal and reverse:"));
    Serial.print(inStringHex);
    Serial.println();
    Serial.print(inStringHexRev);
    Serial.println();
    Serial.println(F("Decimal seperated:"));

    for (byte i = 0; i < mfrc522.uid.size; i++) {
      //Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
      Serial.print(mfrc522.uid.uidByte[i], DEC);
      Serial.print(F(" "));
      //inStringDec += String(mfrc522.uid.uidByte[i], DEC);
    }

    inStringHex = "";
    inStringHexRev = "";
    Serial.println();
    Serial.println(F("Card UID:"));
    Serial.print(WorkingStringA);
    Serial.println();
    Serial.println(F("Card UID Reversed:"));
    Serial.print(WorkingStringB);
    Serial.println();
    delay(5000);
  }
}

Here is a screenshot of the monitor output:

As you might be able to see, the hex string gets converted into a wrong number; 2147483647 when reversed. It should be 3097938530. Any idea why this is happening?

2147483647 is hex 7FFF FFFF, the maximum a long integer can hold. Unsigned long can hold twice as large number. I do see references to unsigned long in your code, but my guess is somewhere it is lost.

You can check validity of that theory if you have a card with lower UID than 2147483647. If lower gives you correct result integer size is the problem.

Yes, I found a tag with UID 1973702853 and it works, so you are correct. How does it get lost/changed into signed though? Any idea how to fix it?

Try to change strtol to strtoul

long unsigned B = strtol(WorkingStringB.c_str(),NULL,16);

to

long unsigned B = strtoul(WorkingStringB.c_str(),NULL,16);

Working like a charm, thank you for all your help Gabriel.

kortpriser:
Ok, I'm almost there now, but there is a final issue that I can't resolve. I can store the UID as hex forward, hex backwards and decimals forward, but for some reason the backwards hex does not convert into the right decimal number, even though I use the exact same method as I do when it's forward and working. I'm using strtol() and I am printing out the variables to the serial monitor to see what happens to the data along the way.

Here is my code:

#include <SPI.h>

#include <MFRC522.h>
#include <stdlib.h>

#define RST_PIN         9          
#define SS_PIN          10

String inStringDec = "";
String inStringHex = "";
String inStringHexRev = "";

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}

void loop() {
// Look for new cards
 if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial())
 {
   //Serial.print("Card UID:");
   for (byte i = 0; i < mfrc522.uid.size; i++) {
     //Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     Serial.print(mfrc522.uid.uidByte[i], HEX);
     inStringHex += String(mfrc522.uid.uidByte[i], HEX);
     inStringHexRev += String(mfrc522.uid.uidByte[mfrc522.uid.size - (i + 1)], HEX);
   }

//convert to decimal UID
   String WorkingStringA = inStringHex;
   long unsigned A = strtol(WorkingStringA.c_str(),NULL,16);
   Serial.println();
   Serial.println(F("long unsigned A:"));
   Serial.print(A);
   WorkingStringA = String(A);
   String WorkingStringB = inStringHexRev;
   Serial.println();
   Serial.println(F("(NOT!)WorkingStringB:"));
   Serial.print(WorkingStringB);
   long unsigned B = strtol(WorkingStringB.c_str(),NULL,16);
   Serial.println();
   Serial.println(F("long unsigned B:"));
   Serial.print(B);
   WorkingStringB = String(B);
   Serial.println();
   Serial.println(F("Hex normal and reverse:"));
   Serial.print(inStringHex);
   Serial.println();
   Serial.print(inStringHexRev);
   Serial.println();
   Serial.println(F("Decimal seperated:"));

for (byte i = 0; i < mfrc522.uid.size; i++) {
     //Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     Serial.print(mfrc522.uid.uidByte[i], DEC);
     Serial.print(F(" "));
     //inStringDec += String(mfrc522.uid.uidByte[i], DEC);
   }

inStringHex = "";
   inStringHexRev = "";
   Serial.println();
   Serial.println(F("Card UID:"));
   Serial.print(WorkingStringA);
   Serial.println();
   Serial.println(F("Card UID Reversed:"));
   Serial.print(WorkingStringB);
   Serial.println();
   delay(5000);
 }
}




Here is a screenshot of the monitor output:
![|500x424](http://i63.tinypic.com/15f0fwp.gif)

As you might be able to see, the hex string gets converted into a wrong number; 2147483647 when reversed. It should be 3097938530. Any idea why this is happening?

Hi,

I've used this code. But i have problem when i save leading zero into String.
May someone help me how to do that?

But i have problem when i save leading zero into String.
May someone help me how to do that?

Without knowing what the problem is? No.

if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial())
  {
    //Serial.print("Card UID:");
    for (byte i = 0; i < mfrc522.uid.size; i++) {
      Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
      Serial.print(mfrc522.uid.uidByte[i], HEX);
      inStringHex += String(mfrc522.uid.uidByte[i], HEX);
      inStringHexRev += String(mfrc522.uid.uidByte[mfrc522.uid.size - (i + 1)], HEX);
    }
 }

The problem is if the card starting with 0, how to save it into String?

The problem is if the card starting with 0, how to save it into String?

Maybe exactly the same way you print it to the serial port. You print a space and a 0 or just a space, if the value is less than 0x10. So, if the value is less than 10, add a space to the String, then add the value. If not, just add the value.

PaulS:
Maybe exactly the same way you print it to the serial port. You print a space and a 0 or just a space, if the value is less than 0x10. So, if the value is less than 10, add a space to the String, then add the value. If not, just add the value.

Thank you sir. Now it's work if the card statred with 0 :slight_smile: :slight_smile: :slight_smile:

//last solution of mine

#include <SPI.h>
#include <MFRC522.h>
#include <stdlib.h>

#define RST_PIN D1 // it is for esp8266 , if u want to use it arduino change it to your pin number(10)
#define SS_PIN D2 //

String inStringDec = "";
String inStringHex = "";
String inStringHexRev = "";

MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance

void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}

void loop() {
if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
inStringHex = "";
for (byte i = 0; i < mfrc522.uid.size; i++) {
if (mfrc522.uid.uidByte < 0x10) {

  • inStringHex += "0";*
  • }*
    _ inStringHex += String(mfrc522.uid.uidByte*, HEX);_
    _
    }_
    _
    }_
    int str_len = inStringHex.length() + 1;
    char char_array[str_len - 1];
    inStringHex.toCharArray(char_array, str_len);
    _
    String rfidTemp = "";_
    _
    for (int i = 7 ; i >= 1; i -= 2) {_
    rfidTemp += char_array[i - 1];
    rfidTemp += char_array;
    _ }
    Serial.println(rfidTemp);
    char str[9];
    rfidTemp.toCharArray(str, 9);
    int val = (int)strtol(str, NULL, 16);
    Serial.println(val);
    }*_