Updating a v0.23 RFID sketch to v1.0

Hi everyone,

I'm trying to make sure my RFID module is running ok. I think it is as I used Arduino v0.23 to run this sketch from the Sparkfun. It's the example code for the product I bought:

/*
  RFID Eval 13.56MHz Shield example sketch v10
  
  Aaron Weiss, aaron at sparkfun dot com
  OSHW license: http://freedomdefined.org/OSHW
  
  works with 13.56MHz MiFare 1k tags

  Based on hardware v13:
  D7 -> RFID RX
  D8 -> RFID TX
  D9 -> XBee TX
  D10 -> XBee RX
  
  Note: RFID Reset attached to D13 (aka status LED)
  
  Note: be sure include the NewSoftSerial lib, http://arduiniana.org/libraries/newsoftserial/
  
  Usage: Sketch prints 'Start' and waits for a tag. When a tag is in range, the shield reads the tag,
  blinks the 'Found' LED and prints the serial number of the tag to the serial port
  and the XBee port. 

*/
#include <NewSoftSerial.h>

NewSoftSerial rfid(7, 8);
NewSoftSerial xbee(10, 9);

//Prototypes
void check_for_notag(void);
void halt(void);
void parse(void);
void print_serial(void);
void read_serial(void);
void seek(void);
void set_flag(void);

//Global var
int flag = 0;
int Str1[11];

//INIT
void setup()  
{
  Serial.begin(9600);
  Serial.println("Start");
  
  // set the data rate for the NewSoftSerial ports
  xbee.begin(9600);
  rfid.begin(19200);
  delay(10);
  halt();
}

//MAIN
void loop()                 
{
  read_serial();
}

void check_for_notag()
{
  seek();
  delay(10);
  parse();
  set_flag();
  
  if(flag = 1){
    seek();
    delay(10);
    parse();
  }
}

void halt()
{
 //Halt tag
  rfid.print(255, BYTE);
  rfid.print(0, BYTE);
  rfid.print(1, BYTE);
  rfid.print(147, BYTE);
  rfid.print(148, BYTE);
}

void parse()
{
  while(rfid.available()){
    if(rfid.read() == 255){
      for(int i=1;i<11;i++){
        Str1[i]= rfid.read();
      }
    }
  }
}

void print_serial()
{
  if(flag == 1){
    //print to serial port
    Serial.print(Str1[5], HEX);
    Serial.print(Str1[6], HEX);
    Serial.print(Str1[7], HEX);
    Serial.print(Str1[8], HEX);
    Serial.println();
    //print to XBee module
    xbee.print(Str1[5], HEX);
    xbee.print(Str1[6], HEX);
    xbee.print(Str1[7], HEX);
    xbee.print(Str1[8], HEX);
    xbee.println();
    delay(100);
    //check_for_notag();
  }
}

void read_serial()
{
  seek();
  delay(10);
  parse();
  set_flag();
  print_serial();
  delay(100);
}

void seek()
{
  //search for RFID tag
  rfid.print(255, BYTE);
  rfid.print(0, BYTE);
  rfid.print(1, BYTE);
  rfid.print(130, BYTE);
  rfid.print(131, BYTE); 
  delay(10);
}

void set_flag()
{
  if(Str1[2] == 6){
    flag++;
  }
  if(Str1[2] == 2){
    flag = 0;
  }
}

Now this code obviously doesn't verify in v1.0. So I tried to modify it to work with v1.0. I changed Newsoftserial to SoftwareSerial and removed the BYTE and HEX references. Now it verifies but doesn't work.

I'm very new to this and am a bit stuck. Heres my adjustments. :blush:

/*
  RFID Eval 13.56MHz Shield example sketch v10
  
  Aaron Weiss, aaron at sparkfun dot com
  OSHW license: http://freedomdefined.org/OSHW
  
  works with 13.56MHz MiFare 1k tags

  Based on hardware v13:
  D7 -> RFID RX
  D8 -> RFID TX
  D9 -> XBee TX
  D10 -> XBee RX
  
  Note: RFID Reset attached to D13 (aka status LED)
  
  Note: be sure include the NewSoftSerial lib, http://arduiniana.org/libraries/newsoftserial/
  
  Usage: Sketch prints 'Start' and waits for a tag. When a tag is in range, the shield reads the tag,
  blinks the 'Found' LED and prints the serial number of the tag to the serial port
  and the XBee port. 

*/
#include <SoftwareSerial.h>

SoftwareSerial rfid(7, 8);
SoftwareSerial xbee(10, 9);

//Prototypes
void check_for_notag(void);
void halt(void);
void parse(void);
void print_serial(void);
void read_serial(void);
void seek(void);
void set_flag(void);

//Global var
int flag = 0;
int Str1[11];

//INIT
void setup()  
{
  Serial.begin(9600);
  Serial.println("Start");
  
  // set the data rate for the NewSoftSerial ports
  xbee.begin(9600);
  rfid.begin(19200);
  delay(10);
  halt();
}

//MAIN
void loop()                 
{
  read_serial();
}

void check_for_notag()
{
  seek();
  delay(10);
  parse();
  set_flag();
  
  if(flag = 1){
    seek();
    delay(10);
    parse();
  }
}

void halt()
{
 //Halt tag
  rfid.print(255);
  rfid.print(0);
  rfid.print(1);
  rfid.print(147);
  rfid.print(148);
}

void parse()
{
  while(rfid.available()){
    if(rfid.read() == 255){
      for(int i=1;i<11;i++){
        Str1[i]= rfid.read();
      }
    }
  }
}

void print_serial()
{
  if(flag == 1){
    //print to serial port
    Serial.print(Str1[5]);
    Serial.print(Str1[6]);
    Serial.print(Str1[7]);
    Serial.print(Str1[8]);
    Serial.println();
    //print to XBee module
    xbee.print(Str1[5]);
    xbee.print(Str1[6]);
    xbee.print(Str1[7]);
    xbee.print(Str1[8]);
    xbee.println();
    delay(100);
    //check_for_notag();
  }
}

void read_serial()
{
  seek();
  delay(10);
  parse();
  set_flag();
  print_serial();
  delay(100);
}

void seek()
{
  //search for RFID tag
  rfid.print(255);
  rfid.print(0);
  rfid.print(1);
  rfid.print(130);
  rfid.print(131); 
  delay(10);
}

void set_flag()
{
  if(Str1[2] == 6){
    flag++;
  }
  if(Str1[2] == 2){
    flag = 0;
  }
}

Can anyone see where I'm going wrong?

Many thanks...

void loop()                 
{
  read_serial();
}

The loop() function is called in an endless loop. Having that function do nothing but call one other function is a waste of time.

NewSoftSerial rfid(7, 8);
NewSoftSerial xbee(10, 9);

Only one instance can be listening at a time.

  if(flag = 1){

When you assign a value to a variable, the result is the value assigned. So, this might as well be:

flag = 1;
if(1) {

which is likely not what you intended.

Now it verifies but doesn't work.

It does something. You want it to do something. Clearly those two somethings are not the same thing. But, you've given us no clue what either of those things is.

PaulS:

Now it verifies but doesn't work.

It does something. You want it to do something. Clearly those two somethings are not the same thing. But, you've given us no clue what either of those things is.

Thanks for the reply Paul.

What I want the code to do is sit there waiting for a RFID tag, when a tag is sensed write the tags ID to the Serial Monitor.

I basically want the sketch doing the same thing in v1.0 as it does in v0.23. I'm not concerned with the XBee stuff to be honest, but as this is a good script to test if the RFID module is working, I thought it would benefit others to get it working on Arduino v1.0.

Thanks

What I want the code to do is sit there waiting for a RFID tag, when a tag is sensed write the tags ID to the Serial Monitor.

Ok, that's what you want it to do. What does it actually do?

In Arduino v0.23 when I open the Serial Monitor it prints 'Start'.
I swipe a tag over the reader and it prints the tags ID (a 8 digit/character hex key).
It then goes back to seek mode.

In Arduino v1.0 when I open the Serial Monitor it prints 'Start'.
I swipe a tag over the reader and nothing happens.

On the evaluation shield for the RFID module there are LEDs to show that it's searching/seeking a tag and an LED for when it finds a tag.
On both sketches the evaluation shield goes into seek mode and also registers when a tag is swiped.

The difference seems to be whether it prints it out or not.

Tell us what your understanding is of what the parse() function is doing.

void parse()
{
  while(rfid.available()){
    if(rfid.read() == 255){
      for(int i=1;i<11;i++){
        Str1[i]= rfid.read();
      }
    }
  }
}

My understanding is that if there is input to the software serial rfid it will check to see if the input is equal to 255. As for why, i'm not sure.
If it is equal to 255 it will fire up the for loop (which will run 10 times) and build the array Str1 up with 10 digits/characters.

Is that right?
Like I said, I'm not sure what the 255 is about.

S....e...r...i...a...l... ...d...a...t...a... ...a...r...r...i...v...e...s... ...s...l...o...w...l...y...

As soon as the first character arrives, you expect to be able to read all 12 of them. That is not a realistic expectation.

Ok. Point taken on board.

Is there a reason why that sketch works fine in Arduino v0.23 and then not so on Arduino v1.0?

Are you stating that this is the reason?

Is there a reason why that sketch works fine in Arduino v0.23 and then not so on Arduino v1.0?

Obviously. We just haven't figured out what that reason is yet.

Are you stating that this is the reason?

No, but it is flawed code, so it needs to be fixed. Fixing it may, or may not, address the issue with the code not behaving correctly on 1.0.

If it does, we know one thing. If it doesn't, we know something else.

Got ya. I'd like to build a bare bones read and print sketch.

As I don't have control over whats being sent via Serial I can't package the data in a nice way i.e. start and end identifiers.

I'm learning as I go here, so bare with me!

I've found this sketch for another RFID module

int RFIDResetPin = 13;

//Register your RFID tags here
char tag1[13] = "4500B8A5025A";
char tag2[13] = "4500B8C30F31";
char tag3[13] = "4500B8A4C49D";

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

  pinMode(RFIDResetPin, OUTPUT);
  digitalWrite(RFIDResetPin, HIGH);

  //ONLY NEEDED IF CONTROLING THESE PINS - EG. LEDs
  pinMode(2, OUTPUT);
}

void loop(){

  char tagString[13];
  int index = 0;
  boolean reading = false;

  while(Serial.available()){

    int readByte = Serial.read(); //read next available byte

    if(readByte == 2) reading = true; //begining of tag
    if(readByte == 3) reading = false; //end of tag

    if(reading && readByte != 2 && readByte != 10 && readByte != 13){
      //store the tag
      tagString[index] = readByte;
      index ++;
    }
  }

  checkTag(tagString); //Check if it is a match
  clearTag(tagString); //Clear the char of all value
  resetReader(); //eset the RFID reader
}

void checkTag(char tag[]){
///////////////////////////////////
//Check the read tag against known tags
///////////////////////////////////

  if(strlen(tag) == 0) return; //empty, no need to contunue

  if(compareTag(tag, tag1)){ // if matched tag1, do this
    lightLED(2);
    Serial.print("a");

  }else if(compareTag(tag, tag2)){ //if matched tag2, do this
    lightLED(2);
    Serial.print("b");

  }else if(compareTag(tag, tag3)){
    lightLED(2);
    Serial.print("c");

  }else{
    Serial.println(tag); //read out any unknown tag
  }

}

void lightLED(int pin){
///////////////////////////////////
//Turn on LED on pin "pin" for 250ms
///////////////////////////////////
  digitalWrite(pin, HIGH);
  delay(250);
  digitalWrite(pin, LOW);
}

void resetReader(){
///////////////////////////////////
//Reset the RFID reader to read again.
///////////////////////////////////
  digitalWrite(RFIDResetPin, LOW);
  digitalWrite(RFIDResetPin, HIGH);
  delay(150);
}

void clearTag(char one[]){
///////////////////////////////////
//clear the char array by filling with null - ASCII 0
//Will think same tag has been read otherwise
///////////////////////////////////
  for(int i = 0; i < strlen(one); i++){
    one[i] = 0;
  }
}

boolean compareTag(char one[], char two[]){
///////////////////////////////////
//compare two value to see if same,
//strcmp not working 100% so we do this
///////////////////////////////////

  if(strlen(one) == 0) return false; //empty

  for(int i = 0; i < 12; i++){
    if(one[i] != two[i]) return false;
  }

  return true; //no mismatches
}

The bit that is interesting is the While loop

  while(Serial.available()){

    int readByte = Serial.read(); //read next available byte

    if(readByte == 2) reading = true; //begining of tag
    if(readByte == 3) reading = false; //end of tag

    if(reading && readByte != 2 && readByte != 10 && readByte != 13){
      //store the tag
      tagString[index] = readByte;
      index ++;
    }
  }

It looks more efficient. Although I don't fully understand how the beginning and ending part works

    if(readByte == 2) reading = true; //begining of tag
    if(readByte == 3) reading = false; //end of tag

I understand that this codes has a lot of extra stuff i.e. checking previously stated tag values that it compares and then prints a letter based on whether it recognises the tag. But it also prints the tag if it doesn't know it.

I guess I want a sketch that will

  • Check to see if there is anything available via serial
  • if there is, put the Tag hex key in an array (knowing where the start and end are)
  • Print the hex key
  • Clear the hex key array
  • Put the module back into seek mode

In the first sketch, I don't understand the halt function

void halt()
{
 //Halt tag
  rfid.print(255, BYTE);
  rfid.print(0, BYTE);
  rfid.print(1, BYTE);
  rfid.print(147, BYTE);
  rfid.print(148, BYTE);
}

or the seek function

void seek()
{
  //search for RFID tag
  rfid.print(255, BYTE);
  rfid.print(0, BYTE);
  rfid.print(1, BYTE);
  rfid.print(130, BYTE);
  rfid.print(131, BYTE); 
  delay(10);
}

Would you be able to explain those?

Got ya. I'd like to build a bare bones read and print sketch.

First thing to do is see what comes back from the module:

void parse()
{
  while(rfid.available())
  {
    byte rfidVal = rfid.read();
    Serial.println(rfidVal, DEC);
  }
}

This will print every thing that the reader outputs. If this works, we can move on to reading the data properly, and then making use of the data.

Thanks PaulS. I'll try this out tomorrow as I've left the reader at work.

:slight_smile:

I've tried the parse function that you've written.

I swiped a tag with the HEX key 42 52 F2 39. This is 66 82 242 57 in DEC

Arduino v1.0 prints nothing after 'Start'. Thats without or with a tag present.

Arduino v0.23 continually prints..

0
2
130
76
208
255

...after "Start" until I swipe a the tag mentioned above, then it prints: (which you can see is the 66 82 242 57)

0
6
130
2
66
82
242
57
73
255

Incase you needed to to see it together! here you go:

Start
0
2
130
76
208
255
0
2
130
76
208
255
0
2
130
76
208
255
0
2
130
76
208
255
0
2
130
76
208
255
0
2
130
76
208
255
0
6
130
2
66
82
242
57
73
255
0
2
130
76
208
255
0
6
130
2
66
82
242
57
73
255
0
2
130
76
208
255

I guess that explains the 255, as that appears to be the end of each cycle.

I also understand now why in the original code we build an array of 10 items (Str1[]) and only print numbers 5, 6, 7 and 8. Those are the tags ID.

I'm not clear what 0, 1, 2, 3, 4, 9 and 10 are in that array.

I also can't say I understand the Halt function..

void halt()
{
 //Halt tag
  rfid.print(255, BYTE);
  rfid.print(0, BYTE);
  rfid.print(1, BYTE);
  rfid.print(147, BYTE);
  rfid.print(148, BYTE);
}

Definitely feel out of my depth at the moment!