String sms_data not working if using Google Maps

Greetings!

First things first, I want to make a project where it automatically sends an SMS message if the prototype itself has outreached it's geo-fence. However, whenever I use the code, the message won't register to my phone.

I live in the Philippines (I do not if this information is relevant).

Here are the materials that I am using for this project:
(1) Arduino UNO R3
(1) Gy-Neo6mV2 GPS module
(1) sim800L version 2 GSM module
(2) 3.7V 2200mAh battery
(1) PCB board

Here is the code(not working code):

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

//--------------------------------------------------------------
// Enter your personal phone number to receive SMS alerts.
// Phone number must start with country code.
const String PHONE = "+639295686569"; // Updated phone number
//--------------------------------------------------------------

// GSM Module RX pin to Arduino 10
// GSM Module TX pin to Arduino 11
#define rxPin 11
#define txPin 10
SoftwareSerial sim800l(rxPin, txPin);

// GPS Module RX pin to Arduino 9
// GPS Module TX pin to Arduino 8
AltSoftSerial neogps; // Using AltSoftSerial for GPS
TinyGPSPlus gps;

//--------------------------------------------------------------

// Size of the geo-fence (in meters)
const float maxDistance = 5;

// Initial coordinates (set as your reference point)
float initialLatitude = 9.789219; //in degrees
float initialLongitude = 125.490977; //in degrees

float latitude, longitude;

void getGps(float& latitude, float& longitude);
void sendAlert();  // Function to send SMS when out of geo-fence
float getDistance(float flat1, float flon1, float flat2, float flon2);

void setup() {
    Serial.begin(9600);
    sim800l.begin(9600);
    neogps.begin(9600);

    // Initialize SIM800L
    sim800l.println("AT"); // Check GSM Module
    delay(1000);
    sim800l.println("ATE1"); // Echo ON
    delay(1000);
    sim800l.println("AT+CREG?"); // network status: +CREG: 0,1 or +CREG: 0,5
    delay(1000);
    sim800l.println("AT+CSQ"); // signal strength: +CSQ: 15,99, where 15 is the signal strength, and the second value (99) is the bit error rate.
    delay(1000);
    sim800l.println("AT+CPIN?"); // Check SIM ready
    delay(1000);
    sim800l.println("AT+CMGF=1"); // SMS text mode
    delay(1000);
    sim800l.println("AT+CNMI=1,1,0,0,0"); // Handle newly arrived SMS
    delay(1000);

    delay(20000); // Allow time for initialization
    Serial.println("System Started...");
}

void loop() {
    // Get GPS coordinates
    getGps(latitude, longitude);

    // Calculate the distance from the initial point
    float distance = getDistance(latitude, longitude, initialLatitude, initialLongitude);

    // Debugging output
    Serial.print("Latitude= "); Serial.println(latitude, 6);
    Serial.print("Longitude= "); Serial.println(longitude, 6);
    Serial.print("Initial Latitude= "); Serial.println(initialLatitude, 6);
    Serial.print("Initial Longitude= "); Serial.println(initialLongitude, 6);
    Serial.print("Current Distance= "); Serial.println(distance);

    // If outside geo-fence, send an alert SMS
    if (distance > maxDistance) {
        Serial.println("Outside geo-fence! Preparing to send alert.");
        sendAlert();
        delay(60000); // Delay to avoid spamming alerts; adjust as necessary
    } else {
        Serial.println("Inside geo-fence.");
    }

    // Relay any incoming messages from GSM module to Serial Monitor
    while (sim800l.available()) {
        Serial.println(sim800l.readString());
    }

    // Relay any messages from Serial Monitor to GSM module
    while (Serial.available()) {
        sim800l.println(Serial.readString());
    }
}

// Calculate the distance between two points using Haversine formula
float getDistance(float flat1, float flon1, float flat2, float flon2) {
    float dist_calc = 0;
    float dist_calc2 = 0;

    float diflat = radians(flat2 - flat1); // Conversion of degrees to radians
    flat1 = radians(flat1);
    flat2 = radians(flat2);

    float diflon = radians((flon2) - (flon1));

    dist_calc = (sin(diflat / 2.0) * sin(diflat / 2.0));

    dist_calc2 = cos(flat1) * cos(flat2) * sin(diflon / 2.0) * sin(diflon / 2.0);

    dist_calc += dist_calc2;

    dist_calc = (2 * atan2(sqrt(dist_calc), sqrt(1.0 - dist_calc)));

    dist_calc *= 6371000.0; // Converting to meters

    return dist_calc;
}

// Get GPS data and store in latitude and longitude
void getGps(float& latitude, float& longitude) {
    boolean newData = false;

    // Wait for up to 20 seconds to get new data
    for (unsigned long start = millis(); millis() - start < 20000;) {
        while (neogps.available()) {
            if (gps.encode(neogps.read())) {
                newData = true;
                break;
            }
        }
    }

    if (newData) {
        latitude = gps.location.lat();
        longitude = gps.location.lng();

        // Debug output
        Serial.print("Extracted Latitude: "); Serial.println(latitude, 6);
        Serial.print("Extracted Longitude: "); Serial.println(longitude, 6);
    } else {
        Serial.println("No valid GPS data available.");
        latitude = 0;
        longitude = 0;
    }
}

// Send SMS alert when outside the geo-fence
void sendAlert() {
    // Create the SMS content
    String sms_data = "ALERT! Outside the geo-fence.\n";
    sms_data += "https://maps.google.com/maps?q=loc:"+ String(latitude,6) + "," + String(longitude,6);

    // Debugging: Print the SMS content to the Serial Monitor
    Serial.println("Preparing to send the following SMS content...");
    Serial.println(sms_data);

    // Send the SMS
    sim800l.print("AT+CMGS=\"" + PHONE + "\"\r");
    delay(2000); // Wait for the command to be processed

    sim800l.print(sms_data);
    delay(5000); // Wait for the message to be processed
    sim800l.write(0x1A); // ASCII code for Ctrl-Z to send SMS
    delay(3000); // Wait for the SMS to be sent

    // Debugging: Confirm SMS sent
    Serial.println("SMS Sent Successfully.");
}

here is the 2nd code (the one where it is working):

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

//--------------------------------------------------------------
// Enter your personal phone number to receive SMS alerts.
// Phone number must start with country code.
const String PHONE = "+639295686569"; // Updated phone number
//--------------------------------------------------------------

// GSM Module RX pin to Arduino 10
// GSM Module TX pin to Arduino 11
#define rxPin 11
#define txPin 10
SoftwareSerial sim800l(rxPin, txPin);

// GPS Module RX pin to Arduino 9
// GPS Module TX pin to Arduino 8
AltSoftSerial neogps; // Using AltSoftSerial for GPS
TinyGPSPlus gps;

//--------------------------------------------------------------

// Size of the geo-fence (in meters)
const float maxDistance = 5;

// Initial coordinates (set as your reference point)
float initialLatitude = 9.789219; //in degrees
float initialLongitude = 125.490977; //in degrees

float latitude, longitude;

void getGps(float& latitude, float& longitude);
void sendAlert();  // Function to send SMS when out of geo-fence
float getDistance(float flat1, float flon1, float flat2, float flon2);

void setup() {
    Serial.begin(9600);
    sim800l.begin(9600);
    neogps.begin(9600);

    // Initialize SIM800L
    sim800l.println("AT"); // Check GSM Module
    delay(1000);
    sim800l.println("ATE1"); // Echo ON
    delay(1000);
    sim800l.println("AT+CREG?"); // network status: +CREG: 0,1 or +CREG: 0,5
    delay(1000);
    sim800l.println("AT+CSQ"); // signal strength: +CSQ: 15,99, where 15 is the signal strength, and the second value (99) is the bit error rate.
    delay(1000);
    sim800l.println("AT+CPIN?"); // Check SIM ready
    delay(1000);
    sim800l.println("AT+CMGF=1"); // SMS text mode
    delay(1000);
    sim800l.println("AT+CNMI=1,1,0,0,0"); // Handle newly arrived SMS
    delay(1000);

    delay(20000); // Allow time for initialization
    Serial.println("System Started...");
}

void loop() {
    // Get GPS coordinates
    getGps(latitude, longitude);

    // Calculate the distance from the initial point
    float distance = getDistance(latitude, longitude, initialLatitude, initialLongitude);

    // Debugging output
    Serial.print("Latitude= "); Serial.println(latitude, 6);
    Serial.print("Longitude= "); Serial.println(longitude, 6);
    Serial.print("Initial Latitude= "); Serial.println(initialLatitude, 6);
    Serial.print("Initial Longitude= "); Serial.println(initialLongitude, 6);
    Serial.print("Current Distance= "); Serial.println(distance);

    // If outside geo-fence, send an alert SMS
    if (distance > maxDistance) {
        Serial.println("Outside geo-fence! Preparing to send alert.");
        sendAlert();
        delay(60000); // Delay to avoid spamming alerts; adjust as necessary
    } else {
        Serial.println("Inside geo-fence.");
    }

    // Relay any incoming messages from GSM module to Serial Monitor
    while (sim800l.available()) {
        Serial.println(sim800l.readString());
    }

    // Relay any messages from Serial Monitor to GSM module
    while (Serial.available()) {
        sim800l.println(Serial.readString());
    }
}

// Calculate the distance between two points using Haversine formula
float getDistance(float flat1, float flon1, float flat2, float flon2) {
    float dist_calc = 0;
    float dist_calc2 = 0;

    float diflat = radians(flat2 - flat1); // Conversion of degrees to radians
    flat1 = radians(flat1);
    flat2 = radians(flat2);

    float diflon = radians((flon2) - (flon1));

    dist_calc = (sin(diflat / 2.0) * sin(diflat / 2.0));

    dist_calc2 = cos(flat1) * cos(flat2) * sin(diflon / 2.0) * sin(diflon / 2.0);

    dist_calc += dist_calc2;

    dist_calc = (2 * atan2(sqrt(dist_calc), sqrt(1.0 - dist_calc)));

    dist_calc *= 6371000.0; // Converting to meters

    return dist_calc;
}

// Get GPS data and store in latitude and longitude
void getGps(float& latitude, float& longitude) {
    boolean newData = false;

    // Wait for up to 20 seconds to get new data
    for (unsigned long start = millis(); millis() - start < 20000;) {
        while (neogps.available()) {
            if (gps.encode(neogps.read())) {
                newData = true;
                break;
            }
        }
    }

    if (newData) {
        latitude = gps.location.lat();
        longitude = gps.location.lng();

        // Debug output
        Serial.print("Extracted Latitude: "); Serial.println(latitude, 6);
        Serial.print("Extracted Longitude: "); Serial.println(longitude, 6);
    } else {
        Serial.println("No valid GPS data available.");
        latitude = 0;
        longitude = 0;
    }
}

// Send SMS alert when outside the geo-fence
void sendAlert() {
    // Create the SMS content
    String sms_data = "ALERT! Outside the geo-fence.\n";

    // Debugging: Print the SMS content to the Serial Monitor
    Serial.println("Preparing to send the following SMS content...");
    Serial.println(sms_data);

    // Send the SMS
    sim800l.print("AT+CMGS=\"" + PHONE + "\"\r");
    delay(2000); // Wait for the command to be processed

    sim800l.print(sms_data);
    delay(5000); // Wait for the message to be processed
    sim800l.write(0x1A); // ASCII code for Ctrl-Z to send SMS
    delay(3000); // Wait for the SMS to be sent

    // Debugging: Confirm SMS sent
    Serial.println("SMS Sent Successfully.");
}

Here is the function that ruined the first code,
sms_data += "https://maps.google.com/maps?q=loc:"+ String(latitude,6) + "," + String(longitude,6);

I know that this particular code is the problem as to why my prototype won't work because I have tested both codes and the second code is working fine while the first code won't work.

Please help me! What should I do?

I'd guess it's not maps.google.com specifically.

Total length? You can test this by replacing every not-a-letter-or-number character, including the \n, with a space. If that doesn't work, reduce the length until it does.

If replacing all the punctuation works, then start putting them back. Maybe it's reacting to an URL.

It might be a memory problem.
Using a GPS and GSM is too much for small Uno, especially taking in account that you don't even try to reduce memory consumption.

Please show a memory using message, that Arduino IDE prints after compilation.

Try to put all constant text messages into F() macro:

Thank you! Let me try this, please reply if I have update okay? okay!

what do you mean by total length? sorry I'm actually a beginner!

bro i don't get what you mean? :sob: :sob: can you try to explain it to me in a step-by-step process on how should I do it?

I tried it, kenb4. But the message was not sent to my phone.

Here's what it said in the serial monitor:

System Started...

Extracted Latitude: 9.789048

Extracted Longitude: 125.490760

Latitude= 9.789048

Longitude= 125.490760

Initial Latitude= 9.789219

Initial Longitude= 125.490974

Current Distance= 30.20

Outside geo-fence! Preparing to send alert.

Preparing to send the following SMS content...

ALERT OUTSIDE GEOFENCE https://maps.google.com/9.789047,125.490760

SMS Sent Successfully.

System Started...

Extracted Latitude: 9.789030

Extracted Longitude: 125.490753

Latitude= 9.789030

Longitude= 125.490753

but it didn't register?

ALERT OUTSIDE GEOFENCE

is 22 characters, and that works?

ALERT OUTSIDE GEOFENCE https://maps.google.com/9.789047,125.490760

is 66 characters. Does

ALERT OUTSIDE GEOFENCEALERT OUTSIDE GEOFENCEALERT OUTSIDE GEOFENCE

which is also 66 characters work?

  • if yes, then there is apparently some kind of filtering going on. The SMS system doesn't like what looks like an URL
  • if not, then 66 might be too long. You can try shorter strings to find the limit.
http://maps.google.com

is also 22 characters with http instead of https. Does that work?

thank you for replying to my questions, Kenb4. However, I have decided to stick with non-URL messages and instead of google maps, I used string latitude and longitude instead.

That way, I can still know where my subject currently is. (But the downside is that I have to manually put the extracted coordinates to my google maps) but hey, it works.

Thank you once again, KenB4!