Friday, June 1, 2012

RDM6300 RFID with PIC18 Dev Board

After getting a simple LED-blink program working, I moved on to the RFID portion of my project.  It seemed to be the simplest of the three major parts (RFID, SD card, and MP3) because it's basically just configuring the UART to receive and check the card IDs.  I'm using the RDM6300 UART RFID Module from ITeadStudio, which cost $11 for the reader and $0.50 per card.  The datasheet is posted and it describes both the pinout of the module and the data format.  I started out by wiring up the power, ground, and TX line to an FTDI breakout board to verify that the RFID reader worked correctly by reading the data into Docklight.  The data format is 9600bps 8N1 serial.  The datasheet listed 13 bytes (0x02, 10 data bytes, checksum, 0x03), yet I consistently received 14 bytes.  I'm not totally sure what's going on, but I always get the same 14 bytes, so I just recorded those for each of the 10 cards I purchased.  The table below shows the hex values I receive for each of the cards.


The datasheet for the RFID module lists the operating current as <50 mA, which is high enough that I want to be able to turn the module on and off from the PIC instead of just leaving it on all the time.  To do this, I used a 2N3906 PNP transistor in between the board 5V supply and the RFID 5V supply, with the base connected to a GPIO with a 1k resistor.  Turning the GPIO high turns the RFID module on;  setting it low turns the RFID module off.  Using the transistor dropped the supply from 5V to 4.87V, but this is still within the +/-5% of 5V listed on the datasheet spec, and it appears to be working just fine.  I also added a resistor divider to the UART TX line of the RFID module to bring the 5V output down below 3.3V.  The following two pictures show a circuit diagram of this, and then what it looks like soldered onto my development board (some parts/wires were soldered underneath the RFID module).



The PIC C18 compiler comes with a set of peripheral libraries, including one for the USART, which made it very easy to configure the USART and had a good example of using it to send and receive data.  Once I verified that I could receive a single card's data, I set up a demo with three RFID tags programmed into the PIC so that it would toggle an LED based on which card was swiped.  I initially tried to use the "gets1USART" function to read a 14 characters off of the USART, but every once and a while the RFID unit spits out a random bad character (sometimes at power up) that was causing me issues.  Instead, the USART reception is handled using an interrupt service routine, and I pulled the basic setup for it from an Example #6 in an older copy of the C18 Getting Started Guide.  The code is below, followed by a video of the demo.  Note that the code assumes a 16 Mhz clock speed, like my previous post.  You'll need to adjust the USART initialization line and delay line if you're using a different clock speed.

#include <p18lf26j11.h>
#include <delays.h>
#include <usart.h>
#include <string.h>

#pragma config OSC = HS //High speed crystal
#pragma config WDTEN = OFF //Disable watchdog timer
#pragma config XINST = OFF //Disable Extended CPU mode

//LED Pin Configuration
#define LED1Pin LATAbits.LATA0
#define LED1Tris TRISAbits.TRISA0
#define LED2Pin LATAbits.LATA1
#define LED2Tris TRISAbits.TRISA1
#define LED3Pin LATAbits.LATA2
#define LED3Tris TRISAbits.TRISA2

#define RFIDVCCPin LATBbits.LATB4 //Define RFIDVCCPin as PORT B Pin 4
#define RFIDVCCTris TRISBbits.TRISB4 //Define RFIDVCCTris as TRISB Pin 4

//Flags & Data Reception Variables
volatile char tagRecdFlag;
volatile char tagComingFlag;
volatile char tagCounter;
volatile char tagRX[14] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

//RFID Tag IDs
char rfidTag1[14] = {0x02, 0x30, 0x35, 0x30, 0x30, 0x41, 0x44, 0x44, 0x38, 0x46, 0x46, 0x43, 0x3f, 0x03};
char rfidTag2[14] = {0x02, 0x30, 0x35, 0x30, 0x30, 0x41, 0x44, 0x42, 0x46, 0x35, 0x37, 0x36, 0x30, 0x03};
char rfidTag3[14] = {0x02, 0x30, 0x35, 0x30, 0x30, 0x41, 0x45, 0x33, 0x46, 0x36, 0x35, 0x44, 0x33, 0x03};

//Function Prototypes
void rx_handler(void);
//Function Prototypes

#pragma code rx_interrupt = 0x8
void rx_int(void)
{
    _asm goto rx_handler _endasm
}
#pragma code

#pragma interrupt rx_handler
void rx_handler(void)
{
    unsigned char rxByte;
    rxByte = RCREG1; //Read character received from USART

    if (tagComingFlag == 0 && rxByte == 0x02)
    {
        tagRX[tagCounter] = rxByte;
        tagComingFlag = 1;
        tagCounter++;
    }   else if (tagComingFlag == 1)
        {
            tagRX[tagCounter] = rxByte;
            tagCounter++;
            if (tagCounter == 14)
            {
                tagCounter = 0;
                tagComingFlag = 0;
                tagRecdFlag = 1;
            }
        }   else
            {
                tagComingFlag = 0;
                tagCounter = 0;
            }
    PIR1bits.RCIF = 0; //Clear interrupt flag
}

void main()
{
        //Set LED Pins data direction to OUTPUT
        LED1Tris = 0;
        LED2Tris = 0;
        LED3Tris = 0;
        //Set LED Pins to OFF
        LED1Pin = 0;
        LED2Pin = 0;
        LED3Pin = 0;

        tagRecdFlag = 0; //Set in ISR if new RFID tag has been read
        tagComingFlag = 0; //Indicates if a tag is partially received
        tagCounter = 0; //Counts byte index
        
        //USART1 Initialization
        Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 25);

        //Interrupts
        RCONbits.IPEN = 1;  //Enable interrupt priority
        IPR1bits.RC1IP = 1;  //Make receive interrupt high priority
        INTCONbits.GIEH = 1; //Enable all high priority interrupts
        
        //Turn on RFID Module
        RFIDVCCTris = 0; //Set to output
        RFIDVCCPin = 1; //Turn on RFID Module

        while(1)
        {
            if (tagRecdFlag)
            {                 
                //Toggle LED corresponding to which card was read
                if (memcmp(tagRX, rfidTag1, 14) == 0)
                {
                    LED1Pin = ~LED1Pin;
                }
                if (memcmp(tagRX, rfidTag2, 14) == 0)
                {
                    LED2Pin = ~LED2Pin;
                }
                if (memcmp(tagRX, rfidTag3, 14) == 0)
                {
                    LED3Pin = ~LED3Pin;
                }

                //Delay 1/2 sec & clear flags to prevent repeated card read
                Delay10KTCYx(200);
                tagRecdFlag = 0; 
                tagComingFlag = 0; 
                tagCounter = 0; 
                }
        }
}

23 comments:

  1. Dear all,

    I have a problem with these RFID modules. At first everything works well, with a Java serial library I read the card ID and it is correct. But after a short time I receive all zeros, in other words the reading is wrong. All the time the situation is the same. What can it be? Thanks in advance.

    ReplyDelete
  2. Thanks for the code snippet, I just used it to bring up a proto PIC18F25K20.

    http://wildsong.biz/index.php?Title=PIC18

    ReplyDelete
  3. thank youuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    you really made me recognize the starting byte '0x02'
    and this made my project work finally
    plzzzz keeep goiiing
    keeep sharing the good stuff

    ReplyDelete
  4. It's hard to tell from the data sheet, but I believe the checksum is 2 bytes. It looks like a hex value written using two ascii characters. That would explain the 14 bytes you (and I) are getting.

    ReplyDelete
  5. Hola que tal yo quisiera saber si este modulo se puede emplear para cualquier PIC. Yo tenia pensado usarlo para un sistema bolt que emplea un PIC 18F2550. Y otra consulta, en los pines del modulo donde estan Tx y Rx solamente se conecta salida Tx. Aca esta la pagina donde saque el proyecto. En ese proyecto utiliza como lector un ID-12 y es muy caro por eso tenia pensado comprar ese lector que es mucho mas barato:
    http://www.puntoflotante.net/BOLT-RFID.htm

    Desde ya muchas gracias...

    ReplyDelete
    Replies
    1. My Spanish isn't great, but I think the answer to what you're asking is that yes, you can use this with any PIC that has a UART, and you only need the TX pin from the RFID module connected to the RX pin on the PIC.

      Delete
  6. Hello such. I wonder that resistance should be placed with the LED. From that value? because every time I pass the card does not turn on the LED. From already thank you very much.

    ReplyDelete
    Replies
    1. I used 330 Ohms, but anything from 200-1k should be fine.

      Delete
    2. Probe because with these resistances and every time I pass the card does not turn on the LED. (The cathode connect it to pin 1 of the reader and the positive anode resistance), and every time I pass the card through the reader shows me some weird symbols on the screen (I would have to show the ten characters of the card and the name of the person). This is due to a problem of reader who sends me wrong data or PIC problem that does not recognize the data. From already thank you very much ...

      Delete
  7. This comment has been removed by the author.

    ReplyDelete
  8. Dear Sir,

    I am finding problem in getting correct data. i am using RDM6300 along with a key chain Tag. it has 10 numbers as tag on the keychain. But my Reader is not giving correct data. i display the data received out of the RDM6300, and all that i get is this sequence " Z Z Z Z Z Z Z" I don`t know what is the issue, anyone can help me? I am using PIC18F452 and have attached TX or RDM6300 with RX of the microcontroller.

    ReplyDelete
  9. Hi Admin Can you please tell me how can we decode the data we get out of the RMD6300 to get original tag value listed on the RFID Tag, because apparently we get different values than what we see written at the tags. Your help would be appreciable.

    ReplyDelete
  10. hi!
    From my knowledge, number, written on the tag is NOT the one actually embedded in the tag. it's completely diffrerent number.(well, supposely it's partly connected to embedded number, but in a complicated way) It's logically, too. Just think: if number would be the same and someone would accidentally see your tag number it's just a matter of time that he will copy your tag and enter your house...
    you just wait for number 02, then receive 10 numbers for tag number, then get additional two for CRC calculating, last one is 03. It's a good idea to implement CRC calculating, because with it you avoid reading random funny numbers which occasionally occur.

    ReplyDelete
  11. hi
    i bought this module and i received rev.2
    it has 4 pins more near logo.
    any idea about how to use them ?
    regards
    peppe

    ReplyDelete
  12. could you please explain how to interpret the readings do not understand ?, module bytes read

    TAG CODE 1 2 3 4 5 6 7 8 9 10 11 12 13 14
    0009228652 02 30 46 30 30 38 43 44 31 36 43 33 45 03
    0009225264 02 30 46 30 30 38 43 43 34 33 30 37 37 03
    0009225606 02 30 46 30 30 38 43 43 35 38 36 43 30 03
    0009217686 02 30 46 30 30 38 43 41 36 39 36 42 33 03
    0009200871 02 30 46 30 30 38 43 36 34 45 37 30 30 03
    0008198553 02 31 32 30 30 37 44 31 39 39 39 45 46 03

    ReplyDelete
    Replies
    1. The data itself doesn't really mean anything, but you can record the values and then use them in your program to associate some action/event with the read of a specific card. The important thing is that you receive the same values every time you scan the same card.

      Delete
  13. This comment has been removed by a blog administrator.

    ReplyDelete
  14. This comment has been removed by a blog administrator.

    ReplyDelete
  15. DEAR ADMIN CAN YOU PLEASE TELL ME: IF WE CAN APPLY TO ARDUINO AND RDM 6300 TO AVOID TAG COLLISION?

    ReplyDelete
  16. Thanks for the nice blog. It was very useful for me. I'm happy I found this blog. Thank you for sharing with us,I too always learn something new from your post. rfid tags

    ReplyDelete
  17. This is my first time i visit here. I found so many interesting stuff in your blog especially its discussion. From the tons of comments on your articles, I guess I am not the only one having all the enjoyment here! keep up the good work
    Asiarfid.com

    ReplyDelete
  18. Are the pin numbers in the JP34 diagram correct? The look inverted to me.

    ReplyDelete
  19. Values here need to be converted to ASCII first to be meaningful. For example, with the first row:

    02 30 35 30 30 41 44 43 43 31 34 33 36 03
    => START 0 5 0 0 A D C C 1 4 3 6 STOP
    => START 05 00ADCC14 36 STOP

    00ADCC14 in decimal is the value printed on the card (11389972).

    ReplyDelete