GPS/SMS tracker - SoftwareSerial conflict? Please help :(

Hi, I am making a GPS localizing device for my dog. I am using Arduino NANO, Neo-6M GPS and SIM800L module.

The idea is that GPS updates position to google maps iOS url and store it in a variable text. GSM module checks for incomming messages and if message "Rotor" is received it changes boolean variable smsRequest to TRUE. Then smsSend function will know that it has to send SMS with GPS coordinates (text) to the sender.

GPS works alone, SIM800l works alone but I have no idea why they don't work together. Maybe there is some kind of conflict between SoftwareSerials. I have no idea how to repair it. I will really appreciate if you could help me out with it.

here is my code:

#include <TinyGPS++.h>
#include <SoftwareSerial.h>

TinyGPSPlus gps;

SoftwareSerial ss(7, 8);
SoftwareSerial SIM900(2, 3);

char text[180];
char latitude[12];
char longitude[12];

unsigned long previousMillis = 0;
const long interval = 5000;         

String number;
char RcvdMsg[200] = "";
int RcvdCheck = 0;
int RcvdConf = 0;
int index = 0;
int RcvdEnd = 0;
char MsgMob[15];
char MsgTxt[50];
int MsgLength = 0;

boolean gpsUpdated = false;
boolean smsRequest = true;

void setup()
{
  Serial.begin(115200);
  ss.begin(9600);
  delay(1000);
  SIM900.begin(4800);
  delay(2000);
  Config();
}

void Config() // This function is configuring our SIM900 module i.e. sending the initial AT commands
{
delay(1000);
SIM900.print("ATE0\r");
Response();
SIM900.print("AT\r");
Response();
SIM900.print("AT+CMGF=1\r");
Response();
SIM900.print("AT+CNMI=1,2,0,0,0\r");
Response();
}

void loop()
{

RecSMS();

sendSMS();


gpsUpdate();


}

void gpsUpdate()
{  

  ss.listen();
  
  while (ss.available() > 0)
    gps.encode(ss.read());    

      if (gps.location.isUpdated())
      {
        strcpy(text, "comgooglemaps://?q=");
        dtostrf(gps.location.lat(), 1, 6, latitude);
        strcat(text,latitude);
        strcat(text,",");
        dtostrf(gps.location.lng(), 1, 6, longitude);
        strcat(text,longitude);
        Serial.println(text);
        //delay(100);
        gpsUpdated = true;
      }
//      else
//      {
//       Serial.println("error"); 
//      }
   
}

void RecSMS()
{
  
SIM900.listen();

if(SIM900.available())
{
char data = SIM900.read();
if(data == '+'){RcvdCheck = 1;}
if((data == 'C') && (RcvdCheck == 1)){RcvdCheck = 2;}
if((data == 'M') && (RcvdCheck == 2)){RcvdCheck = 3;}
if((data == 'T') && (RcvdCheck == 3)){RcvdCheck = 4;}
if(RcvdCheck == 4){RcvdConf = 1; RcvdCheck = 0;}

if(RcvdConf == 1)
{
if(data == '\n'){RcvdEnd++;}
if(RcvdEnd == 3){RcvdEnd = 0;}
RcvdMsg[index] = data;

index++;
if(RcvdEnd == 2){RcvdConf = 0;MsgLength = index-2;index = 0;}
if(RcvdConf == 0)
{
  
Serial.print("Mobile Number is: ");
for(int x = 7;x < 16;x++)
{
  MsgMob[x-4] = RcvdMsg[x];
  number = MsgMob[x-4];
  Serial.print(number);
}
  Serial.println();
  Serial.print("Message Text: ");
for(int x = 45; x < MsgLength; x++)
{
  MsgTxt[x-45] = RcvdMsg[x];
 
 
  Serial.print(MsgTxt[x-45]);
  delay(50);
  if (strcmp("Rotor",MsgTxt) == 0) {    
    smsRequest = true;                     // haslo OK --> wysylamy SMS
    // sendSMS();
    
  }
}

Serial.println();

//****Resetting all the variables*****//

RcvdMsg[200]={0};
RcvdCheck = 0;
RcvdConf = 0;
index = 0;
RcvdEnd = 0;
MsgMob[15];
MsgTxt[50];
MsgLength = 0;

SIM900.flush();


}
}
  SIM900.println("AT+CMGD=1,4");
}


  
}

void sendSMS()
{
 if ((gpsUpdated == true) && (smsRequest == true)) {
  Serial.println("sending SMS");
  //SIM900.listen();  
  delay(300);
  SIM900.print("AT+CMGF=1\r\n");                                                       
  delay(100);
  SIM900.println("AT+CMGS=\""+number+"\"\r\n");                                    
  delay(100);
  SIM900.println(text);        
  delay(100);
  SIM900.println((char)26);                       
  delay(100); 
  SIM900.println();
  delay(100);
  gpsUpdated = false;
  smsRequest = false;
  
}
}


void Response() // Get the Response of each AT Command
{
int count = 0;
Serial.println();
while(1)
{
if(SIM900.available())
{
char data =SIM900.read();
if(data == 'K'){Serial.println("OK");break;}
if(data == 'R'){Serial.println("GSM Not Working");break;}
}
count++;
delay(10);
if(count == 1000){Serial.println("GSM not Found");break;}

}
}

Best regards.

Only one instance of SoftwareSerial can listen at a time. If you want to just send SMS messages, you are OK. But, then you need to dump the RecSMS() call.

If you need to receive GPS data and SMS messages simultaneously, you need an Arduino (or variant) with multiple hardware serial ports. Quit beating your head against the wall trying to accomplish the impossible.

Thanks for reply! Is there any chance to use pins 0 and 1 for one of those devices and SoftwareSerial for others? What alternative to arduino Nano would you recommend? I need it to be small.

Why does your dog need to be able to receive text messages? Spoiled rotten?

You can use Serial to read from one of the devices, once you are done debugging.

What alternative to arduino Nano would you recommend? I need it to be small.

Some of the Teensys have multiple hardware serial ports. Teensy USB Development Board

The developer, Paul Stoffregen, is a staunch supporter of the Arduino project, with some alternative (better) boards.

The SIM800 will pull it's RI (Ring Indicator) pin low when an SMS is received. You can use that as an interrupt for Arduino. So, wait till this interrupt happens, then switch to listening to the SIM800?

valdek737:
Thanks for reply! Is there any chance to use pins 0 and 1 for one of those devices and SoftwareSerial for others? What alternative to arduino Nano would you recommend? I need it to be small.

I use an Adafruit Trinket Pro 3V for a similar project. Do get an FTDI breakout/cable, else you have no serial monitor connection to your PC. FTDI is a lot more convenient for uploading sketches too. Trinket 3V wil run nicely on a LiPo battery too.

Thanks. I will consider using Trinket but I am not sure ATtiny will have enough storage for this program...?

I will order it and change votlage dividers to 3V logic. But until I receive it I will still try to make it work on Arduino. I will try to use Ring Indicator as you suggested. You think I should switch listening using "SIM900.listen();" ?
And for switching to SIM900 should I use

if (digitalRead(ringIndicatorPin) == LOW) {
readSMS();
}
else {
gpsUpdate();
}

? And in the beginning of gpsUpdate(); and readSMS(); codes I would use *.listen();
Would it be ok?

Your SIM800 board probably runs at 3V already, be sure to check that.. My GSM breakout has a VIO pin that you can put to 3V or 5V to tell it the logic levels used.

And no, the ring indicator pin needs to interrupt Arduino, not just read the pin. I think you need to do some studying on how interrupts work. It's not complicated, but you need to wrap your head around it... Especially when you have two devices to talk to with serial connections.

That said, you might be better off getting one breakout with a GPS+GSM combination, not two separate devices. I like: http://www.seeedstudio.com/depot/LoNet-808-Mini-GSMGPRS-GPS-Breakout-p-2493.html

The trinket has The 328P processor, the same one as on the Uno, and the nano, I think, with 28k program memory and 2k dynamic ram. Don't let the size of the board fool you.

what about this one: SIM808 GSM/GPRS/GPS MODULE SIMCOM (Itead IM141125004) GSM/GPRS Quad-Band + GPS

?

Fine too. The board is a bit bigger than the LoNet.

Thanks. I can't find any LoNet board available in Poland so I will go with the other one. What kind of power suply would you recommend? Phone/tablet battery?

I don't know how big your dog is, but mine prefers a small LiPo battery. I have a 550mAh one. For SMS only, smaller batteries may do too, not sure yet. Have a look at Adafruit fona too: Overview | Adafruit FONA 800 Shield | Adafruit Learning System That board is a bit big for my dog, so I went for the LoNet.

My dog is a pretty big guy (42 kg). I am going to power Arduino, Neo-6m GPS and SIM800L module with this battery and I would like it to work for at least 5 hours.

I am thinking about other possible solution. The major problem of mine was inability to simultaneous listening to GSM and GPS. I was able to send SMS and listen to GPS. So I can send GPS coordinates to previously defined phone number whenever Ring Indicator is pulled down. The problem is that I have to use my phone so when my wife or anyone else loses the dog while I am away they can't locate it.

I am thinking that maybe there is a chance that SIM800L could send coordinates to HTML file on a web server every minute and if the dog runs away anyone can access the website and check the position.

I hope this kind of HTML GPRS communication could work one way so listening to GSM SoftwareSerial port would't be necessary. For now I have no idea how to do it and how to setup my website but I will google it in a moment. That idea came to me a moment ago and I hope it is possible.

I use this code to turn GPS coordinates into iOS google map url:

while (ss.available() > 0)
    gps.encode(ss.read());    

      if (gps.location.isUpdated())
      {
        strcpy(text, "comgooglemaps://?q=");
        dtostrf(gps.location.lat(), 1, 6, latitude);
        strcat(text,latitude);
        strcat(text,",");
        dtostrf(gps.location.lng(), 1, 6, longitude);
        strcat(text,longitude);
        Serial.println(text);
        
      }

It works pretty well on iPhone as it opens google maps app and shows a red pin.

I would like this kind of url text i.e. comgooglemaps://?q=50.234234,20.223423 appear on a specified website on my server.
For example I go to: www.myserver.com/dog.html and I see the map link I mentioned above.
Arduino has to update this link every minute somehow.
If anyone knows a similar project I could copy and modify please share :slight_smile:

rickj:
I don't know how big your dog is, but mine prefers a small LiPo battery. I have a 550mAh one. For SMS only, smaller batteries may do too, not sure yet. Have a look at Adafruit fona too: Overview | Adafruit FONA 800 Shield | Adafruit Learning System That board is a bit big for my dog, so I went for the LoNet.

What micro controller do use with the Lonet? (sry for going off topic)

I believe it's up to you.