I am using a MFRC 522 Reader to get RFID tag which is like 8C62B0F8.
Based on the read value I need to pull out a matching record from a data base stored on SD card.
I am unable to figure out how to do the matching. The function below shows my problem. Where am I going wrong ??
// FUNCTION TO SEARCH DATABASE in SD Card TO LOCATE THE RECORD MATCHING SCANNED RFID.
boolean findMatchRec() {
String readString;
String recRFID;
boolean matchFound = false;
byte actRFID[4] = {0x12, 0x34, 0x56, 0x78}; // Dummy tag to check code.
File dataFile = SD.open("GRPLAN.CSV", FILE_READ); // Open the file
if (dataFile) {
while ( dataFile.available()) {
char letter = dataFile.read();
if ( letter == '>' ) { // Read the first record till End Marker
nextRecPos = dataFile.position(); // Save position for next record search to global variable
recRFID = readString.substring (7, 15); // Get the RFID tag value for chosen record..
}
else {
readString += letter; // Build the full record string..
}
}
}
dataFile.close();
Serial.println( recRFID); // Prints "12345678"
String myString = (char*)actRFID; // Convert the byte array to string
Serial.println ( myString); // Prints garbage like 4Vx‚A
if ( recRFID == myString ) Serial.println( "Success!!");
}
You did not describe the format of your 'records' enough to give more constructive hints.
I was expecting to be pulled up for using the String !! Anyway I am using a Mega 2560 and my code is just 10% of the flash and the SRAM is about 2k size. So right now its kind of a quick proto that I am aiming at as many things are still fluid in the project.
Anyway I attach a sample screen shot of the Data Base file and the RFID is the Second column after serial number..
The findMatchRec() function does not compare anything, so how do you expect it to find something?
You set recRFID to the id of the first record, regardless which record you are reading currently.
That is because you keep the whole file (without the '>'s) in the variable.
Yes as it is it will now read only the first record. Actually if you look at the function there is a global variable where I store the starting point of the next record (nextRecPos ).
Once I am successful in this comparison on the first record I will then modify the function to take the position of the next record as an argument and search one after another record from another function.
If you look , after I close the dataFile I do try to check if the tag values match.
My current issue is to bring both tag values - as read by the reader and as extracted from the SD card to a common base to carry out a comparison.
Hmmm... moved away from String object and tried this with string array. Changed the function suitably. Still no luck. Its always "Success" even if the scanned tag and record tag do not match. So what is wrong now ?
// FUNCTION TO FIND IF A RECORD ON SD CARD MATCHES WITH THE RFID TAG
boolean chkTagMatch() {
char rowData[100];
char recRFID[9];
byte actRFID[4] = {0x12, 0x35, 0x56, 0x78}; // Dummy tag to check code - intentionally a wrong one....
File dataFile = SD.open("GRPLAN.CSV", FILE_READ); // Open the file
if (dataFile) {
while ( dataFile.available()) {
char letter = dataFile.read();
for ( int i = 0; i < 94; i++ ) {
rowData[i] = letter;
if ( i > 5 && i < 13) recRFID[i] = letter ; // Save the RFID value from the SD card..
}
nexRecPos = dataFile.position(); // Save the position to continue the search if required
}
}
dataFile.close();
if (strcmp((char*)actRFID, recRFID)) { // Compare the RFID tag with the RFID in the current row..
Serial.println( "Success!!");
return 1;
}
else {
Serial.println("Failure !");
return 0;
}
}
char letter = dataFile.read();
for ( int i = 0; i < 94; i++ ) {
rowData[i] = letter;
if ( i > 5 && i < 13) recRFID[i] = letter ; // Save the RFID value from the SD card..
}
Read one letter. Store it in 94 places in the rowData array. That makes no sense to me.
Store the same letter in recRFID, in positions 5 thru 13, even though the valid range of indices is 0 to 8. That makes no sense to me.
if (strcmp((char*)actRFID, recRFID)) { // Compare the RFID tag with the RFID in the current row..
Serial.println( "Success!!");
strcmp() returns 0 if the records match. You are printing Success!! if they do not match. That makes no sense to me.
I have now corrected all the errors pointed out by Paul but still not reached the solution. I am missing something big time.
The problem boils down to this :
I have a byte array in the form { 0x12345678} from the RFID reader.
I have the matching value to be picked up from the SD card data base.
I can read the data base and store the RFID value in a char array or a String obj.
And finally I need to bring the byte array to either one of the above data types to compare.
Tried various methods and ended up getting various error messages from the compiler.
I am sure this is a very common requirement to read somethin from the SD card and compare with a byte array. How does one convert the different data types to a single type and compare ? Thanks for any help.
OK so here is the code . Pointed out errors removed but still not doing what is expected. I think the real problem is the Byte array to Char array conversion . Why is the conversion failing ??
// FUNCTION TO CHECK IF THE CHOSEN RFID IN DATABASE ON SD CARD MATCHES THE SCANNED RFID.
boolean chkTagMatch() {
char recRFID[9];
int result = -1;
byte actRFID[4] = {0x12, 0x34, 0x56, 0x78}; // Dummy tag to check code.
char letter ;
File dataFile = SD.open("GRPLAN.CSV", FILE_READ); // Open the file
if (dataFile) {
dataFile.seek(7); // Move to the position of start of RFID reference
for ( int i = 0; i < 8; i++ ) { // Read the eight positions of RFID reference
letter = dataFile.read();
recRFID[i] = letter;
}
}
dataFile.close();
recRFID[8] = '\0'; // Null Terminate the string
Serial.println( recRFID); // Prints "12345678"
Serial.println ((char*)actRFID); // Prints garbage. This byte array to char conversion is the problem... :-(
result = strcmp (recRFID, (char*)actRFID);
if (result == 0 ) Serial.println( "SUCCESS!!");
else Serial.println ( "FAILURE");
}
Success at last !! Thanks Paul... your remark on the number of bytes was bugging me from the beginning and it took some time to understand how Serial print works and then decided to do it from scratch.
I am not sure if the code below is elegant ...compact or professional ... but it seems to work and that is a relief. Any comments to improve welcome !! I have also attached the Serial Capture for checking. Seems OK . To me
// FUNCTION TO CHECK IF THE CHOSEN RFID IN DATABASE ON SD CARD MATCHES THE SCANNED RFID.
boolean chkTagMatch() {
char rec_char_RFID[9];
char act_char_RFID[9];
int result = -1;
byte actRFID[4] = {0x12, 0x34, 0x56, 0x78}; // Dummy tag to check code.
byte * bytePtr = actRFID;
char letter ;
File dataFile = SD.open("GRPLAN.CSV", FILE_READ); // Open the file
if (dataFile) {
dataFile.seek(7); // Move to the position of start of RFID reference
for ( int i = 0; i < 8; i++ ) { // Read the eight positions of RFID reference
letter = dataFile.read();
rec_char_RFID[i] = letter;
Serial.println( letter, BIN);
}
}
dataFile.close();
rec_char_RFID[8] = '\0'; // Null Terminate the string
Serial.println( rec_char_RFID); // Prints "12345678
act_char_RFID[8] = '\0';
RFID_To_Char (bytePtr, act_char_RFID, 4);
Serial.println( act_char_RFID); // Prints "12345678
result = strcmp (rec_char_RFID, act_char_RFID);
if (result == 0 ) {
Serial.println( "SUCCESS!!");
}
else {
Serial.println ( "FAILURE");
}
}
// &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
void RFID_To_Char (byte* byteArray, char* charArray, int ByteArraySize) {
int byteCount ;
int charCount ;
for ( byteCount = 0; byteCount < ByteArraySize; byteCount++ ) {
charArray[charCount] = (byteArray[byteCount] >> (4)) | 0x30 ;
Serial.println(charArray[charCount], BIN);
charArray[charCount + 1] = (byteArray[byteCount] & 0x0f ) | 0x30;
Serial.println(charArray[charCount + 1], BIN);
charCount += 2;
}
}