Arduino RC522 RFID Basics

Introduction: Arduino RC522 RFID Basics

In an earlier post I detailed the basics of interfacing to the popular RC522 and PN532 RFID modules. I followed that up with a simple Electronic Wallet implementation also based on those two modules. All of those projects used my favorite combination of the PIC microcontroller and assembly language programming. Given my recent fascination with the Arduino (and more rainy days) I decided to translate the PIC programs for the RC522. I won’t repeat the tons of useful information found in my previous posts so I highly recommend that you read them to better understand what is going on.

Step 1: Schematic

Note: To enable the UART mode refer to the circuit cut described in my previous Instructable.

The schematic is shown above and includes the connections for a 4-bit 1602 LCD interface. It looks pretty much like the PIC diagram and uses the built-in serial interface of the Arduino. Note the two resistors connected to the RC522 module SDA input. The module operates at +3.3 volts so the two resistors act as a voltage divider for the +5 volt signal coming from the Arduino serial TX pin. The Arduino is happy with the +3.3 volt serial data from the RC522 so no logic level conversion is required.

There are two switches used for the Electronic Wallet version but they are not needed for the basic version of the software. One switch allows for manual initialization of the tag and the other allows for adding credits to the tag. The switches can be either momentary contact or toggle types and would normally be hidden from the user.

Step 2: Software

As in the PIC application there are two versions of software. One is a demo of the basic read/write capabilities of a tag and the other is an example of using a tag as an Electronic Wallet. For the most part they are direct translations of the PIC assembly language. There are a few subtle differences in implementation but nothing that really changes the functionality.

The basic version uses an arbitrary data pattern that gets modified each loop through the code. The Electronic Wallet version has an initialized credit value of “0” and there are defined values at the front of the software for the amounts to increment or decrement the stored credits. Keep in mind that these values are in packed BCD format. That means that a value of “0x12” represents twelve.

Because everything is stored in packed BCD, the math for increment and decrement needs to include correction of the results. That operation is called “Decimal Adjust” and some microcontrollers include specific instructions for both DAA (Decimal Adjust Add) and DAS (Decimal Adjust Subtract). The PIC I used in the original implementation did not have that capability so I wrote a couple of macros to handle it. I needed to figure out equivalent pieces of software for the Arduino and found a DAA function online but not a DAS function so I wrote my own.

That’s it for this post. Check out my other Instructables and also my website at: www.boomerrules.wordpress.com

Be the First to Share

    Recommendations

    • Space Contest

      Space Contest
    • Halloween Contest

      Halloween Contest
    • Lamps and Lighting Contest

      Lamps and Lighting Contest

    10 Comments

    0
    necchigonzalo
    necchigonzalo

    7 months ago on Step 2

    Hey! I've been trying to make this work for quite a while now with a different mcu. I pretty much copy-pasted your code and adapted the delays and serial communications from my mcu but the program is stuck in the setup step. When it asks for the firmware version (which should be 0x92) all I get is 0xB7, and I don't know if that's just coincidence but 0xB7 is the command I'm sending (0x37 + 0x80 = read VersionReg) any ideas why this is happening?

    0
    Boomer48
    Boomer48

    Reply 7 months ago

    Are you displaying the results on an LCD or looking at them some other way? Do you get any response from the "Dummy Command"? Maybe try not sending the "Dummy Command". If you send B7 and get B7 it is acting like it thinks that is a write command which doesn't make sense. Maybe try displaying the return values for each write command you send during startup to make sure that they return the correct register number. I did mention that another user had a problem with his brand of module not doing the UART communications after the board mod. Maybe that is the issue. If you want to use Instructables mail to send a plain text version of your software I can take a look to see if I spot anything obvious.

    0
    necchigonzalo
    necchigonzalo

    Reply 7 months ago

    thanks for the quick response! I realized that the RC522 is echoing everything I send to it, if I send a read to VersionReg it responds with B7h, if I send a write command like 15h 40h it just sends back those values in that order. I did a quick search and confirmed that my RC is not a clone, also I don't think I should be getting those responses if the UART mod didn't work right?

    0
    Boomer48
    Boomer48

    Reply 7 months ago

    If it is accepting the write commands properly you should only get a single byte response that echos the register number. So the 15h 40h command should only return 15h. Sounds like the RC522 UART is not working for some reason. If it were me I would try the following:

    1. Double check the board modification with an ohmmeter to make sure the right traces are disconnected and the one that needs to stay connected is connected.

    2. Disconnect the RC522 and see if you get the same response. That would likely mean that your micro RX buffer is somehow echoing the TX buffer. Make sure the baud rate is 9600, 8-bit, no parity, 1 stop bit.

    3. With the RC522 connected, make sure you have 100ms or so delay before sending the first command to it. I have that in my software specifically for the LCD but it also allows the RC522 time to initialize.

    4. Try removing the dummy read (80h) command.

    0
    necchigonzalo
    necchigonzalo

    Reply 7 months ago

    Ok I tried all that.
    1. The trace is properly cut, checked that with my multimeter.
    2. When I disconnect the RC522 I don't receive anything. Uart configuration is correct.
    3. I added 100ms and then a bit more just to make sure but the responses are always the same.
    4.Dummy read returned 0x80, without it it just returns the next command, 01h and 0Fh.
    I'm inclined to think my RC522 is faulty, but I also bought a PN532, adapted your Arduino code on that one too but I have no response at all. So I'm either really unlucky or my code is wrong.

    0
    Boomer48
    Boomer48

    Reply 7 months ago

    Sorry to hear you are having so much trouble. It sure sounds like a basic UART communication issue. If you had access to an Arduino Nano or UNO you could at least verify that your boards are OK. The PN532 should be easier to work with. If your board is like mine, it has a DIP switch for setting the communications mode and both sections should be open for HSU. I actually just took the switch completely off of the board. Also, the baud rate should be set to 115k and I'm assuming that you are sending the wakeup sequence.

    0
    necchigonzalo
    necchigonzalo

    Reply 7 months ago

    It's Ok, I really appreciate you taking the time to help me with this, nobody could help me when I asked on reddit. I tried the PN532 with an arduino and confirmed it works fine, and since it uses UART out of the box I'll keep trying with that one. You are probably right, maybe I'm not configuring UART correctly, I'll check that again with the manual, I just was so sure it works because I received data correctly when I connected the mcu's RX with its TX line. I have a question tho, in your comments you wrote that one should "add more zeros if needed to wake up", should I be getting some kind of response between that sequence and the SAM configuration? How can I know if I should send more zeros?

    0
    Boomer48
    Boomer48

    Reply 7 months ago

    Glad to hear it works with an Arduino. The "more zeros" comment was based on some online chatter when I was researching the issue. The sequence in my software matches what the spec says and it apparently works with your Arduino so that shouldn't factor into your other MCU issue. I don't think there is any response following the "wake-up". If you get responses to the subsequent commands then it's awake. If not, then a few more zeros may or may not help. The normal sequence worked for both my Arduino and my PIC applications.

    Connecting the MCU RX and TX lines is a good basic test that the right codes are being transmitted but it doesn't tell you if the baud, parity, start and stop bits are properly set for the RFID board or if the wiring is correct.

    0
    necchigonzalo
    necchigonzalo

    Reply 7 months ago

    Hello again! So I finally fixed my problem. It was, as you correctly suggested, the UART configuration.
    For some reason enabling the internal FIFO on the peripheral did the trick. I just wanted to update this conversation here for anyone having the same problem and to thank you for you all your help. I'll probably be back with more problems once I try some of the other instructables tho! (The RF and IR remote control projects look very interesting to me)

    0
    Boomer48
    Boomer48

    Reply 7 months ago

    So glad to hear that you figured it out. I usually learn the most on the projects where I have the most problems. I always want to figure things out at a low level so I tend to avoid the standard libraries.