Hooking up an RFID Reader (ID-20)

Hi

This is my first circuit with an Imp. I couldn’t find any example code for hooking it up to an ID-20 so I thought I would write this post on what I found. If there are any errors please advise.

The ID-20 data sheet is where I started and the important bit is the data format that is transmit from it to the connected micro controller (in this instance the Imp-001). The data format is basically as follows:

[0x2] Start byte
[0x0000000000] 10 x bytes to represent the RFID tag code in ASCII for example 0x01082F86DC
[0x00] 2 x bytes to represent the checksum which is an XOR of the 10 bytes above, for example 7C
[0x13] An ASCII CR byte
[0x10] An ASCII LF byte
[0x3] Stop byte

To complete the checksum the five ASCII data strings need to be literally interpreted as hex (and not the decimal byte value that was transmit). So the first two bytes (01) are equal to 00000001 in binary, the second two bytes (08) are equal to 00001000 in binary. These two bytes are ‘XORed’ to calculate a new byte that is to be ‘XORed’ against the third two bytes (2F). This process is reapeated until all of the data bytes have been ‘XORed’. The full process is shown below (using the example RFID ID above):

HEX BYTE 1 (01) 0 0 0 0 0 0 0 1
HEX BYTE 2 (08) 0 0 0 0 1 0 0 0
XOR 0 0 0 0 1 0 0 1
HEX BYTE 3 (2F) 0 0 1 0 1 1 1 1
XOR 0 0 1 0 0 1 1 0
HEX BYTE 4 (86) 1 0 0 0 0 1 1 0
XOR 1 0 1 0 0 0 0 0
HEX BYTE 5 (DC) 1 1 0 1 1 1 0 0
FINAL XOR (7C) 0 1 1 1 1 1 0 0

Here is the circuit:

Finally the code to read the tag:
`
// code to read RFID tags using an ID-20 RFID reader
imp.configure(“RFID Reader”, [], []);

// we use this variable to store the last read rfid tag
local hex_string = “”;

// this function is invoked when the id-20 has some data
function read_rfid()
{
// reset the rfid tag value to an empty string
hex_string = “”;

// delay so the id-20 has time to transfer all the data at 9600 baud
imp.sleep(0.15);

// this should be 0x02
local b = hardware.uart12.read();

if(b != 2)
{
    // no need to process this as the start byte is incorrect
    return;
}

// read until we find the CR byte 0x13
while(b != 13)
{
    b = hardware.uart12.read();
    hex_string += b.tochar();
}

// read the rest of the data (0x10 + 0x03)
// this is a LF character and an end byte
while(b != -1)
    b = hardware.uart12.read();

// do the checksum
if(!checksum_is_correct())
{
    server.log("checksum is incorrect, will not process");
    return;
}

// do whatever you want with the rfid string, send to an agent, web server... whatever
// just remember that the hex_string contains the checksum as the final two ASCII characters
server.log("read: 0x" + hex_string);

// delay to avoid duplicate read, unlikely but hey
imp.sleep(0.15);

}

// function to make sure the checksum is correct
function checksum_is_correct()
{
// read in the first two bytes and convert to an integer
local int1 = hex_to_integer(hex_string[0].tochar() + hex_string[1].tochar());
local xor;

// xor the remaining data bytes
for(local i = 2; i < 10; i+=2)
{
    local int2 = hex_to_integer(hex_string[i].tochar() + hex_string[i+1].tochar());

    xor = int1 ^ int2;
    int1 = xor;
}

// the final xor should be equal to the last two bytes in the hex_string
local checksum = hex_to_integer(hex_string[10].tochar() + hex_string[11].tochar());

if(checksum != xor)
{
    return false;
}
else
{
    return true;
}

}

// function to convert a hex string to an integer value - found on imp forums
// http://forums.electricimp.com/discussion/623/squirrel-hex-to-integer/p1
function hex_to_integer(hex)
{
local result = 0;
local shift = hex.len() * 4;

for(local d=0; d<hex.len(); d++)
{
    local digit;

    if(hex[d] >= 0x61)
        digit = hex[d] - 0x57;
    else if(hex[d] >= 0x41)
         digit = hex[d] - 0x37;
    else
         digit = hex[d] - 0x30;

    // Accumulate digit
    shift -= 4;
    result += digit << shift;
}

return result;

}

// configure uart on pins 1 and 2, invoking read_rfid when data is ready
hardware.uart12.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS, read_rfid);

`

Nice work! If I can track down an ID-20 I’ll definitely try out your code!

The ID-20 is a pretty standard “maker” RFID reader… I believe both SparkFun and Adafruit carry them.

I got mine here, in the UK: http://www.coolcomponents.co.uk/catalog/rfid-reader-p-155.html

You’ll need a breakout board if you want to put it in a breadboard as the pins aren’t spaced out for a breadboard.

Its out of stock at Sparkfun… Adafruit has an RFID/NFC board, but its a different chip. Robotshop has em…

Ebay: http://www.ebay.com/itm/RFID-Reader-ID-20-Perfect-With-Arduino-Uno-or-Mega-/190635812226?pt=LH_DefaultDomain_0&hash=item2c62c7a582

You should be able to use an ID-12 also.

A lot cheaper.
I´m using it with arduino and works very well.

Why is the ID-20 so expensive?

Is there no issue with connecting up the data lines between the 5V ID20 to the 3.3V imp ? Or is a logic level converter required ?

A logic level converter is required.

Connecting more than 3.3v directly to the imp’s pins can cause damage.

@ramstein74 - I got the ID-20 for about £30-odd but yeah it is quite expensive. The RFID reader you link has a different read frequency (13.56MHz = 13560KHz). I’m no expert on RFID (correct me if I’m wrong) but my requirements are to read at 125KHz so unfortunately this unit is not good for my requirements.

There is probably a cheaper 125KHz unit than the ID-20 but I haven’t looked to be honest.

Edit: I have also found the ID-20 a bit bulky, a smaller module might be better when fitting them into ‘project’ boxes - particularly when the breakout board is soldered to the bottom!

@302tt - as beardedinventor points out you will need a logic level converter. For my testing I simply connected two different power supplies.