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);
`