Texas, USA
Offline
Jr. Member
Karma: 0
Posts: 53
Arduino rocks!!
|
 |
« on: August 30, 2012, 10:29:29 pm » |
Hello, I have this dilemma with comparing two RFID Tag numbers using the ID-12 Reader and an Arduino Uno, one from a card, and the other in an array. I'd like to print to Serial: "Card is a Match", then do something. Im manipulating the example from this site: http://www.arduino.cc/playground/Code/ID12The tag Im trying to compare to: byte target_tag[TAG_LEN] = {0x4F, 0x00, 0x88, 0xB3, 0x4F}; I cant make up my mind which of these sets of code is the right one to use, as Ive seen them both work in other people's programs, but they wont work for me: if (bytesread == 12) { // if 12 digit read is complete Serial.print("5-byte master: "); for (i=0; i<5; i++) { if (master[i] < 16) Serial.print("0"); byte master1 = master[i]; Serial.print(master[i], HEX); Serial.print(" "); //Serial.println(); } if(memcmp(master, target_tag[i], TAG_LEN) == 0 ) { Serial.print("This Card is a Match!"); } } Serial.println();
Serial.print("Checksum: "); Serial.print(master[5], HEX); Serial.println(master[5] == checksum ? " -- passed." : " -- error."); Serial.println();
Or this one: if (bytesread == 12) { // if 12 digit read is complete Serial.print("5-byte master: "); for (i=0; i<5; i++) { if (master[i] < 16) Serial.print("0"); byte master1 = master[i]; Serial.print(master[i], HEX); Serial.print(" "); //Serial.println(); } for(int i = 0; i < ARR_LEN; i++) { if (CheckTwoBytes(target_tag[i], master)) { Serial.print("This Card is a Match!"); } } } Serial.println();
Serial.print("Checksum: "); Serial.print(master[5], HEX); Serial.println(master[5] == checksum ? " -- passed." : " -- error."); Serial.println(); }
boolean CheckTwoBytes ( byte a[], byte b[] ) { if ( a[0] != NULL ) // Make sure there is something in the array first match = true; // Assume they match at first
for ( int k = 0; k < 5; k++ ) // Loop 5 times { /* Serial.print("["); Serial.print(k); Serial.print("] ReadCard ["); Serial.print(a[k], HEX); Serial.print("] StoredCard ["); Serial.print(b[k], HEX); Serial.print("] \n"); */ if ( a[k] != b[k] ) // IF a != b then set match = false, one fails, all fail match = false; } if ( match ) // Check to see if if match is still true { //Serial.print("Strings Match! \n"); return true; // Return true } else { //Serial.print("Strings do not match \n"); return false; // Return false } }
Im trying to write the code myself, and learn how it works as Im writing it. I dont feel comfortable just copying and pasting other people's code just to get it to work. I've searched around the web, and found a variety of help pages, examples and tutorials, but nothing as detailed in explanation as Im looking for. Any help is greatly appreciated.
|
|
|
|
|
Logged
|
Working on a Smart Home Management System. Visit my blog: http://tae09.blogspot.com/ to find out more, and to keep track with the project.
|
|
|
|
0
Offline
God Member
Karma: 0
Posts: 592
|
 |
« Reply #1 on: August 30, 2012, 11:26:15 pm » |
where you write if(memcmp(master, target_tag[i], TAG_LEN) == 0 ) is PROBABLY wrong try if(memcmp(master, target_tag, TAG_LEN) == 0 )
|
|
|
|
|
Logged
|
I'm an electrical engineering student. I designed the USnooBie (V-USB dev kit) which is sold at Seeed Studio 
|
|
|
|
Texas, USA
Offline
Jr. Member
Karma: 0
Posts: 53
Arduino rocks!!
|
 |
« Reply #2 on: August 30, 2012, 11:42:51 pm » |
if(memcmp(master, target_tag, TAG_LEN) == 0 ) Hmm, for some reason it was throwing an error before: cannot compare byte* & byte...it works now, but only for one of my RFID cards. The other one wont validate. This is my array for all my tags that Ive got saved in the Arduino: byte target_tag[ARR_LEN][TAG_LEN]={{0x4F, 0x00, 0x88, 0xB3, 0x4F},{*My Other Tag*}}
|
|
|
|
|
Logged
|
Working on a Smart Home Management System. Visit my blog: http://tae09.blogspot.com/ to find out more, and to keep track with the project.
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 67
|
 |
« Reply #3 on: August 31, 2012, 02:06:59 am » |
Maybe this tutorial can help you futher, http://www.tigoe.net/pcomp/code/PHP/347/I did build my code around this and works great.
|
|
|
|
|
Logged
|
|
|
|
|
Texas, USA
Offline
Jr. Member
Karma: 0
Posts: 53
Arduino rocks!!
|
 |
« Reply #4 on: August 31, 2012, 12:15:09 pm » |
I appreciate the link, but Tom approaches this a little differently since he is reading and writing to EEPROM. However, I figured it out this morning by adding one extra loop to check my other Tag ID's. Now it works. Here is the code for the loop: for (int n=0; n<ARR_LEN; n++){ if(memcmp(master, target_tag[n], TAG_LEN) == 0 ) //Compares two bytes of TAG_LEN, if they are a match, the argument will be 0, thus 0 == 0 { Serial.println("This Card is a Match!"); } }
Thanks.
|
|
|
|
« Last Edit: August 31, 2012, 12:25:08 pm by UNTEngineer »
|
Logged
|
Working on a Smart Home Management System. Visit my blog: http://tae09.blogspot.com/ to find out more, and to keep track with the project.
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 313
Posts: 35502
Seattle, WA USA
|
 |
« Reply #5 on: September 01, 2012, 09:39:48 am » |
Here is the code for the loop: You could, of course, print in the body of the if statement the value of n, so you know WHICH tag the scanned one matched, if that was important.
|
|
|
|
|
Logged
|
|
|
|
|
Texas, USA
Offline
Jr. Member
Karma: 0
Posts: 53
Arduino rocks!!
|
 |
« Reply #6 on: September 03, 2012, 10:15:23 pm » |
I have another question, similarly relating to this. I want the program to print out when the card validates, and also when the card doesnt validate. Ive tried this: if(memcmp(master, target_tag[n], TAG_LEN) == 0 ) //Compares two bytes of TAG_LEN, if they are a match, the argument will be 0, thus 0 == 0 { Serial.println("This Card is a Match!"); } else if(memcmp(master, target_tag[n], TAG_LEN) != 0) { Serial.println("This Card is NOT a Match!"); }
If it validates, it outputs once. If it doesnt validate, it outputs twice- for each tag it reads in. What I want it to do is compare vs both tags, and then if it validates, great, output once - like its already doing. If not, output ONCE as well. Any suggestions of how to get that to work?
|
|
|
|
|
Logged
|
Working on a Smart Home Management System. Visit my blog: http://tae09.blogspot.com/ to find out more, and to keep track with the project.
|
|
|
|
0
Offline
God Member
Karma: 0
Posts: 592
|
 |
« Reply #7 on: September 04, 2012, 12:28:53 am » |
it's hard to diagnose the problem without the entire code
|
|
|
|
|
Logged
|
I'm an electrical engineering student. I designed the USnooBie (V-USB dev kit) which is sold at Seeed Studio 
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 313
Posts: 35502
Seattle, WA USA
|
 |
« Reply #8 on: September 04, 2012, 03:56:46 am » |
if(memcmp(master, target_tag[n], TAG_LEN) == 0 ) //Compares two bytes of TAG_LEN, if they are a match, the argument will be 0, thus 0 == 0 { Serial.println("This Card is a Match!"); } else if(memcmp(master, target_tag[n], TAG_LEN) != 0) If the value returned be memcmp() is not 0, how can it be anything but not zero? The second if test is redundant. Most likely what is happening is that you are learning that one of the tags is not tag 0 and is not tag 1, when you read tag 2. If you were to include n in the output message, I think you'd see that the messages are NOT identical. But, without seeing the whole code, who knows for sure.
|
|
|
|
|
Logged
|
|
|
|
|
Texas, USA
Offline
Jr. Member
Karma: 0
Posts: 53
Arduino rocks!!
|
 |
« Reply #9 on: September 05, 2012, 12:36:12 pm » |
If the value returned be memcmp() is not 0, how can it be anything but not zero? The second if test is redundant.
Most likely what is happening is that you are learning that one of the tags is not tag 0 and is not tag 1, when you read tag 2. If you were to include n in the output message, I think you'd see that the messages are NOT identical. But, without seeing the whole code, who knows for sure.
I was trying to do an IF/ELSE statement, and I wasnt getting anywhere, so I figured to try the opposite of my IF statement to see if that worked. It did exactly the same as the ELSE statement. So yes, its redundant. However, since you guys are most insistent about seeing the whole code to analyze the problem, here you go: #include <NewSoftSerial.h> NewSoftSerial mySerial(2, 3); //rx, tx
#define TAG_LEN 5 #define ARR_LEN 2
byte target_tag[ARR_LEN][TAG_LEN] = //This array of TAG ID's will later be in a database on the BB {{0x4F, 0x00, 0x88, 0xB3, 0x4F}, //Card 1 Tag ID {TAG_ID_2}}; //Card 2 Tag ID
boolean match = false; // initialize card match to false
void setup() { Serial.begin(9600);// connect to the serial port mySerial.begin(9600); Serial.println("Bring an RFID tag near the reader..."); }
void loop () { byte i = 0; byte val = 0; byte master[6]; byte checksum = 0; byte bytesread = 0; byte tempbyte = 0;
if(mySerial.available() > 0) { if((val = mySerial.read()) == 2) { // check for header bytesread = 0; while (bytesread < 12) { // read 10 digit master + 2 digit checksum if( mySerial.available() > 0) { val = mySerial.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 master: if (bytesread & 1 == 1) { // make some space for this hex-digit by // shifting the previous hex-digit with 4 bits to the left: master[bytesread >> 1] = (val | (tempbyte << 4));
if (bytesread >> 1 != 5) { // If we're at the checksum byte, checksum ^= master[bytesread >> 1]; // Calculate the checksum... (XOR) }; } else { tempbyte = val; // Store the first hex digit first... };
bytesread++; // ready to read next digit } } //do something else perhaps wait for other data. if (bytesread == 12) { // if 12 digit read is complete Serial.println(); Serial.print("5-byte master: "); for (i=0; i<5; i++) { if (master[i] < 16) Serial.print("0"); byte master1 = master[i]; Serial.print(master[i], HEX); //Prints the Tag of the Card read Serial.print(" "); } for (int n=0; n<ARR_LEN; n++){ //Checks each ID Tag in the Array if(memcmp(master, target_tag[n], TAG_LEN) == 0 ) //Compares two bytes of TAG_LEN, if they are a match, the argument will be 0, thus 0 == 0 { Serial.println(); Serial.println("This Card is a Match!"); Serial.println(); } else { Serial.println("This Card is NOT a Match!"); } } } bytesread = 0; Serial.flush(); } } }
};
Hope this helps in deciphering the two-time repetition of the "This Card is NOT a Match!" statement.
|
|
|
|
|
Logged
|
Working on a Smart Home Management System. Visit my blog: http://tae09.blogspot.com/ to find out more, and to keep track with the project.
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 313
Posts: 35502
Seattle, WA USA
|
 |
« Reply #10 on: September 05, 2012, 01:34:52 pm » |
Hope this helps in deciphering the two-time repetition of the "This Card is NOT a Match!" statement. No, not really. Putting each { on a new line, and using Tools + Auto Format would help. So would including the value of n in the output: Serial.print("Card "); Serial.print(n); Serial.println(" is NOT a Match!"); This way, if you see: Card 0 is NOT a Match! Card 1 is NOT a Match! then we know one thing. If you see Card 0 is NOT a Match! Card 0 is NOT a Match! or Card 1 is NOT a Match! Card 1 is NOT a Match! then we know something else.
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 89
Posts: 6377
-
|
 |
« Reply #11 on: September 05, 2012, 01:52:41 pm » |
If it validates, it outputs once. If it doesnt validate, it outputs twice- for each tag it reads in.
From code inspection, I predict slightly different behaviour. What it should do is compare the received RFID against each of your two hardcoded values in turn. For each comparison it prints either "This Card is a Match!" or "This Card is NOT a Match!". If you want to clean this up I suggest you extract the comparison into a function that returns something to indicate whether the value is a match. If you want to know which one it matched, you could return the 0-based index into the target_tag array (and a negative value to indicate no match). Or if you don't care which one it matched, just return a boolean. Then, based on the return value print out the appropriate trace message. By the way, that's far from the worst code I've seen but in order to convince myself the logic was sound I reformatted it to put each { and } on a separate line with matching pairs indented by the same amount; I suggest you adopt that code style. I also suggest that you get into the habit of putting { and } after any if/else statement. Sure, it might work without it now when you only have one statement, but you've no idea how many times I've seen people tack an extra statement on the end - or inadvertently use a macro that expanded to more than one statement - and introduce a subtle bug. Use { and } to make the control structure as clear and robust as possible.
|
|
|
|
« Last Edit: September 05, 2012, 01:56:46 pm by PeterH »
|
Logged
|
|
|
|
|
Texas, USA
Offline
Jr. Member
Karma: 0
Posts: 53
Arduino rocks!!
|
 |
« Reply #12 on: September 05, 2012, 04:04:21 pm » |
By the way, that's far from the worst code I've seen but in order to convince myself the logic was sound I reformatted it to put each { and } on a separate line with matching pairs indented by the same amount; I suggest you adopt that code style. I also suggest that you get into the habit of putting { and } after any if/else statement. Sure, it might work without it now when you only have one statement, but you've no idea how many times I've seen people tack an extra statement on the end - or inadvertently use a macro that expanded to more than one statement - and introduce a subtle bug. Use { and } to make the control structure as clear and robust as possible.
Well this is practically the example given on the Arduino website for use with the ID-12. I just manipulated it for my purpose. Putting each { on a new line, and using Tools + Auto Format would help. So would including the value of n in the output: Serial.print("Card "); Serial.print(n); Serial.println(" is NOT a Match!"); I am using Auto-format. I'll implement the Card (n) into the code and see what happens.
|
|
|
|
|
Logged
|
Working on a Smart Home Management System. Visit my blog: http://tae09.blogspot.com/ to find out more, and to keep track with the project.
|
|
|
|
UK
Offline
Tesla Member
Karma: 89
Posts: 6377
-
|
 |
« Reply #13 on: September 05, 2012, 04:43:19 pm » |
Well this is practically the example given on the Arduino website for use with the ID-12. I just manipulated it for my purpose.
Well, I'm not saying that the people who coded that example are wrong, but they are not using the coding style which, in my opinion, is the one which makes the control structures in your code clearest. I recommend that you follow the style I outlined, even though you will routinely encounter code that follows other styles.
|
|
|
|
|
Logged
|
|
|
|
|
|