Compatibility poblem: Duemilanove, Mega and Leonardo

Hey guys!

I’m working on a project with an SM130 RFID-Reader, soldered on an Evaluation Shield - both from Sparkfun.
The firmware of the Reader is upgraded to enable tag collision detection.

Also, I have got three arduinos - Mega, Leonardo and Duemilanove - which fit to the shield.
The problem is: The following code is only working on the Duemilanove:

/*
Code originally from Aaron Weiss, aaron at sparkfun dot com
OSHW license: http://freedomdefined.org/OSHW

D7 -> RFID RX
D8 -> RFID TX

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.
*/

#include <SoftwareSerial.h>

SoftwareSerial rfid(7,8);

//Prototypes
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 readerID = 0;
int Str1[11];

//INIT
void setup()
{
  while(!Serial);
  
  Serial.begin(9600);

  // set the data rate for the SoftwareSerial port
  rfid.begin(19200);
  delay(10);
  halt();
}

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

void halt()
{
 //Halt tag
  rfid.write((uint8_t)255);
  rfid.write((uint8_t)0);
  rfid.write((uint8_t)1);
  rfid.write((uint8_t)147);
  rfid.write((uint8_t)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
    // Tag ID
    Serial.print(Str1[8], HEX);
    Serial.print(Str1[7], HEX);
    Serial.print(Str1[6], HEX);
    Serial.print(Str1[5], HEX);
    Serial.println();

    halt();
    delay(500);
  }
}

void read_Serial()
{
  seek();
  delay(10);
  parse();
  set_flag();
  print_Serial();
  delay(100);
}

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

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

As the RFID-Module is working fine, I assume that there’s something wrong with the serial communication.
The following may be of relevance (http://www.arduino.cc/en/Reference/SoftwareSerial):

  • Not all pins on the Mega and Mega 2560 support change interrupts, so only the following can be used for RX: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69).
  • Not all pins on the Leonardo support change interrupts, so only the following can be used for RX: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).

I tried to change the rx / tx pins to 10 and 11, but I didn’t get a better result.

Anyone knows what I’m missing here? Which parts are board-specific and thus need to be replaced?

Thanks in advanced for your help!

The first argument to the SoftwareSerial constructor is the RX pin. Neither the Leonardo or the Mega support pin 7 as an RX pin.

Both the Leonardo and the Mega have multiple serial ports, so using SoftwareSerial on them is less necessary than on the Duemilanove. So, why are you using it?

Anyone knows what I’m missing here?

An explanation of what IS happening. If nothing happens, say that. Explicitly.

Are there lights on the RFID reader? Do they operate correctly when you scan a tag?

void loop()
{
  read_Serial();
}

Why? It makes no sense putting all the code in a function that loop() calls. That’s just a waste of time and resources as the function call is made.

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

If one character has arrived, and it is a 255, read all 11 of the rest that haven’t arrived yet. What a great idea. NOT!

Alright, thanks for the answer!

It's working with the Mega now: I switched RX from 7 to 10, and I have to reset the Arduino with the reset button once the serial connection is established.

It runs until I try to talk with the Arduino (as the leds on the RFID-reader indicate), but when opening the serial monitor, only the power led remains on. After the reset, everything does as it's supposed to.

You have not explained why you are using SoftwareSerial on hardware with multiple hardware serial ports.

At first, I think I can use whatever serial there is without having to care - as long as it does the job. Secondly, I want to use the same code base, and for other Arduinos there are no multiple hardware serial ports. And finally, I can't access the pins 14 and futher, as the evaluation shield is limited here.

Does someone have an idea how this need for a reset is caused - and how to avoid / sidestep it?