0

Here is my code including both GSM and GPS code. Im trying to send GPS coordinates as SMS after a call is made to the GSM module. Both work separately but when i combine both of the GSM and GPS code it doesn't print the GPS coordinates.

    #include "SIM900.h"
    #include <SoftwareSerial.h>
    #include "call.h"

    #include "sms.h"
    #include "TinyGPS++.h"
    long lat,lon; // create variable for latitude and longitude object 
    SoftwareSerial gpsSerial(10, 11); // create gps sensor connection
    TinyGPSPlus gps;

    SMSGSM sms;


    CallGSM call;
    boolean started=false;
    char sms_text[160];
    char message[160]; 
    char latitude[12]; char longitude[12];



    void setup()
    {

        Serial.begin(9600);
          gpsSerial.begin(9600);

        if (gsm.begin(9600)) 
        {
            Serial.println("\nstatus=READY");
            started=true;
        } 
        else 
            Serial.println("\nstatus=IDLE");
    }

    void loop()
    {

      switch (call.CallStatus())
      {
        case CALL_NONE: // Nothing is happening

          break;

        case CALL_INCOM_VOICE : // Yes! Someone is calling us

          Serial.println("RECEIVING CALL");
          call.HangUp();
            while(gpsSerial.available()){ // check for gps data
       if(gps.encode(gpsSerial.read())){ // encode gps data

         Serial.println("Latitude= ");
         Serial.print(gps.location.lat(), 6);
         Serial.println("Longitude= ");
         Serial.print(gps.location.lng(), 6);
       }
      }// The gps data doesnt seem to be printed on the serial monitor



          break;

        case CALL_COMM_LINE_BUSY:  // In this case the call would be established

          Serial.println("TALKING. Line busy.");

          break;
      }
      delay(1000);
    }
Anmol Karki
  • 361
  • 1
  • 3
  • 12

1 Answers1

1

You can't use delay if you want to process GPS characters. You must constantly read the GPS characters and process them, every time through loop.

After checking for GPS characters, you can check the call status, but only occasionally. Checking the call status takes time, which can make it lose GPS characters. GPS data is completely parsed once per second, so that would be a good time to check the call status.

Here's your sketch, modified to always check for GPS characters, then check the call status:

#include <SIM900.h>
#include <call.h>
#include <sms.h>

SMSGSM sms;
CallGSM call;
boolean started=false;

#undef STATUS_NONE // bad SIM900 library!
#include <NMEAGPS.h>
NMEAGPS gps;
gps_fix fix; // create variable that holds latitude and longitude

// BEST:
//#include <AltSoftSerial.h>
//AltSoftSerial gpsSerial; // GPS TX to UNO pin 8 (optional: GPS RX to UNO pin 9)

// 2nd BEST:
#include <NeoSWSerial.h>
NeoSWSerial gpsSerial( 10, 11 );

void setup()
{
  Serial.begin(9600);

  if (gsm.begin(9600)) 
  {
      Serial.println( F("\nstatus=READY") ); // F macro saves RAM
      started=true;
  } 
  else 
      Serial.println( F("\nstatus=IDLE") );

  gpsSerial.begin(9600);
}

void loop()
{
  //  Always check for GPS characters.  A GPS fix will become available 
  //    ONCE PER SECOND.  After the fix comes in, the GPS device will 
  //    be quiet for a while.  That's a good time to check the phone status.

  if (gps.available( gpsSerial )){
    fix = gps.read(); // get latest PARSED gps data

    //  Display what was received
    Serial.print( F("Latitude= ") );
    Serial.println( fix.latitude(), 6 );
    Serial.print( F("Longitude= ") );
    Serial.println( fix.longitude(), 6 );

    //  Then check the current GSM status, ONLY ONCE PER SECOND
    CheckCall();
  }

  //delay(1000);   NEVER use delay!  You will lose GPS characters.
}

void CheckCall()
{
  //  You can use the 'fix' structure in here, if you want.

  switch (call.CallStatus())
  {
    case CALL_NONE: // Nothing is happening

      break;

    case CALL_INCOM_VOICE : // Yes! Someone is calling us

      Serial.println("RECEIVING CALL");
      call.HangUp();

      break;

    case CALL_COMM_LINE_BUSY:  // In this case the call would be established

      Serial.println("TALKING. Line busy.");

      break;
  }
}

Notice that is uses my NeoGPS and NeoSWSerial libraries. NeoGPS is smaller, faster, more reliable and more accurate than all other libraries.

You should avoid SoftwareSerial, because it is very inefficient. It disables interrupts for long periods of time, when a character is sent or received. Disabling interrupts for 1ms is an eternity for a 16MHz Arduino. It can't do anything else but wait for the character to finish. It could have executed 10,000 instructions during that time.

Both AltSoftSerial and NeoSWSerial are much more efficient, and they can send and receive at the same time.

If you could connect the GPS to pins 8 & 9, use AltSoftSerial instead. It can be used reliably up to 19200, and then increasingly less reliably up to 115200, depending on how many interrupts are being handled.

If you cannot move it to those pins, use my NeoSWSerial instead. It is almost as efficient as AltSoftSerial, but still much, much better than SoftwareSerial. It can use any two pins, but only at baud rates 9600, 19200 and 38400.

NOTE:

To use NeoSWSerial on these two pins, you have to modify files in the SIM900 library (probably in the Libraries/GSM-GPRS-GPS-Shield-GSMSHIELD directory). You have to search and replace all occurrences of "SoftwareSerial" with "NeoSWSerial". These 4 files must be changed:

  GSM.h
  SIM900.h
  WideTextFinder.h and cpp

NeoGPS and NeoSWSerial are available from the Arduino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries. The examples NMEAsimple.ino and NMEAloc.ino are a good place to start. Tabular.ino displays all the pieces in the default configuration.

Pang
  • 9,564
  • 146
  • 81
  • 122
slash-dev
  • 1,569
  • 2
  • 9
  • 9
  • This is the type of error im getting: libraries\SoftwareSerial\SoftwareSerial.cpp.o (symbol from plugin): In function `SoftwareSerial::read()': (.text+0x0): multiple definition of `__vector_3' sketch\NeoSWSerial.cpp.o (symbol from plugin):(.text+0x0): first defined here @slash-dev – Anmol Karki Jun 09 '17 at 13:09
  • @AnmolKarki, If you are trying to use NeoSWSerial, no part of your sketch can include/use SoftwareSerial. Did you edit those 4 files I mentioned in the note? – slash-dev Jun 09 '17 at 13:50
  • Yeah I replaced every SoftwareSerial with NeoSWSerial and it did compile without any errors. Now to test it with the hardware, if anything comes up I'll let you know – Anmol Karki Jun 12 '17 at 10:50
  • The void loop doesn't seem to bother with the CheckCall() function and even if i call the device, it doesn't print out receiving or anything. please help @slash-dev – Anmol Karki Jun 25 '17 at 13:49
  • This program only works as a GPS data printer. Doesn't bother with the call status. The GPS doesn't keep quite and continuously feeds data which doesnt let the checkCall() to execute – Anmol Karki Jun 25 '17 at 14:05
  • Are you seeing "Latitude= " being printed out? If not, you do not have the GPS connected correctly. Did you follow the NeoGPS Installation instructions? Tried NMEAdiagnostic and NMEAorder? – slash-dev Jun 25 '17 at 14:05
  • Yeah the GPS data is getting printed. Only the checkCall() function doesn't seem to be called after the gps data is printed – Anmol Karki Jun 25 '17 at 14:09
  • I need to send the printed GPS data as an SMS if there is a incoming call but if the checkCall() doesn't get called then there is a problem. – Anmol Karki Jun 25 '17 at 14:11
  • The NeoSWSerial doesnt seem to work with the call.CallStatus(). I cant run the switch case on this program, only the gps data is getting printed which my previous program also could do. – Anmol Karki Jun 25 '17 at 15:00
  • This is my output: `Trying to force the baud-rate to 9600 1200 2400 4800 9600 19200 38400 57600 115200 ERROR: SIM900 doesn't answer. Check power and serial pins in GSM.cpp status=IDLE Latitude= 27.699207 Longitude= 85.335884 TALKING. Line busy. Latitude= 27.699209 Longitude= 85.335891 TALKING. Line busy. Latitude= 27.699207 Longitude= 85.335853 TALKING. Line busy. Latitude= 27.699197 Longitude= 85.335769 TALKING. Line busy. Latitude= 27.699197 Longitude= 85.335678 TALKING. Line busy. Latitude= 27.699199 Longitude= 85.335594` – Anmol Karki Jun 25 '17 at 15:28
  • My serial pins `#define _GSM_TXPIN_ 2 #define _GSM_RXPIN_ 3` – Anmol Karki Jun 25 '17 at 15:35
  • Does `setup` print either READY or IDLE? Edit your question and add links to where you got the libraries. I suspect that `gsm.begin` is returning `false`, which prints IDLE. But I'll bet that means it didn't find the GSM device. – slash-dev Jun 25 '17 at 15:50
  • When I switch to DBG_port on the SIM900 then it prints status IDLE and doesn't recognize the GSM device but when I switch to UART_port it prints status ready and starts print GPS data but after that doesn't bother with call status – Anmol Karki Jun 26 '17 at 12:22
  • What are `DBG_port` and `UART_port`? Are they on different pins? Do you change the GSM wires to match? – slash-dev Jun 26 '17 at 13:23