How to: get ID-20LA RFID and SIM900 to communicate with UNO (software serials)

Hello Forum
I am currently working on a project where I have to send out a SMS when a specific RFID tag is scanned. I have my ID-20LA and my SIM900 shield hooked up to my Arduino Uno, and both of them working fine on their own. Both the RFID reader and the GSM shield communicates with my Uno via the software-serial library.

This is my shield
http://imall.iteadstudio.com/im120417009.html

This is my current sketch. It should have functioned this way. "When two known tags gets scanned, send a sms" - what I actually get is that I can't scan any RFID's at all, and no sms gets send.

#include <SoftwareSerial.h>
#include "SIM900.h"
#include "sms.h"
SMSGSM sms;

SoftwareSerial mySerial(4,A2); // RX, TX
int RFIDResetPin = 5;

//Tags tilføjes her, de kan findes i seriel monitor, når et tag scannes.
char tag1[13] = "01002DC7D03B";
char tag2[13] = "01002DC6678D";

void setup(){
  mySerial.begin(9600);
  Serial.begin(9600);
  gsm.begin(2400);

  pinMode(RFIDResetPin, OUTPUT);
  digitalWrite(RFIDResetPin, HIGH);
  
  mySerial.listen(); 
}

void loop(){

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

  while(mySerial.available()){  

    int readByte = mySerial.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
    sms.SendSMS("12345678", "TAG1"); //12345678 = phonenumber
  }
  else if(compareTag(tag, tag2)){ //if matched tag2, do this
    sms.SendSMS("12345678", "TAG2");
  }
  else{
    Serial.println(tag); //Læs ukendte tags, og print serielt.
  }

}
void resetReader(){
  //reset læseren
  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,
  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
}

I've read that the Arduino can't handle two software serials running at once, and therefore you have to use the function ".listen" before communicating with either the RFID or the SIM900. At the bottom of my void setup i end with "mySerial.listen();" to be able to scan my tags. Then when a known tag is scanned, I would like to send a sms, which is this part of the sketch:

if(compareTag(tag, tag1)){ // if matched tag1, do this
gsm.listen();
sms.SendSMS("12345678", "TAG1"); //12345678 = phonenumber

I am then trying to use the "gsm.listen();" before sending the message. The problem is that theres is no ".listen" function build into the SIM900 library and therefore I can't use it. Even if I delete the line "gsm.listen();" I don't receive the sms.

Does anyone know how I can change the serial from the RFID to the SIM900 so I can send my sms?

thank you very much
best regards

Johannes

Links to the shield details would be welcome. Then we have a better idea of what may be configurable and what isn't.

This is my shield
http://imall.iteadstudio.com/im120417009.html :slight_smile:

Top-of-head response!

Do you need to communicate with the computer via USB? If not, could you use 0 & 1 to communicate with the GSM shield? Connect two leds to other pins to indicate success or failure when the card is swiped?

Top-of-head response!

Sorry.. But I didn't know what you've expected other than a link to my shield :slight_smile:

I am unable to use pin 0 and 1. My only option is to use two software serials, one for SIM900 and one for RFID.

best regards

SoftwareSerial mySerial(4,A2); // RX, TX

Do you really have a mySerial connected to those pins? I find that hard to believe. Use an instance name that makes sense with respect to what you REALLY have connected to those pins.

I am unable to use pin 0 and 1.

Why? Is it because you need them to talk to the PC?

My only option is to use two software serials, one for SIM900 and one for RFID.

And that isn't an option since you really need both instances listening at the same time, don't you. You need a Mega.

Thanks for your reply Paul
I actually have a mySerial connected to the pins yes. My RFID is connected there. As the only thing the RFID needs is the RX pin, I've just selected a unused pin (A2) as the TX pin as I can't just leave it blank.

I need them to talk to the pc, and therefore I can't use pin 0 and 1. Actually I would be glad is I could just listen to the RFID as default, and then only listen to the SIM900 while sending a message, and then go back and listen to the RFID until a new SMS has to be sent. But as I said I am unable to figure out how to change between the software serials as the SIM900 library doesn't support the command "gsm.listen();" as I would have used then I had to listen at the SIM900 instead of the RFID.

best regards

I actually have a mySerial connected to the pins yes.

Can you attach a picture of a mySerial? I'm curious what a mySerial looks like.

My RFID is connected there.

So, a more meaningful name would be rfid, wouldn't it?

Actually I would be glad is I could just listen to the RFID as default, and then only listen to the SIM900 while sending a message

You could, as long as you don't need to be able to listen to the SIM900 (except while sending).

But as I said I am unable to figure out how to change between the software serials as the SIM900 library doesn't support the command "gsm.listen();"

If gsm is an instance of SoftwareSerial (I have my doubts about that), it should support listen(). But, actually, any method of the SoftwareSerial class will make the instance that the method is called for the active (listening) instance. So, listen() isn't really required for devices that only send.

You should not be calling checkTag(), clearTag(), and resetReader() on every pass through loop(). You should only be calling them when the end of a tag has been read (reading becomes false).

You should not be calling strlen() with the non-NULL terminated array of chars. You SHOULD be NULL terminating the array as data is added to it. Because the array is local, it is NOT initialized to 13 NULLs, so you can not pretend that the array is NULL terminated.

tagString and index and reading should really be global variables (or at least static) because you can not rely on the entire packet arriving in one iteration of loop().