Go Down

Topic: help with comparing RFID tags (Read 863 times) previous topic - next topic

jarrod_99

HI,
I am building a small RFID reader  (to be used in airsoft/paintball)
the object of this reader is to use tags to collect points
i have got the code working to a point, however i would like to compare the current tag been scanned with the last one scanned (trying to prevent multiple reads of the same tag )

however i am having issues comparing the two tags

the code is based on the trionix lessons from the website
hardware is adruino UNO and rdn630 RFID reader

would be very grateful if some one could point out where i am going wrong, please bear in mind im new to programming

Code: [Select]

#include <SoftwareSerial.h>
int data1;
long old_tag = 0;
long new_tag = 0;
int dup = 0;
const int BUFFER_SIZE = 14; // RFID DATA FRAME FORMAT: 1byte head (value: 2), 10byte data (2byte version + 8byte tag), 2byte checksum, 1byte tail (value: 3)
const int DATA_SIZE = 10; // 10byte data (2byte version + 8byte tag)
const int DATA_VERSION_SIZE = 2; // 2byte version (actual meaning of these two bytes may vary)
const int DATA_TAG_SIZE = 8; // 8byte tag
const int CHECKSUM_SIZE = 2; // 2byte checksum
SoftwareSerial ssrfid = SoftwareSerial(6,8);
uint8_t buffer[BUFFER_SIZE]; // used to store an incoming data frame
int buffer_index = 0;
void setup() {
 Serial.begin(9600);
 ssrfid.begin(9600);
 ssrfid.listen();

 Serial.println("INIT DONE");
}
void loop() {
  if (ssrfid.available() > 0){
    bool call_extract_tag = false;
    
    int ssvalue = ssrfid.read(); // read
    if (ssvalue == -1) { // no data was read
      return;
    }
    if (ssvalue == 2) { // RDM630/RDM6300 found a tag => tag incoming
      buffer_index = 0;
    } else if (ssvalue == 3) { // tag has been fully transmitted      
      call_extract_tag = true; // extract tag at the end of the function call
    }
    if (buffer_index >= BUFFER_SIZE) { // checking for a buffer overflow (It's very unlikely that an buffer overflow comes up!)
      Serial.println("Error: Buffer overflow detected!");
      return;
    }
    
    buffer[buffer_index++] = ssvalue; // everything is alright => copy current value to buffer
    if (call_extract_tag == true) {
      if (buffer_index == BUFFER_SIZE) {
        unsigned tag = extract_tag();
      } else { // something is wrong... start again looking for preamble (value: 2)
        buffer_index = 0;
        return;
      }
    }    
  }    
}
unsigned extract_tag() {
    uint8_t msg_head = buffer[0];
    uint8_t *msg_data = buffer + 1; // 10 byte => data contains 2byte version + 8byte tag
    uint8_t *msg_data_version = msg_data;
    uint8_t *msg_data_tag = msg_data + 2;
    uint8_t *msg_checksum = buffer + 11; // 2 byte
    uint8_t msg_tail = buffer[13];
    unsigned long now = millis ();
    delay(500);
    flush();
    


    // this is the area of code i am having issues with
    //
    //
    //
    //
    //
    long tag = hexstr_to_value(msg_data_tag, DATA_TAG_SIZE);
    Serial.print("Extracted Tag: ");
    Serial.println(tag);
    Serial.println(old_tag);
    Serial.println(new_tag);
    Serial.print("dup ;");
    Serial.println(dup);
    if (dup != 1) {
      old_tag = tag;
      dup++;
    } else {
      new_tag = tag;
    return;
    }
    if (old_tag == new_tag){
      Serial.println("duplicate tag!!!");
    }else  {
      Serial.println("good tag");
      old_tag = new_tag;
      dup = 0;
    }
    
    delay(5000);
    flush();
    int ssvalue = -1;
    return tag;
}
long hexstr_to_value(char *str, unsigned int length) { // converts a hexadecimal value (encoded as ASCII string) to a numeric value
  char* copy = malloc((sizeof(char) * length) + 1);
  memcpy(copy, str, sizeof(char) * length);
  copy[length] = '\0';
  // the variable "copy" is a copy of the parameter "str". "copy" has an additional '\0' element to make sure that "str" is null-terminated.
  long value = strtol(copy, NULL, 16);  // strtol converts a null-terminated string to a long value
  free(copy); // clean up
  return value;
}

void flush() { // prevents multiple reads
  for (int z = 0 ; z < 56 ; z++) // read the rest of the tag
    {
      data1 = ssrfid.read();
    }
}

ieee488


jarrod_99

AH...yes ieee488
a desription of my problem would help..wouldnt it

ok, program is set up to read a tag then place a copy of that tags number in old_tag
2nd tag gets scanned and placed into new_tag
both are then compared to see it they match, if they do then "duplicate is displayed", if they dont "good tag" displayed

i also print the values of old_tag and new_tag to serial monitor along with the tag scanned so i can see whats getting read/stored etc

but it does not seem to store the value of the tag in old_tag or new_tag for comparison

PaulS

Code: [Select]
        unsigned tag = extract_tag();
That variable goes out of scope immediately after this line.

Code: [Select]
    return;
You lied. You promised to return something.

Why are you then storing this (nonexistent) unsigned int in a signed long?

Code: [Select]
    int ssvalue = -1;
Another useless variable that immediately goes out of scope.

Code: [Select]
  memcpy(copy, str, sizeof(char) * length);
  copy[length] = '\0';
  // the variable "copy" is a copy of the parameter "str". "copy" has an additional '\0' element to make sure that "str" is null-terminated.
  long value = strtol(copy, NULL, 16);  // strtol converts a null-terminated string to a long value
  free(copy); // clean up

This was useless. strtol() does not alter the input array, so there is NO reason to make a copy of it.

Even if there were, strdup() is a lot simpler to use.

jarrod_99

ok last reply hasnt really helped, i did say that the code was based on some on trionix, and to be honest i dont understand what is meant in the last part of the comment, the only part of the code i have written is as follows, i am very new to this and a lot of the comment made no sense to me , no disrespect to paulS
Code: [Select]

    Serial.print("Extracted Tag: ");
    Serial.println(tag);
    Serial.println(old_tag);
    Serial.println(new_tag);
    Serial.print("dup ;");
    Serial.println(dup);
    if (dup != 1) {
      old_tag = tag;
      dup++;
    } else {
      new_tag = tag;
    return;
    }
    if (old_tag == new_tag){
      Serial.println("duplicate tag!!!");
    }else  {
      Serial.println("good tag");
      old_tag = new_tag;
      dup = 0;
    }
   
    delay(5000);
    flush();
    int ssvalue = -1;
    return tag;




i think by assing a value of -1 to ssvalue im trying to prevent muliple reads of the tag, as sometimes when you remove the tag it still has data in the buffer
i also wrote

Code: [Select]

void flush() { // prevents multiple reads
  for (int z = 0 ; z < 56 ; z++) // read the rest of the tag
    {
      data1 = ssrfid.read();
    }
}


this reads any remaining data and basically discards it, which seams to solve the multiple read once tag has been removed

jarrod_99

well i managed to figure it out, cut the code down and got rid of stuff that i thought would work but obviously didnt, now im up and running.....on to the next part of what i want to do with the project

westgate

#6
Nov 30, 2018, 01:17 pm Last Edit: Nov 30, 2018, 01:22 pm by westgate
Code: [Select]
  memcpy(copy, str, sizeof(char) * length);
  copy[length] = '\0';
  // the variable "copy" is a copy of the parameter "str". "copy" has an additional '\0' element to make sure that "str" is null-terminated.
  long value = strtol(copy, NULL, 16);  // strtol converts a null-terminated string to a long value
  free(copy); // clean up

This was useless. strtol() does not alter the input array, so there is NO reason to make a copy of it.
Even if there were, strdup() is a lot simpler to use.
I think the point to note here is that "copy" is not simply a duplicate of "str". Rather, it is a (null-terminated) copy of only the first *length* characters of "str". Given the purpose of the function and the code comments concerning the structure of the RFID tag, I believe only 8 bytes are required, following the 1byte header and 2byte version, so the arguments passed to it should be
Code: [Select]
hexstr_to_value(buffer+3, 8 );

Go Up