TinyGPS++ for NEO6m GPS and SIM800L using Arduino Nano

Hello, I need help in building a device that in one press of a button, it will give a gps coordinates through SIM800L software serial. I am currently use software serial for SIM800L and hardware serial on pins 0 and 1 Tx and Rx for the NEO6m GPS module. I can get the coordinates of latitude and longitude, however, everytime I try to send the coordinates through the sim, sometimes the values goes back to NMEA sentences, sometimes not. Here is my code:

#include <TinyGPS++.h>
#include <SoftwareSerial.h>

HardwareSerial& gpsSerial = Serial;

int SIM_Tx_Pin = A1;
int SIM_Rx_Pin = A0;

int Emergency_Button = 12;
int Button_Power = 10;
int Reset_Val_Pin = 11;

float latitude;
float longitude;

int Prev_Val = 0;
String Locked_Location;

String SMS = "";

SoftwareSerial SIM_Serial(SIM_Tx_Pin, SIM_Rx_Pin);
TinyGPSPlus gps;

void setup() {

  Serial.begin(9600);

  gpsSerial.begin(9600);
  SIM_Serial.begin(9600);

  pinMode(Button_Power, OUTPUT);
  pinMode(Emergency_Button, INPUT_PULLUP);
  pinMode(Reset_Val_Pin, INPUT_PULLUP);
}

void loop() {
  digitalWrite(Button_Power, LOW);
  int Button_Value = digitalRead(Emergency_Button);
  int Reset_Val = digitalRead(Reset_Val_Pin);

  if (Button_Value == 0 && Prev_Val == 0) {
    Send_SMS_1();
    //Prev_Val = 1;
  }
  if (Reset_Val == 0) {
    Prev_Val = 0;
  }

  GPS_Run();
}

void displayInfo() {
  if (gps.location.isValid()) {

    latitude = gps.location.lat();
    longitude = gps.location.lng();

    Serial.print("Latitude: ");
    Serial.print(gps.location.lat(), 6);
    Serial.print(", Longitude: ");
    Serial.println(gps.location.lng(), 6);

    SMS = "Latitude: " + String(latitude, 6) + ", Longitude: " + String(longitude, 6);

  } else {
    Serial.println("Location: Not Available");
  }
  delay(1000);
}

void GPS_Run() {
  while (gpsSerial.available() > 0) {
    char c = gpsSerial.read();
    if (gps.encode(c)) {
      if (gps.location.isValid()) {
        displayInfo();  // Display the GPS information if valid
      }
    }
  }

  if (millis() > 5000 && gps.charsProcessed() < 10) {
    Serial.println("No GPS detected");
  }
  delay(10);
}

void Send_SMS_1() {
  SIM_Serial.println("AT");  //Once the handshake test is successful, it will back to OK
  updateSerial();
  SIM_Serial.println("AT+CMGF=1");  // Configuring TEXT mode
  updateSerial();
  SIM_Serial.println("AT+CMGS=\"+63**********\"");  //change ZZ with country code and xxxxxxxxxxx with phone number to sms
  updateSerial();

  //SIM_Serial.println("Emergency response needed at coordinates: [latitude/longitude]" + String(latitude, 6) + " " + String(longitude, 6) + ", Assistance required immediately.");
  if (SMS.length() < 38) {
    SIM_Serial.println(SMS);  // Send the constructed SMS message
    updateSerial();
    SIM_Serial.write(26);  // Ctrl+Z to terminate the SMS
  } else {
    Serial.println("SMS is too long, not sent.");  // Inform if SMS is too long
  }
}


void updateSerial() {
  delay(100);
  while (Serial.available()) {
    SIM_Serial.write(Serial.read());  //Forward what Serial received to Software Serial Port
  }
  while (SIM_Serial.available()) {
    Serial.write(SIM_Serial.read());  //Forward what Software Serial received to Serial Port
  }
}

Serial monitor output:

7:56:42.052 -> > $GPRMC,235641.00,A,0813.70628,N,12414.77924,E,1.163,,260424,,,A154,K,A*24

07:56:42.195 -> >H������rb�r����t�b�) �b�r��b��r�bj�56.9,M,,*6E

07:56:42.322 -> > $GPGSA,A,3,01,06,076,,02SMS is too long, not sent.

07:56:43.070 -> ,41,187,23,03,07,205,,04,46,243,*70

07:56:43.117 -> @�AMb�$b��b��b��b���b��b�$GPRMC,235642.00,A,0813.70624,N,12414.77931,E,1.566,,260424,,,A0KA2

07:56:43.215 -> > GGA5.Xb�ѱѢ��*�t4U)��H�Ԩ%�KN��,,,b3,2.77,3.06*04

07:56:43.430 -> > $GPGSV,4,1,13ib��bSMS is too long, not sent.

07:56:44.019 -> �b��b���b��b��b��b���b��b��b��b���b��b�‚b�bt�j

07:56:44.051 -> > $GPGSV,4,4,1303,N,12414.77941,E,1.553,,260424,,,A*77

07:56:44.166 -> > $GPVTG,,T,,M,1.553,N7,1,,6,,,.273lh�b����I��)��&LKKLM�04,lɱ�j�"u�Ib��b��b��b���b��b��b��,27,27,37,03,SMS is too long, not sent.

07:56:45.032 -> 34

07:56:45.032 -> ERROR

07:56:45.032 -> AT+CMGS="+639914069815"

07:56:45.032 -> @AT

07:56:45.032 -> > $GPRMC,235644.00,A,0813.70579,N,12414.77953,E,1.283,,260424,,,A376,K,A*2B

07:56:45.190 -> >H����r��t�r���b�b��b�r��b��r�bj�56.9,M,,*6A

07:56:45.302 -> > $GPGSA,A,3,3,01,06,076,,SMS is too long, not sent.

07:56:46.074 -> 02,41,187,23,03,07,205,,04,46,243,*70@�AY�4,2,13,07,06,325,18$GPRMC,235645.00,A,0813.70566,N,12414.77963,E,1.057,,26042,,,A*58,K,A2$P,34.Xbn�9�����bĉ����S�$�*&&'KK��r��b�r��b�r��R��R$GPGSV,4,1,13,01,07,0,325,19,SMS is too long, not sent.

You only have a two serials - one for GPS and other for SIM800.
But your code is designed as if you have three Serials:

Your Serial and gpsSerial - is the same port:

Do you understand that with the updateSerial() function you sending meaningless chunks of messages from the GPS-receiver to the SIM800 modem and back?
With such an exchange, it’s strange that at least sometimes something works for you.

Thank you for your reply, I figured it's because of the update_serial. It's like to converted NEMA sentences to longitude latitude reverts back to as NEMA. Can this be solved without changing the hardware, just the code?

what if I disable the serial monitor and let the code runs without displaying texts?

You have to be careful when using the hardware serial port (Serial) for both the GPS and the serial monitor.

The Tx line from the GPS should be connected to the Rx of the Nano, with no connection from the Tx of the Nano to the Rx of the GPS. You will not be able to send commands to the GPS, only receive data from the GPS.

You will not be able to receive any data from the serial monitor, but you can send data to be displayed on the serial monitor.

The connection between the GPS and Nano must be disconnected when uploading a sketch.

Be careful of anything in the sketch that can cause long delays. At 9600 baud, the Rx buffer will overflow in about 65mS, which will corrupt the NMEA sentence data if the input is not read often enough and fed into TinyGPS.

1 Like

Thank you for replying to this thread. I have gained new knowledge. Regardin with my problem, I see that if I disconnect RX during while sending an SMS, the code works, but I disconnect it with a jumper. Is there any way to disable RX at some point in the code? like everytime I want to send an SMS, I want RX to stop receiving data from the GPS.

Are you wanting to send an SMS message entered from the serial monitor? If so, you cannot have the GPS connected to the hardware serial port. If all you want is to send the GPS coordinates using SMS, then why are you reading Serial and sending that to the SIM800L?

I was currently trying to monitor if the location is available. But I have tried a solution, everytime I try to send GPS location through SIM, I will execute: gpsSerial.end(), then when I read GPS again, I will gpsSerial.begin(9600), all those inside the loop function. It works. Thank you very much for your replies, I wouldn't be able to do this without your help.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.