Sending GPS cordinates after Receiving a keyword

hello there! I’m trying to send the GPS coordinates via SMS but only after receiving a keyword “TRACK”. I want it to send continuously every a minute or so, only after receiving the said keyword.

Also I’m trying to light a LED if there is a location fix, but it doesn’t light up even if there is a location fix.

I’ve been doing this all day and I can’t seem to do it. please help

PS this is the code that -dev have given in the other forum posts and I tried modifying it but it doesn’t work. please help.

#include "SIM900.h"
#include <SIM900.h>
#include <SoftwareSerial.h>
#include "sms.h"
#undef STATUS_NONE // bad SIM900 library!
#include <NMEAGPS.h>
#define gps_port SoftwareSerial
SoftwareSerial gps_port( 10,9 );

int numdata;
boolean GSMledBlinking =false;
boolean GPSlock = false;
boolean TrackNow = false;
char smsbuffer[160];
char n[20];
const int GSMled = 4;
const int GPSled = 5;
const int Systemled = 13;
const int SirenRelay = 7;
const int buttonPin = 53;
//debug begin
char sms_position;
char phone_number[20]; // array for the phone number string
char sms_text[100];
int buttonState = 0;
int i;

NMEAGPS gps;
gps_fix fix;
SMSGSM sms;


void setup()
{
    pinMode(GSMled, OUTPUT);
    pinMode(GPSled, OUTPUT);
    pinMode(Systemled, OUTPUT);
    pinMode(SirenRelay, OUTPUT);
    digitalWrite(Systemled, HIGH);
    Serial.begin(9600);
    gps_port.begin(9600);
    Serial.println("GSM Shield testing.");

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

    if(GSMledBlinking) 
    {
       
       for(i=1;i<=20;i++)
       {
           sms.DeleteSMS(i);
           
       }
    }

    
};

uint16_t fixCount;


void loop()
{
  Receiving();
  Tilt();
     
    if (GSMledBlinking)
      {
        GSMledBlink();
      }
}


void GSMledBlink()
{
pinMode(GSMled, OUTPUT); 
digitalWrite(GSMled,LOW);
delay(3000);
digitalWrite(GSMled,HIGH);
delay(1000);
}

void GPSTest()
{
     while (gps.available( gps_port ))
  {
    fix = gps.read();
    fixCount++;
    if (fix.valid.location&&(fixCount > 1 * 60))
    {
     fixCount = 0; // reset the counter
      Serial.print( F("longitude: ") );
      Serial.println( fix.latitude(), 5 );
      Serial.print( F("latitude : ") );
      Serial.println( fix.longitude(), 5 );
      Alert();
    }

      else if (fix.valid.location)
      {
          pinMode(5, OUTPUT); 
          digitalWrite(5,HIGH);
          delay(1000);
          digitalWrite(5,LOW);
           delay(1000);
      }
  }
}

void Receiving()
{
    if(GSMledBlinking) 
    {
        sms_position=sms.IsSMSPresent(SMS_UNREAD);
        if (sms_position) 
        {
            // read new SMS
            Serial.print("SMS postion:");
            Serial.println(sms_position,DEC);
            sms.GetSMS(sms_position, phone_number, sms_text, 100);
            // now we have phone number string in phone_num
            Serial.println(phone_number);
            // and SMS text in sms_text
            Serial.println(sms_text);


           
            if (strcmp(sms_text,"Siren Off")==0)//comparing char sms_text to a string
            {
               pinMode(SirenRelay, OUTPUT);
              digitalWrite(SirenRelay,LOW);
            } 
            else if (strcmp(sms_text,"Siren Test")==0)//comparing char sms_text to a string
            {
               pinMode(SirenRelay, OUTPUT);
               digitalWrite(SirenRelay,HIGH);
               delay(1000);
               digitalWrite(SirenRelay,LOW);
               delay(1000);
               digitalWrite(SirenRelay,HIGH);
               delay(1000);
               digitalWrite(SirenRelay,LOW);
               delay(1000);
            }
            else if (strcmp(sms_text,"UNLI")==0)//comparing char sms_text to a string
            {
               sms.SendSMS(8080, "C20");
            }
            else if (strcmp(sms_text,"TRACK")==0)//comparing char sms_text to a string
            {
              // if(GPSlock == true)
               //{
               // TrackNow = true;
                sms.SendSMS(phone_number, "Will Now Track the Vehicle Every 5 Minutes");
                GPSTest();
               /*}
               else
               {
                 sms.SendSMS(phone_number,"GPS doesn't have satellite lock!! ");
               }*/            
            }
            
        else
        {
         sms.SendSMS(phone_number, "Wrong Keyword!!!");
        }     
        delay(1000);
    }
    }
}


void Alert()
{
        // Build the message to send
      char text[ 159 ];

      strcpy_P( text, (const char *) F("Current Motorcycle Location\nlongitude: ") );
      char *ptr = &text[ strlen(text) ]; // end of the text so far

      if (fix.valid.location)                 //  <-- add this if test
        dtostrf( fix.latitude(), 4, 5, ptr ); // append the latitude
      char   *lat    = ptr;                 // remember where these characters are...
      size_t  latLen = strlen(ptr);         //   ... and how many.
      ptr = &ptr[ latLen ];

      strcpy_P( ptr, (const char *) F("\nlongitude: ") ); // append this string
      ptr = &ptr[ strlen(ptr) ];

      if (fix.valid.location)                 //  <-- add this if test
        dtostrf( fix.longitude(), 4, 5, ptr ); // append the longitude
      char   *lon    = ptr;                  // remember...
      size_t  lonLen = strlen(ptr);
      ptr = &ptr[ lonLen ];

      strcpy_P( ptr, (const char *) F("\n\nOpen Google Maps by clicking:\nhttps://maps.google.com/maps?q=(") );
      ptr = &ptr[ strlen(ptr) ];

      strncpy( ptr, lat, latLen );  // copy those latitude characters again
      ptr = &ptr[ latLen ];

      *ptr++ = ',';  // append one character

      strncpy( ptr, lon, lonLen );  // copy those longitude characters again
      ptr = &ptr[ lonLen ];

      strcpy_P( ptr, (const char *) F(")") ); // and finish the URL


      //  Make sure we didn't run past the end of the text[array]
      size_t textLen = strlen(text);
      if (textLen >= sizeof(text)) {
        Serial.print( F("text array too small!  Needs to be at least text[") );
        Serial.print( textLen + 1 );
        Serial.println( F("] !") );
      }

      Serial.println( text );

      //  Send the message

      gsm.begin(9600);
      if (sms.SendSMS( phone_number, text ))
        {
        Serial.println( F("\nSMS sent OK.") );
        }
      else
        {
        Serial.println( F("\nError sending SMS.") );
        }

}

void Tilt()
{

pinMode(SirenRelay, OUTPUT);
pinMode(buttonPin, INPUT);

buttonState = digitalRead(buttonPin);
    if (buttonState == HIGH) 
    {
      digitalWrite(SirenRelay, HIGH);
    }
    else 
      {
        Receiving();
      }
}

If I don’t receive a keyword and only light the LED it works, but if I start with the receiving keyword part. it doesn’t light up anymore.

I used this code here:

#include <SIM900.h>
#include "sms.h"
SMSGSM sms;

#undef STATUS_NONE // bad SIM900 library!
#include <NMEAGPS.h>
NMEAGPS gps;
gps_fix fix;

#define gps_port SoftwareSerial

#include <SoftwareSerial.h>
SoftwareSerial gps_port( 10, 9 );



char remoteNumber[] = "+639059456422";


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

uint16_t fixCount;

void loop()
{
  while (gps.available( gps_port ))
  {
    fix = gps.read();
    fixCount++;
    if (fix.valid.location&&(fixCount > 1 * 60))
    {
     fixCount = 0; // reset the counter
      Serial.print( F("longitude: ") );
      Serial.println( fix.latitude(), 5 );
      Serial.print( F("latitude : ") );
      Serial.println( fix.longitude(), 5 );
      Alert();
    }

      else if (fix.valid.location)
      {
          pinMode(5, OUTPUT); 
          digitalWrite(5,HIGH);
          delay(1000);
          digitalWrite(5,LOW);
           delay(1000);
      }
  }

}

void Alert()
{
        // Build the message to send
      char text[ 159 ];

      strcpy_P( text, (const char *) F("Current Motorcycle Location\nlongitude: ") );
      char *ptr = &text[ strlen(text) ]; // end of the text so far

      if (fix.valid.location)                 //  <-- add this if test
        dtostrf( fix.latitude(), 4, 5, ptr ); // append the latitude
      char   *lat    = ptr;                 // remember where these characters are...
      size_t  latLen = strlen(ptr);         //   ... and how many.
      ptr = &ptr[ latLen ];

      strcpy_P( ptr, (const char *) F("\nlongitude: ") ); // append this string
      ptr = &ptr[ strlen(ptr) ];

      if (fix.valid.location)                 //  <-- add this if test
        dtostrf( fix.longitude(), 4, 5, ptr ); // append the longitude
      char   *lon    = ptr;                  // remember...
      size_t  lonLen = strlen(ptr);
      ptr = &ptr[ lonLen ];

      strcpy_P( ptr, (const char *) F("\n\nOpen Google Maps by clicking:\nhttps://maps.google.com/maps?q=(") );
      ptr = &ptr[ strlen(ptr) ];

      strncpy( ptr, lat, latLen );  // copy those latitude characters again
      ptr = &ptr[ latLen ];

      *ptr++ = ',';  // append one character

      strncpy( ptr, lon, lonLen );  // copy those longitude characters again
      ptr = &ptr[ lonLen ];

      strcpy_P( ptr, (const char *) F(")") ); // and finish the URL


      //  Make sure we didn't run past the end of the text[array]
      size_t textLen = strlen(text);
      if (textLen >= sizeof(text)) {
        Serial.print( F("text array too small!  Needs to be at least text[") );
        Serial.print( textLen + 1 );
        Serial.println( F("] !") );
      }

      Serial.println( text );

      //  Send the message

      gsm.begin(9600);
      if (sms.SendSMS( remoteNumber, text ))
        {
        Serial.println( F("\nSMS sent OK.") );
        }
      else
        {
        Serial.println( F("\nError sending SMS.") );
        }

}

I Don’t know what to do anymore…

You have a Mega, so you should use the extra HardwareSerial ports, Serial1, Serial2 or Serial3. This GSM-GPRS-GPS-Shield-GSMSHIELD library (great name!) will use Serial1 for the GSM shield if you change these lines at the top of GSM.h:

//#define UNO
#define MEGA

Then make sure the GSM TX is connected to RX1 (Mega pin 19), and the GSM RX is connected to TX1 (Mega pin 18).

You should connect the GPS to either Serial2 (GPS TX to Mega RX2 pin 17) or Serial3 (GPS TX to Mega RX3 pin 15). DO NOT USE SoftwareSerial.

senoyasha:
I’m trying to send the GPS coordinates via SMS but only after receiving a keyword “TRACK”. I want it to send continuously every a minute or so, only after receiving the said keyword.

First, declare a tracking flag that can be true or false:

    bool tracking = false;

Then set the flag when you receive “TRACK”. Shouldn’t you be able to stop tracking? Maybe clear the flag when you receive “STOP”:

    char smsAvailable = sms.IsSMSPresent( SMS_UNREAD );

    if (smsAvailable > 0) {
      // Got one!
      char message[ 20 ];

      sms.GetSMS( smsAvailable, remoteNumber, sizeof(remoteNumber), message, sizeof(message) );

      if (strstr_P( message, (const char *) F("TRACK") ))
        tracking = true;
      else if (strstr_P( message, (const char *) F("STOP") ))
        tracking = false;

      sms.DeleteSMS( smsAvailable );
    }

Also I’m trying to light a LED if there is a location fix

Don’t use delay. It will cause the sketch to lose GPS data. Just set the LED on or off when a new fix is received:

  // Check for GPS data
  while (gps.available( gps_port ))
  {
    fix = gps.read();
    gpsSeconds++; // this is our "clock" for timing, like millis()

    // Turn the pin 5 LED ON or OFF, depending on whether we have a fix or not.
    digitalWrite( 5, fix.valid.location );

Incorporating all those suggestions, here is a new sketch:

static const bool useSMS = false; // when false, don't send or receive SMS messages, just print

#include <SIM900.h>
#include "sms.h"
SMSGSM sms;

#undef STATUS_NONE // bad SIM900 library!
#include <NMEAGPS.h>
NMEAGPS gps;
gps_fix fix;

#define gps_port Serial2 // pin 17 to GPS TX, pin 16 to GPS RX


char remoteNumber[] = "+639059456422";


void setup()
{
  Serial.begin(9600);
  gps_port.begin(9600);
  if (useSMS)
     gsm.begin(9600); // connect to Serial1 (pin 19 to GPS TX, pin 18 to GPS RX)
}

uint16_t gpsSeconds;
bool     tracking = false;
uint16_t lastTrackSent;
uint16_t lastSMScheck;

void loop()
{
  // Check for a command from the Serial Monitor window
  //    (just for debugging, really).
  if (Serial.available()) {
    char cmd = Serial.read();

    if (cmd == 't') {
      tracking = true;
      Serial.println( F("Tracking ON") );
    } else if (cmd == 's') {
      tracking = false;
      Serial.println( F("Tracking OFF") );
    }
  }
  
  // Check for GPS data
  while (gps.available( gps_port ))
  {
    fix = gps.read();
    gpsSeconds++; // this is our "clock" for timing, like millis()

    // Turn the pin 5 LED ON or OFF, depending on whether we have a fix or not.
    digitalWrite( 5, fix.valid.location );

    // Don't constantly send a tracking SMS, because it takes a long time.
    //    Just send it once every 60 seconds.

    if (fix.valid.location && tracking && 
        ((gpsSeconds - lastTrackSent) > 1 * 60))
    {
      Serial.print( F("longitude: ") );
      Serial.println( fix.latitude(), 5 );
      Serial.print( F("latitude : ") );
      Serial.println( fix.longitude(), 5 );
      Alert();

      lastTrackSent = gpsSeconds; // reset the timer
    }
  }

  // Don't constantly check for an SMS, because it takes a long time.
  //    Just check once every 30 seconds.

  if (useSMS && ((gpsSeconds - lastSMScheck) > 30)) {

    // Time to check for a new SMS
    char smsAvailable = sms.IsSMSPresent( SMS_UNREAD );

    if (smsAvailable > 0) {
      // Got one!
      char message[ 20 ];

      sms.GetSMS( smsAvailable, remoteNumber, sizeof(remoteNumber), message, sizeof(message) );

      if (strstr_P( message, (const char *) F("TRACK") ))
        tracking = true;
      else if (strstr_P( message, (const char *) F("STOP") ))
        tracking = false;

      sms.DeleteSMS( smsAvailable );
    }

    lastSMScheck = gpsSeconds;
  }

} // loop

void Alert()
{
  // Build the message to send
  char text[ 159 ];

  strcpy_P( text, (const char *) F("Current Motorcycle Location\nlongitude: ") );
  char *ptr = &text[ strlen(text) ]; // end of the text so far

  if (fix.valid.location)                 //  <-- add this if test
    dtostrf( fix.latitude(), 4, 5, ptr ); // append the latitude
  char   *lat    = ptr;                 // remember where these characters are...
  size_t  latLen = strlen(ptr);         //   ... and how many.
  ptr = &ptr[ latLen ];

  strcpy_P( ptr, (const char *) F("\nlongitude: ") ); // append this string
  ptr = &ptr[ strlen(ptr) ];

  if (fix.valid.location)                 //  <-- add this if test
    dtostrf( fix.longitude(), 4, 5, ptr ); // append the longitude
  char   *lon    = ptr;                  // remember...
  size_t  lonLen = strlen(ptr);
  ptr = &ptr[ lonLen ];

  strcpy_P( ptr, (const char *) F("\n\nOpen Google Maps by clicking:\nhttps://maps.google.com/maps?q=(") );
  ptr = &ptr[ strlen(ptr) ];

  strncpy( ptr, lat, latLen );  // copy those latitude characters again
  ptr = &ptr[ latLen ];

  *ptr++ = ',';  // append one character

  strncpy( ptr, lon, lonLen );  // copy those longitude characters again
  ptr = &ptr[ lonLen ];

  strcpy_P( ptr, (const char *) F(")") ); // and finish the URL


  //  Make sure we didn't run past the end of the text[array]
  size_t textLen = strlen(text);
  if (textLen >= sizeof(text)) {
    Serial.print( F("text array too small!  Needs to be at least text[") );
    Serial.print( textLen + 1 );
    Serial.println( F("] !") );
  }

  Serial.println( text );

  if (useSMS) {
    //  Send the message

    if (sms.SendSMS( remoteNumber, text ))
      {
      Serial.println( F("\nSMS sent OK.") );
      }
    else
      {
      Serial.println( F("\nError sending SMS.") );
      }
  }

} // Alert

I added a useSMS flag that lets you test the program without sending or receiving messages. You can use the Serial Monitor window to enter a command. Enter ‘t’ to start tracking or ‘s’ to STOP tracking. When useSMS is false, it will just print things to the Serial Monitor window. No SMS will be sent. Change useSMS to true when you want to use the GSM shield to send/receive SMS messages.

As I mentioned in your other post, “the SIM900 library has several compile warnings, and it does not play nicely with other libraries.” Everytime you use one of the SIM900 library methods, it will lose GPS data. When the SIM900 library returns to loop, it will eventually start getting fixes again.

With the timings you are using (1 minute), the sketch will work. Just remember that after performing an SMS operation, it may take 1 or 2 seconds to get the current GPS fix.

Cheers,
/dev

thank you very much sir!
it helps a lot. thank you!

I am thinking of adding more features, using tilt sensor and a siren/horn to make it more secure. what do you think sir? should I go for it? if so, mind giving me a few pointers or suggestions? thank you.

senyosha:
it helps a lot. thank you!

I'm glad it's working. If you had to change anything, please post the final sketch that worked for you. It will help others who find your post.

I am thinking of adding more features...

Good! Now it's a "real" project. :wink:

mind giving me a few pointers or suggestions?

* Don't use String™. If you can't figure out how to use char arrays, ask a question. You'll get lots of suggestions.

* Don't use delay. When you want to do several things at the same time, don't make the Arduino stop in its tracks and twiddle its thumbs. Just add extra "checking" sections and "lastCheck" time variables to loop.

* Don't use a software serial port on a Mega, and make sure your libraries don't use SoftwareSerial, either.

* Take some time to read Useful Links. Don't try to read it all at once -- read one topically thoroughly and make sure you understand the concepts and the examples.

Cheers,
/dev

hey sir. I transfered my code to another PC but when I try to Compile it says: " 'Serial2' was not declared in this scope " what seems to be the problem?

Post the sketch in code tags (select the code and press the “<>” button, or put "[code]" before your sketch and "[/code]" after your sketch) or attach the INO file if it’s too big.

In the IDE, try to build your sketch and select all the error messages in the build window, and paste them into a code block, too. You can also press the “Copy Error Messages” button. If there are too many messages, paste them into a text document (e.g., NotePad) and attach the TXT file.

Until then, I can only guess that you haven’t selected “Mega 2560” in the Tools → Board menu.

this is the error sir:

Arduino: 1.6.7 (Windows 10), Board: "Arduino/Genuino Uno"

C:\Users\user\Desktop\sen files\THESIS_ARDUINOCC_SUGGESTION\THESIS_ARDUINOCC_SUGGESTION.ino: In function 'void setup()':

THESIS_ARDUINOCC_SUGGESTION:12: error: 'Serial2' was not declared in this scope

 #define gps_port Serial2 // pin 17 to GPS TX, pin 16 to GPS RX

                  ^

C:\Users\user\Desktop\sen files\THESIS_ARDUINOCC_SUGGESTION\THESIS_ARDUINOCC_SUGGESTION.ino:22:3: note: in expansion of macro 'gps_port'

   gps_port.begin(9600);

   ^

C:\Users\user\Desktop\sen files\THESIS_ARDUINOCC_SUGGESTION\THESIS_ARDUINOCC_SUGGESTION.ino: In function 'void loop()':

THESIS_ARDUINOCC_SUGGESTION:12: error: 'Serial2' was not declared in this scope

 #define gps_port Serial2 // pin 17 to GPS TX, pin 16 to GPS RX

                  ^

C:\Users\user\Desktop\sen files\THESIS_ARDUINOCC_SUGGESTION\THESIS_ARDUINOCC_SUGGESTION.ino:53:25: note: in expansion of macro 'gps_port'

   while (gps.available( gps_port ))

                         ^

exit status 1
'Serial2' was not declared in this scope

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.

and the problem lies here: #define gps_port Serial2 // pin 17 to GPS TX, pin 16 to GPS RX

PS. sir, I used the sketch that you suggested and these were the errors

-dev:
Until then, I can only guess that you haven't selected "Mega 2560" in the Tools -> Board menu.

He is very likely right.

senoyasha:

Arduino: 1.6.7 (Windows 10), Board: "Arduino/Genuino Uno"

In the first line of your error it says Board: Arduino Uno. The Uno has only one Serial port(i think), so that the IDE thinks you did something wrong.
You have to change tho board to Arduino Mega. You can do this by clicking on Tools -> Boards and selecting "Arduino Mega 2560" as -dev suggested.

Hope this helps, and as I write this, i realize that this is somewhat useless because everything has been said before :smiley:

HOLY COW! Can't believe I forgot something like checking the type of board. HAHA
thanks mate!!!

I'll try to add more features to this. I'll post it later. Please don't get tired of giving advices and instructions to me. Thank you very much!

as I said this is the new code:

static const bool useSMS = false; // when false, don't send or receive SMS messages, just print
#include <SIM900.h>
#include "sms.h"
SMSGSM sms;

#undef STATUS_NONE // bad SIM900 library!
#include <NMEAGPS.h>
NMEAGPS gps;
gps_fix fix;

#define gps_port Serial2 // pin 17 to GPS TX, pin 16 to GPS RX


char remoteNumber[] = "+639059456422";
int buttonState = 0;
const int SirenRelay = 7;
const int buttonPin = 53;
const int GSMled = 4;
bool TILTLOCK = false;

void setup()
{
   digitalWrite(13,HIGH); //SystemLed light up once the Arduino is powered
  Serial.begin(9600);
  gps_port.begin(9600);
  if (useSMS)
     gsm.begin(9600); // connect to Serial1 (pin 19 to GPS TX, pin 18 to GPS RX)
     if (gsm.begin(9600)) //the GSM indicator LED will light up
     {
      digitalWrite(GSMled,HIGH);
     }
}

uint16_t gpsSeconds;
bool     tracking = false;
uint16_t lastTrackSent;
uint16_t lastSMScheck;

void loop()
{
  // Check for a command from the Serial Monitor window
  //    (just for debugging, really).
  if (Serial.available()) 
  {
    char cmd = Serial.read();

    if (cmd == 't') 
    {
      tracking = true;
      Serial.println( F("Tracking ON") );
    } 
    else if (cmd == 's') 
    {
      tracking = false;
      Serial.println( F("Tracking OFF") );
    }
  }
  
  // Check for GPS data
  while (gps.available( gps_port ))
  {
    fix = gps.read();
    gpsSeconds++; // this is our "clock" for timing, like millis()

    // Turn the pin 5 LED ON or OFF, depending on whether we have a fix or not.
    digitalWrite( 5, fix.valid.location );

    // Don't constantly send a tracking SMS, because it takes a long time.
    //    Just send it once every 60 seconds.

    if (fix.valid.location && tracking && 
        ((gpsSeconds - lastTrackSent) > 1 * 60))
    {
      Serial.print( F("longitude: ") );
      Serial.println( fix.latitude(), 5 );
      Serial.print( F("latitude : ") );
      Serial.println( fix.longitude(), 5 );
      Alert();

      lastTrackSent = gpsSeconds; // reset the timer
    }
  }
  
  // Don't constantly check for an SMS, because it takes a long time.
  //    Just check once every 30 seconds.
  
  if (useSMS && ((gpsSeconds - lastSMScheck) > 30)) 
  {

    // Time to check for a new SMS
    char smsAvailable = sms.IsSMSPresent( SMS_UNREAD );

    if (smsAvailable > 0) 
    {
      // Got one!
      char message[ 20 ];

      sms.GetSMS( smsAvailable, remoteNumber, sizeof(remoteNumber), message, sizeof(message) );

      if (strstr_P( message, (const char *) F("TRACK") ))
        tracking = true;
      else if (strstr_P( message, (const char *) F("STOP") ))
        tracking = false;

      sms.DeleteSMS( smsAvailable );
    }

    lastSMScheck = gpsSeconds;
  }
      Receiving();//function to check if there is new message and compare the text to execute certain commands
        while(TILTLOCK)
          {
            Tilt(); //function to check the status of the tilt switch module
          }
} // loop

void Alert()
{
  // Build the message to send
  char text[ 159 ];

  strcpy_P( text, (const char *) F("Current Motorcycle Location\nlongitude: ") );
  char *ptr = &text[ strlen(text) ]; // end of the text so far

  if (fix.valid.location)                 //  <-- add this if test
    dtostrf( fix.latitude(), 4, 5, ptr ); // append the latitude
  char   *lat    = ptr;                 // remember where these characters are...
  size_t  latLen = strlen(ptr);         //   ... and how many.
  ptr = &ptr[ latLen ];

  strcpy_P( ptr, (const char *) F("\nlongitude: ") ); // append this string
  ptr = &ptr[ strlen(ptr) ];

  if (fix.valid.location)                 //  <-- add this if test
    dtostrf( fix.longitude(), 4, 5, ptr ); // append the longitude
  char   *lon    = ptr;                  // remember...
  size_t  lonLen = strlen(ptr);
  ptr = &ptr[ lonLen ];

  strcpy_P( ptr, (const char *) F("\n\nOpen Google Maps by clicking:\nhttps://maps.google.com/maps?q=(") );
  ptr = &ptr[ strlen(ptr) ];

  strncpy( ptr, lat, latLen );  // copy those latitude characters again
  ptr = &ptr[ latLen ];

  *ptr++ = ',';  // append one character

  strncpy( ptr, lon, lonLen );  // copy those longitude characters again
  ptr = &ptr[ lonLen ];

  strcpy_P( ptr, (const char *) F(")") ); // and finish the URL


  //  Make sure we didn't run past the end of the text[array]
  size_t textLen = strlen(text);
  if (textLen >= sizeof(text))
  {
    Serial.print( F("text array too small!  Needs to be at least text[") );
    Serial.print( textLen + 1 );
    Serial.println( F("] !") );
  }

  Serial.println( text );

  if (useSMS) 
  {
    //  Send the message

    if (sms.SendSMS( remoteNumber, text ))
      {
      Serial.println( F("\nSMS sent OK.") );
      }
    else
      {
      Serial.println( F("\nError sending SMS.") );
      }
  }

} // Alert


void Receiving()
{
  char smsAvailable = sms.IsSMSPresent( SMS_UNREAD );
  if (smsAvailable > 0) 
    {
      // Got one!
      char message[ 20 ];

      sms.GetSMS( smsAvailable, remoteNumber, sizeof(remoteNumber), message, sizeof(message) );

      if (strstr_P( message, (const char *) F("Siren ON") ))
        {
          digitalWrite(SirenRelay,HIGH);
        }
      else if (strstr_P( message, (const char *) F("Siren OFF") ))
        {
          digitalWrite(SirenRelay,LOW);
        } 
      else if (strstr_P( message, (const char *) F("Siren Test") ))
        {
          digitalWrite(SirenRelay,LOW);
          digitalWrite(SirenRelay,HIGH);
          delay(1000);
          digitalWrite(SirenRelay,LOW);
          delay(1000);
          digitalWrite(SirenRelay,HIGH);
          delay(1000);
          digitalWrite(SirenRelay,LOW);
          delay(1000);
        }
      else if (strstr_P( message, (const char *) F("TILT") ))
        {
          sms.SendSMS(remoteNumber, "OKAY! Turning TILT it ON Now");
              TILTLOCK = true;
        }         
      else if (strstr_P( message, (const char *) F("C10") ))
        {
          sms.SendSMS("8080", "C10");
        } 
      else if (strstr_P( message, (const char *) F("C15") ))
        {
          sms.SendSMS("8080", "C15");
        } 
      else if (strstr_P( message, (const char *) F("C20") ))
        {
          sms.SendSMS("8080", "C20");
        } 
     else
        {
             sms.SendSMS(remoteNumber, "Wrong Keyword!!!");
            Serial.println("WRONG");
        } 
        
        
      sms.DeleteSMS( smsAvailable );
    }
}// Receiving

void Tilt()
{

pinMode(SirenRelay, OUTPUT);
pinMode(buttonPin, INPUT);

buttonState = digitalRead(buttonPin);
    if (buttonState == HIGH) 
    {
      sms.SendSMS(remoteNumber, "U-Box Opened!");
      digitalWrite(SirenRelay, HIGH);
      Receiving();//so that it still receives message. so that I can still turn the siren off via SMS
    }
  
}// Tilt

please give me pointers on what should I improve on the code. thank you very much.

please give me pointers on what should I improve on the code.

  • Indent your code. You can also press control-T in the IDE editor, and it will auto-format the code for you.

  • Don’t use delay. I’m starting to think you don’t read my posts. -_- This code prevents your sketch from reading GPS data or receiving any other commands:

     else if (strstr_P( message, (const char *) F("Siren Test") ))
        {
          digitalWrite(SirenRelay,LOW);
          digitalWrite(SirenRelay,HIGH);
          delay(1000);
          digitalWrite(SirenRelay,LOW);
          delay(1000);
          digitalWrite(SirenRelay,HIGH);
          delay(1000);
          digitalWrite(SirenRelay,LOW);
          delay(1000);
        }

Nothing else will happen until the test is completed. To avoid this “blocking”, just add a siren flag, a siren count, and a siren timestamp:

    bool     testingSiren = false;
    uint8_t  sirenCount   = 0;
    uint32_t sirenTime    = 0;

… set the variables when you receive the command:

     else if (strstr_P( message, (const char *) F("Siren Test") ))
        {
          digitalWrite(SirenRelay,LOW);
          digitalWrite(SirenRelay,HIGH);
          testingSiren = true;
          sirenCount   = 0
          sirenTime    = millis();
        }

… and check the variables in loop, just like checking GPS and checking SMS:

void loop()
{
  // Check for a command
      ...

  // Check for GPS data
      ...

  // Check for SMS (once every 30 seconds).
      ...

  // Check for siren changes
  if (testingSiren && (millis() - sirenTime >= 1000)) { // 500ms? 250ms?

    // It has been one second, toggle the siren on or off
    digitalWrite( SirenRelay, !digitalRead( SirenRelay ) );

    // Do this a few times (be sure to end on an odd number)
    sirenCount++
    if (sirenCount >= 3) {
      //  All done testing
      testingSiren = false;
    }
  }
} // loop

For some reason, you are checking for an SMS every time through loop. Did you read this comment?

  // Don't constantly check for an SMS, because it takes a long time.
  //    Just check once every 30 seconds.
  
  if (useSMS && ((gpsSeconds - lastSMScheck) > 30)) 
  {
      ...
  }
  Receiving();  // check every time?!?

If you want to check more frequently, that’s ok, but not EVERY time through loop. Just call the Receiving routine, instead of leaving the original code in there:

  // Don't constantly check for an SMS, because it takes a long time.
  //    Just check once every 30 seconds.
  
  if (useSMS && ((gpsSeconds - lastSMScheck) > 30))  // 10? 5?
  {
      Receiving();
  }
  // NO --> Receiving();  <-- delete this line!

You must let loop run over and over, so it can check all the things you need to do. Once in a great while it will do something.

This while loop has the same blocking problem:

      while(TILTLOCK)
      {
        Tilt(); //function to check the status of the tilt switch module
      }

You had to call Receiving from the Tilt function, because this while loop BLOCKS everything else. Instead, just check the flag every time though loop:

      // Check the tilt switch module
      if(TILTLOCK)
      {
         Tilt(); //function to check the status of the tilt switch module
      }

Then your Tilt() function is simpler:

void setup()
{
  pinMode(SirenRelay, OUTPUT);
  pinMode(buttonPin, INPUT);
}

void Tilt()
{
  // Check the tilt switch
  buttonState = digitalRead(buttonPin);

  if (buttonState == HIGH)
  {
    // If it connected, turn the siren on (ONCE)
    if (digitalRead( SirenRelay ) == LOW) // already on?
    {
      digitalWrite(SirenRelay, HIGH);
      sms.SendSMS(remoteNumber, "U-Box Opened!");
    }
  }
  
}// Tilt

Notice that the pinMode calls should be in setup().

You should add a command to turn TILTLOCK off.

-dev:

  • Don't use delay. I'm starting to think you don't read my posts. -_- This code prevents your sketch from reading GPS data or receiving any other commands:

sorry about that sir. I thought that was only applicable for gps that is why I used delay again. also partly due to force of habit. I will correct it now. thank you very much and please don't run out of patience with me. haha

-dev:
Nothing else will happen until the test is completed. To avoid this "blocking", just add a siren flag, a siren count, and a siren timestamp:

    bool     testingSiren = false;

uint8_t  sirenCount  = 0;
    uint32_t sirenTime    = 0;



... set the variables when you receive the command:



else if (strstr_P( message, (const char *) F("Siren Test") ))
        {
          digitalWrite(SirenRelay,LOW);
          digitalWrite(SirenRelay,HIGH);
          testingSiren = true;
          sirenCount  = 0
          sirenTime    = millis();
        }



... and check the variables in `loop`, just like checking GPS and checking SMS:

About the uint8_t sirenCount = 0; and uint32_t sirenTime = 0; should I change the value to something like delay? or leave it as it is? I'm quite unfamilliar with these statements.

Senoyasha:
should I change the value to something like delay?

Seriously?

I guess you didn't read this or Useful Links (esp. General Design section), from my Reply #5. If we take the time to provide a link, it might be worth your time to check them out.