I have been trying to do this for 2 days now. I am able to send the GPS lat,lang as a text message to a receiving number. However what i want now is to send this using GPRS. I am using a SIM900A GSM/GPRS module. I am a Software Engineering student and I'm quite new to Arduino. This is my code to use GSM.
#include <SoftwareSerial.h>
#include <TinyGPS.h>
TinyGPS gps;
SoftwareSerial ss(5, 6);
static void smartdelay(unsigned long ms);
void setup()
{
Serial.begin(115200);
ss.begin(9600);
}
void loop()
{
float flat, flon;
unsigned long age, date, time, chars = 0;
unsigned short sentences = 0, failed = 0;
gps.f_get_position(&flat, &flon, &age);
sendLatLang(flat, flon);
gps.stats(&chars, &sentences, &failed);
Serial.println();
smartdelay(1000);
}
static void smartdelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (ss.available())
gps.encode(ss.read());
} while (millis() - start < ms);
}
static void sendLatLang(float lat, float lang)
{
if (lat == TinyGPS::GPS_INVALID_F_ANGLE || lang == TinyGPS::GPS_INVALID_F_ANGLE) {
Serial.println("Searching for GPS fix...");
} else {
Serial.println("AT+CMGF=1");
delay(1000);
Serial.println("AT+CMGS=\"+94123445678\"");
delay(1000);
Serial.print("Latittude : ");
Serial.println(lat);
Serial.print("Longitude : ");
Serial.println(lang);
Serial.write(26);
delay(1000);
}
}
First, SoftwareSerial is very, very inefficient. It disables interrupts for long periods of time, which interferes with other parts of your sketch.
To summarize this answer:
Second, your because your program talks to two devices, you have to be careful about using
delay
or "blocking" at any part of your program. While the program is "stuck" at adelay
, nothing else is being processed. GPS characters continue to come in, and they will eventually overflow the input buffer (64 char limit). ThesmartDelay
function tries to work around that.You should use a Finite-state Machine to handle the sending, without calling
delay
. Every time throughloop
, the FSM will check to see if it's time to do the next step. This is very easy to implement with aswitch
statement and acase
for each "step" of the sending process (i.e., the current "state").This allows loop to constantly handle all the GPS characters, even though the FSM is "waiting" for some time to elapse. The FSM isn't using
delay
, it is constantly checkingmillis()
to see if the time has elapsed. It checks once perloop
.I would also recommend using my NeoGPS library. It is smaller, faster and more accurate than all other libraries, and it can be configured to parse only the fields and NMEA messages that you really use. If you'd like to try it, it is available from the Arduino IDE menu Sketch -> Include Library -> Manage Libraries.
Here is a NeoGPS version of your sketch:
Your original program used 8896 bytes of program space and 564 bytes of RAM. The NeoGPS version uses 8562 bytes of program space and 364 bytes of RAM.
Even if you don't use NeoGPS, be sure to read the Troubleshooting page. It describes many common problems, which are usually related to program structure and timing.
P.S. Notice that the F macro is used on "double-quoted" string constants... this saves RAM by forcing them to be used from FLASH memory. The sketch also has a SENDING_INTERVAL to avoid sending lat/long messages every second. :P