Parallax RFID and NewSoftSerial

I everyone.

I am having issues with the NewSoftSerial library and my RFID reader.
Using the built in SoftwareSerial library it works but I can’t use that library and NewSoftSerial I can use.
However, even in the most basic sketch I can’t get it to work reliably.

Code is here

#include <NewSoftSerial.h>

int  val = 0; 
char code[10]; 
int bytesread = 0; 

#define rxPin 7
#define txPin 8
// RFID reader SOUT pin connected to Serial RX pin at 2400bps to pin7

void setup()
{ 
  Serial.begin(9600);  // Hardware serial for Monitor 9600bps

  pinMode(txPin,OUTPUT);       // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin 
  digitalWrite(txPin, LOW);    // Activate the RFID reader 
}


void loop()
{ 
  NewSoftSerial RFID = NewSoftSerial(rxPin,53); 
  RFID.begin(2400);

  if((val = RFID.read()) == 10)
  {   // check for header 
    bytesread = 0; 
    while(bytesread<10)
    {  // read 10 digit code 
      val = RFID.read(); 
      if((val == 10)||(val == 13))
      {  // if header or stop bytes before the 10 digit reading 
        break;                       // stop reading 
      } 
      code[bytesread] = val;         // add the digit           
      bytesread++;                   // ready to read next digit  
    } 

    if(bytesread == 10)
    {  // if 10 digit read is complete 
      Serial.print("TAG code is: ");   // possibly a good TAG 
      Serial.println(code);            // print the TAG code 
    }
    bytesread = 0; 
    delay(1000);                       // wait for a second
  } 
}

The output I’m getting looks like this

TAG code is: ÿÿÿÿÿÿÿÿÿÿ

TAG code is: 124070FDA3

TAG code is: 124070FDA3

As you can see sometimes it’s correct, and other times it’s wrong. If i change the delay to less it seems to get worse, but I don’t want to have to use delay at all. I can use debouncing to add the delay in, but I still wouldn’t have to hold my tag up the the reader for 3 seconds to get a good read every time.

Anybody have any ideas?

Thanks
-Eric

Are the Arduino and RFID reader grounds connected? How long is the cable between the two?

It probably won't help but you really should make RFID a global or static variable...

NewSoftSerial RFID = NewSoftSerial(rxPin,53);

void [glow]setup[/glow]()
{
  RFID.begin(2400);
...

They are grounded together, cable is about 16 inches long.

Code changed to

#include <NewSoftSerial.h>

int  val = 0;
char code[10];
int bytesread = 0;

#define rxPin 7
#define txPin 8
// RFID reader SOUT pin connected to Serial RX pin at 2400bps to pin7
NewSoftSerial RFID = NewSoftSerial(rxPin,53);

void setup()
{
  Serial.begin(9600);  // Hardware serial for Monitor 9600bps
  RFID.begin(2400);

  pinMode(txPin,OUTPUT);       // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
  digitalWrite(txPin, LOW);    // Activate the RFID reader
}


void loop()
{

  if((val = RFID.read()) == 10)
  {   // check for header
    bytesread = 0;
    while(bytesread<10)
    {  // read 10 digit code
      val = RFID.read();
      if((val == 10)||(val == 13))
      {  // if header or stop bytes before the 10 digit reading
        break;                       // stop reading
      }
      code[bytesread] = val;         // add the digit          
      bytesread++;                   // ready to read next digit  
    }

    if(bytesread == 10)
    {  // if 10 digit read is complete
      Serial.print("TAG code is: ");   // possibly a good TAG
      Serial.println(code);            // print the TAG code
    }
    bytesread = 0;
    delay(1000);                       // wait for a second
  }
}

with no change

I still can’t say why you’re getting the dotted-y’s but I did spot one other problem in the Sketch…

#include <NewSoftSerial.h>

int  val = 0;
char code[[glow]11[/glow]]; // <-- need space for the terminator
int bytesread = 0;

#define rxPin 7
#define txPin 8
// RFID reader SOUT pin connected to Serial RX pin at 2400bps to pin7
NewSoftSerial RFID = NewSoftSerial(rxPin,53);

void setup()
{
  Serial.begin(9600);  // Hardware serial for Monitor 9600bps
  RFID.begin(2400);

  pinMode(txPin,OUTPUT);       // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
  digitalWrite(txPin, LOW);    // Activate the RFID reader
}


void loop()
{

  if((val = RFID.read()) == 10)
  {   // check for header
    bytesread = 0;
    while(bytesread<10)
    {  // read 10 digit code
      val = RFID.read();
      if((val == 10)||(val == 13))
      {  // if header or stop bytes before the 10 digit reading
        break;                       // stop reading
      }
      code[bytesread] = val;         // add the digit
      bytesread++;                   // ready to read next digit
    }

    if(bytesread == 10)
    {  // if 10 digit read is complete
      [glow]code[bytesread+1] = 0;  // <-- need to terminate the string[/glow]
      Serial.print("TAG code is: ");   // possibly a good TAG
      Serial.println(code);            // print the TAG code
    }
    bytesread = 0;
    delay(1000);                       // wait for a second
  }
}

Yo, Mr. Coding Badly, I think there’s a problem with where you are putting that NULL.

char code[11]; // <-- need space for the terminator
    if(bytesread == 10)
    {  // if 10 digit read is complete
      code[bytesread+1] = 0;  // <-- need to terminate the string

Didn’t you just put the NULL in code[11]?

If I change and use SoftwareSerial with code like this

//#include <NewSoftSerial.h>
#include <SoftwareSerial.h>

int  val = 0;
char code[11];
int bytesread = 0;

#define rxPin 7
#define txPin 8
// RFID reader SOUT pin connected to Serial RX pin at 2400bps to pin7
//NewSoftSerial RFID = NewSoftSerial(rxPin,53);
SoftwareSerial RFID = SoftwareSerial(rxPin,53);

void setup()
{
  Serial.begin(9600);  // Hardware serial for Monitor 9600bps
  RFID.begin(2400);

  pinMode(txPin,OUTPUT);       // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
  digitalWrite(txPin, LOW);    // Activate the RFID reader
}


void loop()
{

  if((val = RFID.read()) == 10)
  {   // check for header
    bytesread = 0;
    while(bytesread<10)
    {  // read 10 digit code
      val = RFID.read();
      if((val == 10)||(val == 13))
      {  // if header or stop bytes before the 10 digit reading
        break;                       // stop reading
      }
      code[bytesread] = val;         // add the digit          
      bytesread++;                   // ready to read next digit  
    }

    if(bytesread == 10)
    {  // if 10 digit read is complete
      code[bytesread] = 0;  // <-- need to terminate the string
      Serial.print("TAG code is: ");   // possibly a good TAG
      Serial.println(code);            // print the TAG code
    }
    bytesread = 0;
//    delay(1000);                       // wait for a second
  }
}

it works perfect. That leads me to believe there is something wrong in the NewSoftSerial library.

Didn’t you just put the NULL in code[11]?

Yikes! Sorry about that.

      [glow]code[bytesread] = 0;  // <-- need to terminate the string[/glow]

Is this the tag reader you have…
http://www.parallax.com/tabid/768/ProductID/114/Default.aspx

That leads me to believe there is something wrong in the NewSoftSerial library

Sounds like it. There haven’t been any similar complaints which makes me suspect the problem is with the baud rate (2400). Probably the bit time calculation.

Where’s Mikal Hart when you need him?

That is the exact reader I have

Using the built in SoftwareSerial library it works but I can't use that library

Why not?

Every time I use the SoftwareSerial library it holds the sketch waiting for serial data. I need other things to happen while there isn't any data. Also I want to have more then one thing connected via serial later on down the road.

That is definately a "show stopping" problem.

Unfortunately, I don't know enough about the two libraries to help much more than what little I have. I know the author (Mikal Hart) has his own web site... http://arduiniana.org/libraries/newsoftserial/

I also know he occasionally visits this site... http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1233298805/all

At this point, I suggest posting a message on Mr Hart's web site; he seems to be very response.

Thanks for the help I've posted a message on his site asking if he can look at this thread and have any insight.

Thanks again.

Greetings, all...!

This is a timing issue. You should usually check nss.available() before attempting any reads. If you try to read when no characters are available, NewSoftSerial returns -1 (unlike SoftwareSerial, which just waits until a character arrives). I know this is what's happening here, because when you try to print -1 as a character you get that umlauted-y character :y.

Assuming the data flows in groups of 10 characters terminated by a CR/LF, I think I'd architect the loop function something like this:

char code[11];
int offset = 0;

void loop()
{
  if (rfid.available() > 0)
  {
    if (offset > 10)
    {
      Serial.println("Weird: buffer overflow");
      offset = 0;
    }
    char c = rfid.read();
    if (c == '\r' || c == '\n')
    {
      code[offset] = 0;
      if (c == '\r')
      {
        Serial.print("Tag code is ");
        Serial.println(code);
      }
      offset = 0;
    }
    else
    {
      code[offset++] = c;
    }
  }
}

Also, you shouldn't call rfid.begin() every time through the loop. That reinitializes the port, potentially losing data. Just call it once in setup().

Mikal

Thanks Mikal

The code I was using I grabbed from another site, not something I wrote myself. I will change it to what you have suggested and post my results when I do.

Thanks again