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.
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
//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 readTouchSlide() {
myByte = mySerial.read();
if(myByte == 'U') //if the letter "A" comes from the touchshield
{
//Kwikset lock code
controlKwikset();
//end Kwikset lock code
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
}
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
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().