I\'m using this RFID module for Arduino Ethernet R3 and I need to retrieve from the Software Serial the card (TAG) ID that is written outside the tag. The module\'s datasheet sa
Here's a walkthrough of how to calculate the checksum.
Take your card number (this is just directly quoted from your text)
I received: 2
I received: 51
I received: 67
I received: 48
I received: 48
I received: 67
I received: 69
I received: 55
I received: 53
I received: 52
I received: 67
I received: 67
I received: 66
I received: 3
This would give you a number that is equivalent to the following:
2 51 67 48 48 67 69 55 53 52 67 67 66 3
The first numer (2) indicates that this is the beginning of a request.
The last number (3) indicates that this is the end of a request.
2 51 67 48 48 67 69 55 53 52 67 67 66 3
For the purposes of calculating the checksum, we are going to remove these two numbers. So your new number is now:
51 67 48 48 67 69 55 53 52 67 67 66
The last two numbers that you have are your checksum. The remaining numbers are your card number. So:
Your card number is:
51 67 48 48 67 69 55 53 52 67
And your checksum is:
67 66
Next you need to convert your Card Number and your Checksum to ASCII values:
Your card number is:
3 C 0 0 C E 7 5 4 C
And your checksum is:
C B
Next, grab each number into pairs:
Your card number is:
3C 00 CE 75 4C
And your checksum is:
CB
Then you need to treat each pair as a HEXIDECIMAL value and do an XOR against them. So basically you need to prove the following:
3C ^ 00 ^ CE ^ 75 ^ 4C == CB
(3C ^ 00) = 3C
3C ^ CE ^ 75 ^ 4C == CB
(3C ^ CE) = F2
F2 ^ 75 ^ 4C == CB
(3C ^ CE) = 87
87 ^ 4C == CB
(87 ^ 4C) = CB
CB == CB
Because CB == CB, this is a valid transaction.
No doubt someone else can come up with a better approach than this, but there should be enough pseudo code here for you to write it yourself.
I found this blog which has an implementation in Arduino, I've adapted it to work in Java
and results are good. Since there are a lot of bitwise operations - I used http://www.miniwebtool.com/bitwise-calculator/ to try to understand what's going on. I understand all of it except (val | (tempbyte << 4))
, I mean I understand what the statement does, I just struggle to see how that produces the result I want.
void loop () {
byte i = 0;
byte val = 0;
byte code[6];
byte checksum = 0;
byte bytesread = 0;
byte tempbyte = 0;
if(Serial.available() > 0) {
if((val = Serial.read()) == 2) {
// check for header
bytesread = 0;
while (bytesread < 12) {
// read 10 digit code + 2 digit checksum
if( Serial.available() > 0) {
val = Serial.read();
if((val == 0x0D)||(val == 0x0A)||(val == 0x03)||(val == 0x02)) {
// if header or stop bytes before the 10 digit reading
break;
// stop reading
}
// Do Ascii/Hex conversion:
if ((val >= '0') && (val <= '9')) {
val = val - '0';
} else if ((val >= 'A') && (val <= 'F')) {
val = 10 + val - 'A';
}
// Every two hex-digits, add byte to code:
if (bytesread & 1 == 1) {
// make some space for this hex-digit by
// shifting the previous hex-digit with 4 bits to the left:
code[bytesread >> 1] = (val | (tempbyte << 4));
if (bytesread >> 1 != 5) {
// If we're at the checksum byte,
checksum ^= code[bytesread >> 1];
// Calculate the checksum... (XOR)
};
} else {
tempbyte = val;
// Store the first hex digit first...
};
bytesread++;
// ready to read next digit
}
}
// Output to Serial:
if (bytesread == 12) {
// removed code for clarity
LCD.print("Check:");
LCD.print(code[5], HEX);
LCD.print(code[5] == checksum ? "-passed" : "-error");
}
bytesread = 0;
}
}
}
My Java/Android port is listening over a BluetoothSocket
. I'm using the code from BlueTerm as the base, this code goes in the ConnectedThread
. Apologies for all silly comments, but I'm still learning Java).
//assume you have checksum as int and code as int array. it will overflow if bytes are used like above example
public void run() {
Log.d(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (true) {
Log.d(TAG, "Running");
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
for (int i = 0; i < bytes; i++) {
Log.d(TAG, "Reading: " + i + " of " + bytes + " from input stream");
byte b = buffer[i];
try {
if(bytesread >= 0) {
//just printing ASCII
char printableB = (char) b;
if (b < 32 || b > 126) printableB = ' ';
Log.d(TAG, "'" + Character.toString(printableB) + "' (" + Integer.toString(b) + ")");
if((b == 0x0D)||(b == 0x0A)||(b == 0x03)||(b == 0x02)) {
// if header or stop bytes before the 10 digit reading
Log.e(TAG, i + " Unexpected header while processing character " + Integer.toString(b));
} else {
// Do ASCII/Hex conversion
if ((b >= '0') && (b <= '9')) {
b = (byte) (b - '0');
} else if ((b >= 'A') && (b <= 'F')) {
b = (byte) (10 + b - 'A');
}
if ((bytesread & 1) == 1) {
//if isOdd(bytesread)
// make some space for this hex-digit by shifting the previous hex-digit with 4 bits to the left:
code[bytesread >> 1] = (b | (tempbyte << 4));
if (bytesread >> 1 != 5) {
// If we're not at the checksum byte,
checksum ^= code[bytesread >> 1];
// Calculate the checksum... (XOR)
}
} else {
// Store the first hex digit first
tempbyte = b;
}
}
bytesread++;
} else if(b == 2) {
bytesread = 0;
Log.d(TAG, "Header found!");
}
if(bytesread == 12) {
String check = (code[5] == checksum ? "-passed" : "-error");
String r = "";
for(int j = 0; j < 5; j++){
r += Integer.toString(code[i]);
}
Log.d(TAG, "Check:" + Integer.toString(code[5]) + check);
init();
} else if(bytesread > 12){
Log.e(TAG, "Too many bytes!");
}
} catch (Exception e) {
Log.e(TAG, i + " Exception while processing character " + Integer.toString(b), e);
}
}
String a = buffer.toString();
a = "";
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
Log.i(TAG, "END mConnectedThread");
}