Search code examples
arduinogpsgsm

Sending GPS location via GSM module


I am using a SIM900A GSM module and a NEO-6m GPS module. I want to send the location via the GSM module when the GSM module receives a message.

My code is working when I am receiving and sending any message with the help of the GSM module, but it is not working when I join the two, i.e. GPS and GSM modules.

Here is my code for the two.

#include <SoftwareSerial.h>
// GPS
#include <TinyGPS.h>

// GSM
SoftwareSerial SIM900A(9, 10);
SoftwareSerial mySerial(5, 6);
TinyGPS gps;

void setup() {
  Serial.begin(9600);
  SIM900A.begin(9600);
  SIM900A.println("AT+CNMI=2,2,0,0,0");
  mySerial.begin(9600);
  delay(1000);
}

void loop() {
  bool newdata = false;
  String buffer = readSIM900A();
  if(SIM900A.available() > 0)
    Serial.println(SIM900A.read());
  if (buffer.startsWith("\r\n+CMT: ")) {
    // printing the number
    Serial.println(buffer.substring(9, 22));
    // Remove first 51 characters
    // buffer.remove(0, 51);
    int len = buffer.length();
    // printing message
    Serial.println(buffer.substring(51, len-2));
    if (buffer.substring(51, len-2) == "location") {
      Serial.println("Sending location");
      // GPS
      if (mySerial.available()) {
        char c = mySerial.read();
        if (gps.encode(c)) {
          newdata = true;
        }
      }
      if (newdata) {
        long int lat, lon;
        unsigned long age, age1, date, time, chars;
        gps.get_position(&lat, &lon, &age);
        gps.get_datetime(&date, &time, &age);
        Serial.print("Lat/Long(10^-5 deg): ");
        Serial.print(lat);
        Serial.print(", ");
        Serial.print(lon); 
        Serial.print(" Fix age: "); 
        Serial.print(age); Serial.println("ms.");
        Serial.print("Date(ddmmyy): "); Serial.print(date);
        Serial.print(" Time(hhmmsscc): ");
        Serial.print(time);
        Serial.print(" Fix age: "); Serial.print(age); 
        Serial.println("ms.");
        Serial.print("Alt(cm): "); Serial.print(gps.altitude());
        Serial.print(" Speed(mps): "); Serial.print(gps.f_speed_mps());
        // setting GSM module
        SIM900A.println("AT+CMGF=1"); //Sets the GSM Module in Text Mode
        delay(1000); // Delay of 1000 milli seconds or 1 second
        // sending location from which code word had come
        SIM900A.println("AT+CMGS=\"" + buffer.substring(9, 22) + "\"\r");
        // Replace x with mobile number
        Serial.println("AT+CMGS=\"" + buffer.substring(9, 22) + "\"\r");
        delay(1000);
        SIM900A.print("Lat/Long(10^-5 deg): ");
        SIM900A.print(lat);
        SIM900A.print(", ");
        SIM900A.print(lon); 
        SIM900A.print(" Fix age: "); 
        SIM900A.print(age); SIM900A.println("ms.");
        SIM900A.print("Date(ddmmyy): "); SIM900A.print(date);
        SIM900A.print(" Time(hhmmsscc): ");
        SIM900A.print(time);
        SIM900A.print(" Fix age: "); SIM900A.print(age); 
        SIM900A.println("ms.");
        SIM900A.print("Alt(cm): "); SIM900A.print(gps.altitude());
        SIM900A.print(" Speed(mps): "); SIM900A.print(gps.f_speed_mps());
        SIM900A.println((char)26);// ASCII code of CTRL+Z
        delay(1000);
      }
    }
  }
  delay(100);
}

String readSIM900A() {
  String buffer;
  while (SIM900A.available()) {
    char c = SIM900A.read();
    buffer.concat(c);
    delay(10);
  }
  return buffer;
}

Above is my final code when the GPS and GSM modules are handled together. They are working totally fine when they are handled separately.

Connections:

Connected Tx, Rx pin of SIM900A to 9, 10 of Arduino Nano respectively, and Tx, Rx of GPS module to 5, 6 respectively. And I also made ground common with Arduino.


Solution

  • #include <NeoSWSerial.h>
    //#include <SoftwareSerial.h>
    #include <AltSoftSerial.h>
    // GPS
    #include <TinyGPS.h>
    
    // GSM
    static const int RXPin = 8, TXPin = 9;
    AltSoftSerial SIM900A(RXPin, TXPin);
    
    NeoSWSerial mySerial(5, 6);
    TinyGPS gps;
    
    void setup()
    {
    Serial.begin(9600);
    SIM900A.begin(9600);
    SIM900A.println("AT+CNMI=2,2,0,0,0");
    mySerial.begin(9600);
    delay(1000);
    }
    
    void loop()
    {
    bool newdata = false;
    String buffer = readSIM900A();
    if(SIM900A.available() > 0)
      Serial.println(SIM900A.read());
    if (buffer.startsWith("\r\n+CMT: "))
    {
        // printing the number
        Serial.println(buffer.substring(9, 22)); 
    
        // Remove first 51 characters
        // buffer.remove(0, 51);
        int len = buffer.length();
        // Remove \r\n from tail
        // buffer.remove(len - 2, 2);
        // printing message
        Serial.println(buffer.substring(51, len-2));
        if (buffer.substring(51, len-2) == "location")
        {
          Serial.println("Sending location");
    
          // GPS
          if (mySerial.available()) 
          {
             char c = mySerial.read();
             if (gps.encode(c)) 
             {
                newdata = true;
             }
          }
          if (newdata)
          {
            long int lat, lon;
            unsigned long age, age1, date, time, chars;
    
            gps.get_position(&lat, &lon, &age);
            gps.get_datetime(&date, &time, &age);
            Serial.print("Lat/Long(10^-5 deg): ");
            Serial.print(lat);
            Serial.print(", ");
            Serial.print(lon); 
            Serial.print(" Fix age: "); 
            Serial.print(age); Serial.println("ms.");
    
            Serial.print("Date(ddmmyy): "); Serial.print(date); Serial.print(" 
            Time(hhmmsscc): ");
            Serial.print(time);
            Serial.print(" Fix age: "); Serial.print(age); 
            Serial.println("ms.");
    
            Serial.print("Alt(cm): "); Serial.print(gps.altitude());
            Serial.print(" Speed(mps): "); Serial.print(gps.f_speed_mps());
    
            // setting GSM module
            SIM900A.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
            delay(1000);  // Delay of 1000 milli seconds or 1 second
            // sending location from which code word had come
            SIM900A.println("AT+CMGS=\"" + buffer.substring(9, 22) + "\"\r"); // 
             Replace x with mobile number
            Serial.println("AT+CMGS=\"" + buffer.substring(9, 22) + "\"\r");
            delay(1000);
    
            SIM900A.print("Lat/Long(10^-5 deg): ");
            SIM900A.print(lat);
            SIM900A.print(", ");
            SIM900A.print(lon); 
            SIM900A.print(" Fix age: "); 
            SIM900A.print(age); SIM900A.println("ms.");
    
            SIM900A.print("Date(ddmmyy): "); SIM900A.print(date); 
            SIM900A.print(" Time(hhmmsscc): ");
            SIM900A.print(time);
            SIM900A.print(" Fix age: "); SIM900A.print(age); 
            SIM900A.println("ms.");
    
            SIM900A.print("Alt(cm): "); SIM900A.print(gps.altitude());
            SIM900A.print(" Speed(mps): "); SIM900A.print(gps.f_speed_mps());
    
            SIM900A.println((char)26);// ASCII code of CTRL+Z
            delay(1000);
          }
        }
        }
        delay(100);
       }
    
     String readSIM900A()
    {
    String buffer;
    
    while (SIM900A.available())
    {
        char c = SIM900A.read();
        buffer.concat(c);
        delay(10);
    }
    
    return buffer;
    }
    

    P.S : I have changed the pins for GSM and rest part is same. Except adding AltSoftSerial it is a library same as SoftwareSerial (Download it from manage libraries and it requires pins 8 and 9). Don't change pin number in sketch change the connections.