GPS data logging + SIM 800L help

Good day to everyone, I am currently working on a project involving an Arduino UNO, a GPS module and a SIM 800L as a GSM to send data via SMS when requested. The aim of this project is to track the position of the device using the GPS, store such values on an SD card as they are received and, if an SMS is sent to the Arduino, to automatically respond with another message holding the current position of the device. The components I'm using are :
GPS module -> Grove GPS Grove - GPS - Seeed Wiki
GSM module -> SIM 800L V1 (the red one so to speak)
Arduino UNO

Right now I have tested each component separately and no problem arise of any kind, in particular:
I have successfully saved some data on the SD card.
I received the position data from the GPS and checked for the quality of the data.
I was able to assess whether an SMS was sent to Arduino and to answer with a predetermined text.
Also I tested each component using the same wiring, and no problem arise in this sense.

Unfortunately, I have some problems when I try to run the full project with all the components connected and the device stops collecting GPS data as soon as I introduce some calls to the SIM 800L module and I'm unable to understand why. Here is the code I'm using:

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <Sim800l.h>
#include <SD.h>
#include <SPI.h>
Sim800l Sim800l;
String textSms;
String help;
bool report_one;
bool report_two;
const int chipSelect=4;
int counter=0;
String dataString="";
String dataString2="";
String dataString3="";
String dataString4="";
TinyGPSPlus gps;
SoftwareSerial gpsSerial(2,3);
SoftwareSerial SIM_port(9,10);

void setup()
{
  Sim800l.begin();
  delay(2000)
  report_one=Sim800l.delAllSms();
  delay(2000);
  gpsSerial.begin(9600);
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  if (!SD.begin(4)) 
  {
    Serial.println("initialization failed!");
    while (true);
  }
  Serial.println("initialization done.");
}


void loop()
{
  while (gpsSerial.available()>0) 
    if (gps.encode(gpsSerial.read()))  displayInfo();       
    SIM_port.listen();  
    if (SIM_port.available()>0)
    {
      textSms=Sim800l.readSms(1);
      if (textSms.indexOf("OK")!=-1)
      {
        help=dataString2+" "+dataString3;
        int str_len=help.length()+1;
        char distress[str_len]; 
        help.toCharArray(distress,str_len);
        report_two=Sim800l.sendSms("+#########", distress); //phone number here
        delay(2000);
        while (true);
      }
    }
    else
    {
      gpsSerial.listen();
    }
    if (gps.location.isValid())
    {
      if (gps.date.isValid()) 
      {
        dataString=(String(gps.date.month())+"/"+gps.date.day());
      }
      else  
      {
        dataString="*******";
      }
      dataString2=String(gps.location.lat(),6);
      dataString3=String(gps.location.lng(),6); 
      dataString4=String(gps.speed.kmph(),8);
      File dataFile=SD.open("GPS.txt",FILE_WRITE);
      if (dataFile) 
      {
        dataFile.print("Latitude: ");
        dataFile.print(dataString2);
        dataFile.print(" Longitude: ");
        dataFile.print(dataString3);
        dataFile.print(" Speed [km/h]: ");
        dataFile.print(dataString4);
        dataFile.print(" Time: ");
        dataFile.print(dataString);
        dataFile.print(" ");
        if (gps.time.hour()<10) dataFile.print(F("0"));
        dataFile.print(gps.time.hour());
        dataFile.print(":");
        if (gps.time.minute()<10) dataFile.print(F("0"));
        dataFile.print(gps.time.minute());
        dataFile.print(":");
        if (gps.time.second()<10) dataFile.print(F("0"));
        dataFile.print(gps.time.second());
        dataFile.print(".");
        if (gps.time.centisecond()<10) dataFile.print(F("0"));
        dataFile.println(gps.time.centisecond());
        dataFile.close();
       } 
       else
       {
          Serial.println("Failed to open file"); 
          Serial.println();
          while(true);
       }  
    }
    else
    {
      Serial.println("Location: Not Available");
    } 
}



 
void displayInfo()
{
  if (gps.location.isValid())
  {
    Serial.print("Latitude: ");
    Serial.println(gps.location.lat(), 6);
    Serial.print("Longitude: ");
    Serial.println(gps.location.lng(), 6);
    Serial.print("Altitude: ");
    Serial.println(gps.altitude.meters());
    Serial.print("Number of Satellites: ");
    Serial.println(gps.satellites.value(), 6);
  }
  else
  {
    Serial.println("Location: Not Available");
  }
  Serial.print("Date: ");
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print("/");
    Serial.print(gps.date.day());
    Serial.print("/");
    Serial.println(gps.date.year());
    Serial.println();
    Serial.print("Number of Satellites: ");
    Serial.println(gps.satellites.value(), 6);
  }
  else
  {
    Serial.println("Not Available");
  }
  Serial.print("Time: ");
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(":");
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(":");
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(".");
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.println(gps.time.centisecond());
  }
  else
  {
    Serial.println("Not Available");
  }
  Serial.println();
  Serial.println();
  smartDelay(1000);
}

static void smartDelay(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
    while (gpsSerial.available())
      gps.encode(gpsSerial.read());
  } 
  while (millis()-start<ms);
}

If I remove the call to textSms=Sim800l.readSms(1); and the related code, then the GPS works again. Looking online it seems that the issue is related to SoftwareSerial but since this is my first project with Arduino I do not understand where the problem is with my approach.

So the only problem I have is just how to integrate the receiving process of the GPS with the check every once in a while if an SMS has been sent to the Arduino.

Can anyone please suggest how to solve this issue or any sources I can read about? Any help would be much appreciated, thanks in advance for all your kind help.

You can only have one software serial instance listening at a time. You could use the hardware serial port instead, but that makes it harder to debug.

1 Like

Thanks for your kind answer, is there a way to stop the acquisition of the GPS data, listen to the SIM 800L module and then start again listening for GPS data?

Anyhow, setting a device on software serial (like the GPS maybe) and the other one (SIM 800L) on the hardware serial port may be a solution, am I correct?

Also I have read something similar on AltSoftSerial, but I haven't tested it yet.

There is a listen function you can call to select each software serial instance in turn, but I suspect that if you are listening to the GPS when the SMS arrives, you will miss some or all of it.

That's probably what happens, in my code I use the listen function to check the SIM module but the part inside that condition never executes.

Using an Arduino Mega would solve my problem perhaps?

Anything with multiple hardware serial ports would help. You could use a Mega as long as the size isn't an issue.

1 Like

Thank you so much, I will experiment a little more with the code and, if I'm still unsuccessful, I will try the Mega.

In the meantime any other suggestions are welcome.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.