Reputation: 361
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);
}
Upvotes: 0
Views: 2271
Reputation: 1579
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.
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.
Upvotes: 1