Reading certain RFID cards returns the wrong value

I have a lot of RFID cards that I'm using, but around 1/4 of them does not work with the code I have.

First off, I have an USB RFID card reader that I use to read and program the RFID cards, plus store their hexadecimal values to our SQL database.

After that I have an Arduino machine with a RFID reader(not the same reader as the USB one) that reads the RFID cards hexadecimal value and then sends this with a HTTP GET to our server were it'll validate in our SQL database. Based on this it returns success or false.

A majority of the cards works great but some does not.

Here is an example of a card that works, it has the RFID '08BEF8CA' which also is the value we have stored in the database, the Arduino device however reads the hexadecimal as 'CAF8BE08'. But this is the same hexadecimal just with a different endian, we fix this server-side(after the HTTP GET) and it works as intended.

Another card has the RFID '08BDDCAA', but the Arduino device returns 'AA00DCBD' for this card. Like the other card, it has a different endian. But for some reason the 08 has disappeared and is now 00, thus breaking the HTTP GET since we're not expecting that value.

Here is some code for the Arduino device

#include <Ethernet.h>
#include <SPI.h>
#include <SoftwareSerial.h> 
#include <SimpleTimer.h>

#define standby_pin A0//Blue LED
#define grant_pin A1//Green LED
#define grantbuzzer_pin A4//Buzzer
#define deny_pin A3//Red LED
#define denybuzzer_pin A4//Buzzer

// the timer object
SimpleTimer HBtimer;

char tag[10];
int tagindex=0;

SoftwareSerial mySerial(2, 3); //pin3 Rx, pin2 Tx 
byte readCard[]={0xAA,0xBB,0x02,0x20,0x22};
int cardPresent=0;
int cardBytesRead;
int readComplete;

int CMD[64];
int comlen =0;
int out_flag =0;
boolean isReplyRead=0;
String strAuthResp;
String strTagID;

int aread=0,readCardBytes=0,readIndex=0,index=0;
char value[250];
int HBTimeout=60000;	

int isConnected = 0;

void setup()
{
        pinMode(standby_pin,OUTPUT);
        pinMode(grant_pin,OUTPUT);
        pinMode(deny_pin,OUTPUT);
        pinMode(grantbuzzer_pin,OUTPUT);
        pinMode(denybuzzer_pin,OUTPUT);
        pinMode(5,INPUT);
	digitalWrite(standby_pin,LOW);
        digitalWrite(grant_pin,HIGH);
        digitalWrite(deny_pin,HIGH);
	Serial.begin(19200);
	mySerial.begin(19200);
        cardBytesRead=0;
        readComplete=0;
	delay(50);
	mySerial.listen();
	delay(10);
} 

void loop()
{
    HBtimer.run();
    readComplete=0;
    cardPresent=digitalRead(5);
    cardPresent=!cardPresent;
    if((cardPresent)&&(!readComplete)){
    readCardF();
    delay(50);
  
    }//End IF
}//End Loop

void readCardF(){
  
  mySerial.write(readCard, sizeof(readCard));
  while(mySerial.available()&&readComplete<1){
    byte C = mySerial.read();
    
    
    if (C<16) Serial.print("0");
    Serial.print(C,HEX);
    
    cardBytesRead++;
      if ((cardBytesRead>4)&&(cardBytesRead<9)){
        byte hinibble = (C >> 4) & 0x0f;
        byte lonibble = C & 0x0f;
        
        tag[tagindex++] = bintohexascii(hinibble);
        tag[tagindex++] = bintohexascii(lonibble);
      } //End If
      

  if (cardBytesRead==9) {
          tagindex=0;
          cardBytesRead=0;
          readComplete=1;
           Serial.println("");
	   Serial.println("RFID tag value= ");
	   Serial.println(tag);
           Serial.println("");
           strTagID=tag;
	   isReplyRead=0;

	   if(strTagID.length()==8){
              //Success
              //Call our HTTP GET function
              
              //For testing purposes we call the resetFunc here so we can re-scan to keep testing
              delay(100);
              resetFunc();
            }
            else
            {
                Serial.println("Invalid Length of RFID Card");
                delay(100);
                resetFunc();
            }
            return;
	}//End If carybytesread==9
  }//End While
} //End Function

char bintohexascii(byte x)
{
	char hex[16] = {
		'0', '1', '2', '3', '4', '5', '6', '7',
		'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
	};
	return hex[x & 0x0f];
}
void resetFunc() // Restarts program from beginning but does not reset the peripherals and registers
{
asm volatile ("  jmp 0");  
}

I have an older Arduino device that can read these cards fine, and it uses pretty much the exact same functions to create the RFID, only real difference is that it is a different device and has a different frequence(or what the baud thing is?)

Thanks in before hand.

I'm not going to try to paste that code together. Post ALL of your code as ONE file (as attachment if necessary).

PaulS:
I'm not going to try to paste that code together. Post ALL of your code as ONE file (as attachment if necessary).

Are you happy

I don't like the use of resetFunc() (what problem is that trying to solve?) and you seem to be using the problematic String class where a call to strlen() would achieve the same effect with less cost and risk, but I don't see anything there that would definitely cause it to fail.

Do you have examples of RFID values that return the wrong result, and what the wrong result is? Is the 'wrong' result consistent for a given RFID?

PeterH:
I don't like the use of resetFunc() (what problem is that trying to solve?) and you seem to be using the problematic String class where a call to strlen() would achieve the same effect with less cost and risk, but I don't see anything there that would definitely cause it to fail.

Do you have examples of RFID values that return the wrong result, and what the wrong result is? Is the 'wrong' result consistent for a given RFID?

I mentioned it here

Another card has the RFID '08BDDCAA', but the Arduino device returns 'AA00DCBD' for this card. Like the other card, it has a different endian. But for some reason the 08 has disappeared and is now 00, thus breaking the HTTP GET since we're not expecting that value.

Here is an update :

I added

if (C<16) Serial.print("0");
Serial.print(C,HEX);

Before the

if ((cardBytesRead>4)&&(cardBytesRead<9))

Inside the readCardF() function to see the full RFID before we split it with the if statement.

Examples :
Working card : has the hexadecimal value of CAF8BE08(08BEF8CA in the database) with what I just added we can see that the whole HEX of the whole RFID is AABB0620CAF8BE08A2. As you can see we have our value in there(which is the value we grab with our if statement)
Non working card : has the hexadecimal value of AADCBD08(08BDDCAA in the database) the full HEX of the whole RFID is AABB0620AA00DCBD08. As you can see, for this card we have the 00 value inside there rather than the 08 value(which is outside the if statement now)

Why does the 00 appear inside there rather than the 08? Does this explain anything?

And no. Obviously I can not change the if statement. if I change it from (4 to 9) to (4 to 10) it becomes too large, and the 00 is still in there. If I change it from (4 to 9) to (5 to 10) we'll lose our AA at the start and we'll still have the 00 inside the hexadecimal.

Thanks for your help

	EthernetClient client;

What is this for, in setup()? Creating an instance of the EthernetClient class that immediately goes out of scope is pointless.

  while(mySerial.available()&&readComplete<1){

readComplete should be a boolean that is either true or false. mySerial.available() does NOT return a boolean, and should not be treated as if it did.

	   Serial.println(tag);

tag is NOT a NULL terminated array of chars, and should not be passed to functions that expect NULL terminated arrays of chars.

PaulS:

	EthernetClient client;

What is this for, in setup()? Creating an instance of the EthernetClient class that immediately goes out of scope is pointless.

It is being used for the HTTP GET.

PaulS:

  while(mySerial.available()&&readComplete<1){

readComplete should be a boolean that is either true or false. mySerial.available() does NOT return a boolean, and should not be treated as if it did.

It works.

PaulS:

	   Serial.println(tag);

tag is NOT a NULL terminated array of chars, and should not be passed to functions that expect NULL terminated arrays of chars.

It also works and is just being used to track the data.

I updated the code a bit in the original post.

This code is fully functionable and the only issue is that I'm not getting the correct value from certain cards as explained in the earlier posts. The rest of the code is fine.

The rest of the code is fine.

No, it isn't. The rest of the code has problems that haven't YET caused you problems that you know of. Feel free to ignore them as you search for the problem yourself. Or, fix them if you want help. Your choice.

PaulS:

The rest of the code is fine.

No, it isn't. The rest of the code has problems that haven't YET caused you problems that you know of. Feel free to ignore them as you search for the problem yourself. Or, fix them if you want help. Your choice.

So you want me to change an integer to a boolean otherwise you will just ignore me, really?
But hey, lets say I have fixed the issues locally. How about you actually read the thread and focus on the main issue here?

I know you're helping on your own free will and aren't forced to, but you're acting really childish and keeps going off-topic.