Read RFID Tags with ID-20

I'm trying to read some RFID tags using Innovations ID-20 reader. I've created this code:

#include <SoftwareSerial.h>
SoftwareSerial id20(2,3); // virtual serial port

char tag[13];

void setup() 
{
 Serial.begin(9600);
 id20.begin(9600);
}

void loop () {
  while (id20.available()<13){ //wait until all the 12 bytes are buffered
  }
  for (int i=0; i<13; ){
      tag[i]=id20.read(); //write the bytes into the array
      i++;
    }
  
  Serial.println(tag); //print the array
   
  for (int i=0; i<13; i++){ //clear the array
    tag[i]=0;  
  }
  
}

The result should be 010D429BBF6A, but, the first time I put the card over the reader I get:

010D429BBF6A 010D429BBF6A

The second time

010D429BB 010D429BBF6A
010D429BB

The third time

F6A
010D42 010D429BBF6A
010D429BBF6A
010D42

And so on.
What did I get wrong?
I have Arduino UNO and I use IDE 1.0.5
Thanks in advance.

I'm sorry for the double post...

Does the data from the RFID reader include a null terminator? If not, you should add one before you print. Be sure to make the buffer long enough to store the 13 characters AND the null terminator.

I've tried to modify the code as you described. The result is better, but not at all.

#include <SoftwareSerial.h>
SoftwareSerial id20(2,3); // virtual serial port

char tag[13];

void setup() 
{
 Serial.begin(9600);
 id20.begin(9600);
}

void loop () {
  while (id20.available()<13){ //wait until all the 12 bytes are buffered
  }
  for (int i=0; i<14; ){
    if(i==13) { //inserts a null character
      tag[12]=00;
      i++;
    }
    else if(i!=0||i!=13){
      tag[i-1]=id20.read(); //write the bytes into the array
      i++;
    }
    else if (i==0) i++; //avoids the first bit, which is not data
  }
    
  Serial.println(tag); //print the array
   
  for (int i=0; i<13; i++){ //clear the array
    tag[i]=0;  
  }
  
}

1

010D429BFF2A

2

õò

3

Ì?­?°à0

Psst:

Be sure to make the buffer long enough to store the 13 characters AND the null terminator.

You forgot something.

else if(i!=0||i!=13){
If i is not 0 or it is not 13? What are you trying to do?

Modifying the code to add the NULL was trivial. Make the array size 14, and add

tag[13] = '\0'; // Add trailing NULL

after the for loop to read 13 values.

[code]With this modified code I don't get any strange characters, but it happens a periodic behaviour which I cannot explain to myself.
[code]#include <SoftwareSerial.h>
SoftwareSerial id20(2,3); // virtual serial port

void setup() 
{
 Serial.begin(9600);
 id20.begin(9600);
}

void loop () {
  char tag[14];
  while (id20.available()<14){ //wait until all the 12 bytes are buffered
  }
  for (int i=0; i<14; ){
    if(i==13) { //inserts a null character
      tag[13]='\0';
      i++;
    }
    else if (i<13) {
      tag[i]=id20.read();
      i++;
    }
  }
    Serial.println(tag); //print the array  
}

[/code]1 -> No reading
2 -> 010D429BBF6A (which is the exact code)
3 ->
010D429BB (one blank character, then starts another line, partial code, two blank characters)
4 -> F6A
010D42
5 -> 9BBF6A
010
6 -> D429BBF6A
(Empty line)
010D429BBF6A (again the exact code after 4 cicles)[/code]
Then I get the exact code again after 9 cicles and so on, alternating between 4 and 9 cicles.

  while (id20.available()<14){ //wait until all the 12 bytes are buffered

Fourteen does not equal twelve.

You were waiting for 13 characters.

  while (id20.available()<13){ //wait until all the 12 bytes are buffered

No more data is sent. Why are you now waiting for 14?

The result is the same, but now it reads the code from the first cycle.
I used 14 because I was trying different numeric values to make it work and since the result was identical I forgot to rewrite the correct value.
I don't have any ideas.

  for (int i=0; i<14; ){
    if(i==13) { //inserts a null character
      tag[13]='\0';
      i++;
    }
    else if (i<13) {
      tag[i]=id20.read();
      i++;
    }
  }

Way too damned complicated.

  for (int i=0; i<13; i++)
  {
      tag[i]=id20.read();
  }
  tag[13] = '\0';

Much simpler!

Thanks for the advice :wink:
If I try to read another card during the cycles while I'm getting the errors, I get part of the final code of the previous card and on the second line the first bytes of the card actually being read.

F2A (end of the previous card code)
010D4 (start of the card being read now, which is the same as the other because they were sold together)

Don't I have to clean the buffer each time after Serial.println?

Don't I have to clean the buffer each time after Serial.println?

Did you get it dirty?

All that is needed to "clean" the array is:

tag[0]='\0';

I meant maybe I should clean the Serial buffer, not the array, even because I did clean the array and it didn't work.

I meant maybe I should clean the Serial buffer, not the array, even because I did clean the array and it didn't work.

There is not a good way to "clean" the serial buffer. You need to read all the data, to determine when a new tag is presented.

That you are having issues tells me that the RFID reader is sending more data than you think it is.

It's what I supposed, too. Now I've tried this and it works fine. So I'll study its behaviour to understand how to correct my own code.
I'll tell you what I find out. Thanks again :slight_smile:

Usually the RFID reader will include one or more terminator characters after the ID. Typically these will be CR (13) and LF (10). What I would do is read and buffer characters until I read a 10 or 13. If the number of buffered characters matches the length of an ID, put in a null and process the ID. After that, reset the buffer (set the counter back to 0). Be sure to also reset the buffer if you get too many characters for an ID.

johnwasser:
Usually the RFID reader will include one or more terminator characters after the ID. Typically these will be CR (13) and LF (10).

Thanks to your advice I finally get a code which printed only 12 character tags, but there was one final error that I solved with this final code:

#include <SoftwareSerial.h>
SoftwareSerial id20(3,2); // virtual serial port

void setup() 
{
 Serial.begin(9600);
 id20.begin(9600);
}

void loop () {
  char tag[13];
  boolean mem=false;  
  while (id20.available()<14){ //wait until all the 12 bytes are buffered
  }
  if(id20.read()==2){ //checks for the header
    for (int i=0; i<14; ){
      if (i<13) {
        tag[i]=id20.read();
        i++;
      }
      else {
        tag[13]='\0';
        i++;
        mem=true;
      }
    }
  }
  if (mem==true) Serial.println(tag); 
}
  char tag[13];
        tag[13]='\0';

Very bad form to write into the 14th element of a 13 element array.

johnwasser:
Very bad form to write into the 14th element of a 13 element array.

How would you put in a null?

How would you put in a null?

Just like you are doing it, but in the last element of the array ([12]), not beyond the end of the array.