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!

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