I am working on a project for my local Makerspace, we have limited budget so I was hoping to use the RFID-RC522 el'cheap'o RFID/NFC readers on eBay, I received a couple of SPI based boards, they work, however the code examples for them are limited.

I have found several different libraries and settled on this one: https://github.com/ljos/MFRC522

The trouble is that all the code available online seem to spawn from some Chinese guys Python code that people have translated, and hacked into an Arduino library.

The code works, but Mifare cards are meant to have 4, 7 or 10 byte UIDs and the example/library is returning a 5 byte serial number.

There is no documentation and the NXP datasheet is incomprehensible... Additionally it seems to work with most cards, but it doesn't work with Mastercard PayWave cards which conform to the ISO 14443 standard. The more expensive RDM880 reader which is based on the MFRC500 works fine and has a nice library but the cost makes the implementation impossible.

So, can someone help me to get this NXP MFRC522 based unit reading the UID from all ISO 14443 cards.

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

#define RFID_SS  10
#define RFID_RST 5

MFRC522 rfid( RFID_SS, RFID_RST );

void setup() {

void loop() {
  byte data[MAX_LEN];
  byte uid[5];

  if ( rfid.requestTag( MF1_REQIDL, data ) == MI_OK ) {
    if ( rfid.antiCollision( data ) == MI_OK ) {
      memcpy( uid, data, 5 );
      for ( int i = 0; i < 5; i++ ) {
        Serial.print( uid[i], HEX );
        Serial.print( ' ' );
  • This is probably not the problem, but your uid array is of length 5. Did you try using a larger array since you want a 10 byte result?
    – asheeshr
    Apr 30, 2014 at 1:58
  • Yes, I did but it didn't help, in fact the other reader seems to only return 4 byte numbers and it's a different make with decent example code, very confused. May 1, 2014 at 17:11

4 Answers 4


Sorry, but I must disagree with your 'NXP datasheet is incomprehensible'. From the FIRST PAGE of the MFRC522 datasheet:

'Remark: The MFRC522 supports all variants of the MIFARE Mini, MIFARE 1K, MIFARE 4K, MIFARE Ultralight, MIFARE DESFire EV1 and MIFARE Plus RF identification protocols'

Here it says the MFRC522 covers just a part of ISO/IEC 14443. The following are missing fron the NXP RC522:

*MIFARE DESFire EV1 (includes AES encryption)

MIFARE DESFire EV2 (includes MIsmartApp, Transaction MAC, Unlimited Applications MIFARE Plus drop-in replacement for MIFARE Classic with certified security level (AES 128 based))

MIFARE SAM AV2 (secure access module that provides the secure storage of cryptographic keys and cryptographic functions)*

These are probably the ones used in bank cards. Again, from the FIRST PAGE of the MFRC500 datasheet:

'All protocol layers of the ISO/IEC 14443 A are supported.'

You'll have to plow through all the different MIFARE / ISO/IEC 14443 specs to find out how many ID bytes there are for the different types (I suspect diferent types return a different quantity of bytes).

So, basically, you're screwed. Spring for the expensive MFRC500-based reader. I assume that with the higher cost you also get a high-class API, documentation and examples or even (gasp!) tech support.


  • 1
    You are right that the MFRC522 doesn't support this, but you are wrong that the MFRC500 is the solution, that device only supports MIFARE Classic, MIFARE 1K (S50) and MIFARE 4K (S70) cards. Dec 22, 2014 at 0:46
  • 1
    Also the MFRC522 module is <£3 and the MFRC500 is £30. Dec 22, 2014 at 0:47

The MFRC522::requestTag() returns the card type in the first two bytes of the 2nd parameter (data in your example above). You will need to look at this value to determine which sort of card it is. Use this information to print out the required N bytes of ID.

At a pinch, you could dump out the full 16 bytes (MAX_LEN), and test them with your various card types to see which bytes are changing in a deterministic manner, thus allowing you to determine the correct length of the ID.

And in case it saves you some time, if you call that library's self-test functions - getFirmwareVersion() and digitalSelfTestPass(); it's necessary to call MFRC522::begin() again, otherwise it's not possible to read RFID IDs (at the time of writing of course.)


Try using the most popular one.


This is working for me. It returns the uID as what you desire. Just remove the other functions just the getting of the uid from its example.


The fifth byte from the RC522 is just a checksum.

For instance, a possible return value (taken from https://github.com/miguelbalboa/rfid/issues/604#issuecomment-1885042556 ) is:

8B 65 66 B9 31

and if you do the binary xor of the first four numbers, you get precisely the fifth:

In [1]: hex(int("8B", 16)^int("65", 16)^int("66", 16)^int("B9", 16))[2:]
Out[1]: '31'

(Indeed, if you compare the first four bytes from the RC522 with the four bytes from the other reader, they should coincide)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.