Running 2x SoftwareSerial, odd blocking problems

I'm running 2 SoftwareSerial instances. 1 to a Parallax RFID reader and 1 to a Liquidware TouchSlide. The code for each works fantastically well as long its on its own. When I combine them, I get odd behavior; only one of them will work at a time, and they alternate which works. I can use the RFID reader once, then it won't work again until the TouchSlide talks to the Arduino. Then once the TouchSlide talks to the 'duino, I can use the RFID reader again.

Help!

//Arduino Mega and Duemilanove or Diecimilia

#include <SoftwareSerial.h>
#define rxPin 3
#define txPin 2

char myByte;

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
SoftwareSerial RFIDSerial = SoftwareSerial(5,14);

//RFID variable setup
int  val = 0; 
char code[11]; 
int bytesread = 0; 


//RFID Tag number arrays
char card1[11] = "3600741A13";
char card2[11] = "3600741965";
//end RFID variable setup

void setup() {
pinMode(rxPin, INPUT);//set recieve as an input
pinMode(txPin, OUTPUT);//set transmit as an output
pinMode(5, INPUT);
pinMode(14, OUTPUT);

//pins for kwikset lock
pinMode(10, OUTPUT);
pinMode(9, OUTPUT);
digitalWrite(10, LOW);
digitalWrite(11, LOW);

//pins for schlage lock
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
digitalWrite(6, LOW);
digitalWrite(7, LOW);



//RFID hardware setup
Serial.begin(9600); // set up the monitoring port
pinMode(4,OUTPUT);   // Set digital pin 4 as OUTPUT to connect it to the RFID /ENABLE pin 
digitalWrite(4, LOW);                  // Activate the RFID reader
//end RFID hardware setup

mySerial.begin(4800); //set up the software serial connection to the TouchSlide
RFIDSerial.begin(2400); //set up the software serial connection to the RFID reader
}

void loop() {
  readRFID();
  myByte = mySerial.read();
    if(myByte == 'U') //if the letter "A" comes from the touchshield
    {
      //Kwikset lock code
      controlKwikset();
      //end Kwikset lock code
        
      //begin Schlage lock code
      controlSchlage();
      //end Schlage lock code
    } 
}

void controlSchlage() {
  digitalWrite(6, HIGH);
  delay(600);
  digitalWrite(6, LOW);
  delay(5000);
  digitalWrite(7, HIGH);
  delay(600);
  digitalWrite(7, LOW);
}

void controlKwikset() {
  digitalWrite(11, HIGH);
  delay(100);
  digitalWrite(10, HIGH);
  delay(100);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
}

void readRFID() {
  
  
    if((val = RFIDSerial.read()) == 10) {   // check for header 
      bytesread = 0; 
      while(bytesread<10) {              // read 10 digit code 
          val = RFIDSerial.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 
        //check the password
        Serial.print("The TAG code is: ");
        Serial.println(code);
        //code[10] = '\0';
        if (code[7] == '9') {
          Serial.println("Found the right card");
          controlSchlage();
        } else {
        Serial.println("Wrong card");
        }
      } 
      bytesread = 0; 
           delay(500);                       // wait for a second 
    }  
}

The soft serial library uses "delay" to time the incoming serial bits; it is bound to block (unless the two incoming streams are perfectly interleaved) , I'm afraid.

Other than using a mega so I could get the 4 serial ports, any advice?

Other than using a mega so I could get the 4 serial ports, any advice?

Write your own soft serial library.

BTDT (but sadly not for the AVR, and not in C).

Have a look at NewSoftSerial : http://arduiniana.org/

That's not working either. In fact, it's working less. As soon as I have both NewSoftwareSerial devices in the loop, all communications are dead. If I only have one or the other in the loop, they work perfectly.

//Arduino Mega and Duemilanove or Diecimilia

#include <NewSoftSerial.h>
int rxPin = 3;
int txPin = 2;

char myByte;

NewSoftSerial mySerial = NewSoftSerial(rxPin, txPin);
NewSoftSerial RFID = NewSoftSerial(5, 14);

//RFID variable setup
int val = 0;
char code[11];
int bytesread = 0;

//RFID Tag number arrays
char card1[11] = "3600741A13";
char card2[11] = "3600741965";
//end RFID variable setup

void setup() {

//pins for kwikset lock
pinMode(10, OUTPUT);
pinMode(9, OUTPUT);
digitalWrite(10, LOW);
digitalWrite(11, LOW);

//pins for schlage lock
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
digitalWrite(6, LOW);
digitalWrite(7, LOW);

Serial.begin(9600);

//RFID hardware setup
RFID.begin(2400);
pinMode(4,OUTPUT); // Set digital pin 4 as OUTPUT to connect it to the RFID /ENABLE pin
digitalWrite(4, LOW); // Activate the RFID reader
//end RFID hardware setup

mySerial.begin(4800); //set up the software serial connection to the TouchSlide

}

void loop() {
readRFID();
delay(100);
readTouchSlide();
}

void controlSchlage() {
digitalWrite(6, HIGH);
delay(600);
digitalWrite(6, LOW);
delay(5000);
digitalWrite(7, HIGH);
delay(600);
digitalWrite(7, LOW);
}

void controlKwikset() {
digitalWrite(11, HIGH);
delay(100);
digitalWrite(10, HIGH);
delay(100);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
}

void readTouchSlide() {
myByte = mySerial.read();
if(myByte == 'U') //if the letter "A" comes from the touchshield
{
//Kwikset lock code
controlKwikset();
//end Kwikset lock code

//begin Schlage lock code
controlSchlage();
//end Schlage lock code
}
}

void readRFID() {

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
if (code[7] ==card1[7]) {
controlSchlage();
}
}
bytesread = 0;
delay(500); // wait for a second
}

}

Check out the web site in the link above for information on using more than one instance of NewSoftSerial

I did, it says as long as they're read serially it should be fine. It's not.

There is a thread with information on newSoftSerial here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1233298805/0

I think dual working was a feature added in the later releases so if there is something there that will help you it maybe towards the end of the thread. If not, try sending a PM to the author, mikalhart

quadmasta,

This may help you understand why your code is not working with NewSoftSerial. NSS allows only one device to actively receive at a time. If device A is active, you can activate device B by calling B.read() or B.available(). But here is the key: since B is not active, there is no data returned from these. read() will return -1 and available() will return 0 for an inactive device.

In your loop, you call readRFID() and readTouchSlide() over and over one after the other. Each of these calls read() just once and exits. This is not reading serially. It's almost exactly the same situation as the example of "how not to" I gave on the NewSoftSerial site.

What you want to do is reorganize your code so that readRFID() doesn't return until a complete RFID has been received (or a suitable timeout has lapsed), and only then do you call readTouchSlide().

Does that make some sense?

Good luck!

Mikal