A9G Code Assist. Please

I'm using the A9G Pudding module with an Arduino Nano controller. I'm just trying to get this to reply to an SMS request for "Location" with a Google Maps link. My wiring is simple, TX-RX/RX-TX between modules, & my Nano is supplying the 5V to the A9G. I can't get this to reply with a Google Maps link. I'm not the best at coding, so I'm guessing the issue is there. Any help pointing out what I might be missing is appreciated. Thanx.

#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>

static const int RXPin = 6, TXPin = 5;
String s = "www.google.com/maps?q=";
String phoneNumber = "";

static const uint32_t GPSBaud = 115200;

const size_t BUFSIZE = 300;
char f_buffer[BUFSIZE];
float *f_buf = (float*)f_buffer;

TinyGPSPlus gps;// The TinyGPSPlus object
SoftwareSerial ss(RXPin, TXPin);// The serial connection to the GPS device

void setup() {
  Serial.begin(115200);
  ss.begin(GPSBaud);

  Serial.println("Starting...");
  ss.println("\r");
  ss.println("AT\r");
  delay(10);

  ss.println("\r");
  ss.println("AT+GPS=1\r");

  delay(100);
  ss.println("AT+CREG=2\r");
  delay(6000);

  ss.println("AT+CGATT=1\r");
  delay(6000);

  ss.println("AT+CGDCONT=1,\"IP\",\"Mobilenet\"\r");
  delay(6000);

  ss.println("AT+CGACT=1,1\r");
  delay(6000);

  ss.println("\r");
  ss.println("AT+GPS=1\r");
  delay(1000);

  ss.println("AT+GPSRD=10\r");
  delay(100);

  ss.println("AT+CMGF=1\r");
  delay(1000);

  ss.println("AT+CNMI=2,2,0,0,0\r");
  delay(1000);

  Serial.println("Setup Executed");
}

void loop() {
  if (ss.available()) {
    String incomingMessage = ss.readString();
    if (incomingMessage.indexOf("Location") != -1) {
      phoneNumber = get_phone_number(incomingMessage);
      send_gps_data(phoneNumber);
    }
  }

  smartDelay(2000);

  if (millis() > 5000 && gps.charsProcessed() < 10) {
    Serial.println(F("No GPS data received: check wiring"));
  }
}

static void smartDelay(unsigned long ms) {
  unsigned long start = millis();
  do {
    while (ss.available()) {
      gps.encode(ss.read());
    }
  } while (millis() - start < ms);
}

String get_phone_number(String message) {
  int start = message.indexOf("\"") + 1;
  int end = message.indexOf("\"", start);
  String phoneNumber = message.substring(start, end);
  return phoneNumber;
}

void send_gps_data(String phoneNumber) {
  if (gps.location.lat() == 0 || gps.location.lng() == 0) {
    Serial.println("Return Executed");
    return;
  }

  Serial.print("Latitude (deg): ");
  f_buf[0] = gps.location.lat();
  Serial.println(f_buf[0]);

  Serial.print("Longitude (deg): ");
  f_buf[1] = gps.location.lng();
  Serial.println(f_buf[1]);

  s = "www.google.com/maps?q=" + String(gps.location.lat(), 6) + "," + String(gps.location.lng(), 6);

  Serial.println(s);

  ss.println("AT+CMGF=1\r");
  delay(1000);

  ss.print("AT+CMGS=\"+" + phoneNumber + "\"\r");
  delay(1000);

  ss.print(s);
  ss.write(0x1A);
  delay(1000);
   }
  

What parts work?

Using blind delays is not very robust. I recommend reading the actual response to each request. Maybe the "SendShortComand()" function from this example will help. It uses "WaitForResponse()" to check if the response is "OK" or "ERROR".

#include <SoftwareSerial.h>

SoftwareSerial ATCommandStream(2, 3);
unsigned long ATComandBaudRate = 19200;

const char * DestinationNumber = "+639358861057";
const char * SMSMessage = "Test Message";

void setup()
{
  // start the serial communication with the host computer
  Serial.begin(115200);
  while (!Serial);
  delay(200);
  Serial.println("Sketch started.");

  ATCommandStream.begin(ATComandBaudRate);
  Serial.print("ATCommandStream started at baud rate ");
  Serial.println(ATComandBaudRate);

  // Turn on verbose messages
  SendShortCommand("AT+CMEE");

  // Set character set to GSM:
  SendShortCommand("AT+CSCS=\"GSM\"");

  // Set the SMS output to text mode
  SendShortCommand("AT+CMGF=1");

  // Check the phone number type
  SendShortCommand("AT+CSTA?");
  Serial.println("Note: 129=Unknown, 161=National, 145=International, 177=Network Specific");

  // Test for CMGS command support:
  SendShortCommand("AT+CMGS=?");

  SendSMSMessage(DestinationNumber, SMSMessage);

  SendShortCommand("AT"); // Just checking that it responds with OK
}

void loop() {}

bool WaitForResponse()
{
  unsigned long startTime = millis();
  while (millis() - startTime < 5000)
  {
    String reply = ATCommandStream.readStringUntil('\n');
    if (reply.length() > 0)
    {
      Serial.print("Received: \"");
      Serial.print(reply);
      Serial.println("\"");

      if (reply.startsWith("OK"))
        return true;
        
      if (reply.startsWith("ERROR"))
        return false;
    }
  }
  Serial.println("Did not receive OK.");
  return false;
}

bool SendShortCommand(String command)
{
  Serial.print("Sending command: \"");
  Serial.print(command);
  Serial.println("\"");

  ATCommandStream.print(command);
  ATCommandStream.print("\r\n");

  return WaitForResponse();
}

void SendSMSMessage(const char *number, const char *message)
{
  Serial.println("Sending SMS text");

  Serial.print("Sending: ");
  Serial.print("AT+CMGS=\"");
  Serial.print(number);
  Serial.println("\"(CR)");
  Serial.print(message); // The SMS text you want to send
  Serial.println("(EM)");

  ATCommandStream.print("AT+CMGS=\"");  // Send SMS
  ATCommandStream.print(number);
  ATCommandStream.print("\"\r"); // NOTE: Command ends with CR, not CRLF
  ATCommandStream.print(message); // The SMS text you want to send
  ATCommandStream.write(26); // ASCII EndMessage (EM) CTRL+Z character

  WaitForResponse();
}

Thank you. I’ll try this and let you know the results. Stay tuned.

So your revision worked to send me a text that read "Test Message". This at least shows me that theSMS function is working. How can I alter this to send a google maps link when anyone sends an SMS request, "Location"?

The first step is receiving the "Location" message. Does that work in your existing code?

To send a google map link, put it as the second argument to SendSMSMessage().

I’m wondering if that’s my problem. As I said, I’m not that good at the coding part of this. Still learning. I’m trying to make it so that anyone can send the “Location” request and receive the link. Is that a thing that can be done, or do I have to designate a target phone number? I basically copy/pasted your code to try it. I put in my phone number and when it got through its start Up, I received a text saying “Test Message”. I’m leaving this as I go, so I’m kinda grasping at straws here. I did a test run with some sample code I found on the internet, where it basically sends the maps link after “data _counter >= 10”. That just proved its functionality. Tried to alter that to my needs, but that’s where it started going off the rails.

ok, I've altered my code to show me some data on the serial monitor. I can see that everything's checking out as "OK". I sent an SMS request, watched it receive it, but then saw an "SMSFULL" error. I then added some instruction to check and delete all messages when it was full, to free up space. Now Im seeing this on the serial monitor, All SMS messages deleted.
(AT+CPMS?
+CPMS: "SM",0,40,"SM",0,40,"ME",50,50)
As far as I can tell, that's the SIM Main memory. I still seem to be getting a +CEIV: "SMSFULL",2 when I send the request text. I'm definitely learning a lot. It just seems to be what not to do. Here's a cut of my latest code. See what you can make out of it. I used your delay idea. That seemed to help a lot. With exception of the phone number in both the setup and loop, nothing else is altered in the running code.



#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>

static const int RXPin = 4, TXPin = 3;
String s = "www.google.com/maps?q=";
String phoneNumber = "+XXXXXXXX"; // Replace with the phone number you want to send SMS to

static const uint32_t GPSBaud = 115200;

const size_t BUFSIZE = 300;
char f_buffer[BUFSIZE];
float *f_buf = (float*)f_buffer;

TinyGPSPlus gps; // The TinyGPSPlus object
SoftwareSerial ss(RXPin, TXPin); // The serial connection to the GPS device

void setup() {
  Serial.begin(115200);
  ss.begin(GPSBaud);

  Serial.println("Starting...");
  

  WaitForResponse("AT\r");

  WaitForResponse("AT+GPS=1\r");

  WaitForResponse("AT+CREG=2\r");

  WaitForResponse("AT+CGATT=1\r");

  WaitForResponse("AT+CGDCONT=1,\"IP\",\"mobilenet\"\r");

  WaitForResponse("AT+CGACT=1,1\r");

  WaitForResponse("AT+GPS=1\r");

  WaitForResponse("AT+GPSRD=10\r");

  WaitForResponse("AT+CMGF=1\r");

  WaitForResponse("AT+CNMI=2,2,0,0,0\r");

  WaitForResponse("AT+CMGD=1,4\r");

  delay(1000);

  Serial.println("Setup Executed");
}

void loop() {
  bool responseReceived = WaitForResponse("AT+GPSRD=10\r");
  if (!responseReceived) {
    Serial.println("No response received from GPS device.");
  }
  delay(5000); // wait 5 seconds before sending the next command

  // Check SMS memory usage
  String memInfo = "";
  WaitForResponse("AT+CPMS?\r");
  while (ss.available()) {
    memInfo += ss.readString();
  }
  Serial.println("SMS Memory Info: " + memInfo);
  int used = memInfo.substring(memInfo.indexOf("\"SM\"")+5, memInfo.indexOf(",", memInfo.indexOf("\"SM\""))).toInt();
  int total = memInfo.substring(memInfo.indexOf("\"SM\"")+1, memInfo.indexOf(",", memInfo.indexOf("\"SM\""))).toInt();

  while (used == total) {
    // Delete oldest SMS message
    WaitForResponse("AT+CMGD=1,4\r");
    Serial.println("All SMS messages deleted.");

    // Update memory usage
    memInfo = "";
    WaitForResponse("AT+CPMS?\r");
    while (ss.available()) {
      memInfo += ss.readString();
    }
    Serial.println("SMS Memory Info: " + memInfo);
    used = memInfo.substring(memInfo.indexOf("\"SM\"")+5, memInfo.indexOf(",", memInfo.indexOf("\"SM\""))).toInt();
    total = memInfo.substring(memInfo.indexOf("\"SM\"")+1, memInfo.indexOf(",", memInfo.indexOf("\"SM\""))).toInt();
  }

  send_gps_data(phoneNumber);
}

bool WaitForResponse(String command) {
  ss.println(command);

  unsigned long start = millis();
  while (millis() - start < 10000) { // wait up to 10 seconds for response
    if (ss.available()) {
      String incomingMessage = ss.readString();
      Serial.println(incomingMessage);
      return true; // response received
    }
  }

  Serial.println("No response received for command: " + command);
  return false; // no response received
}

static void smartDelay(unsigned long ms) {
  unsigned long start = millis();
  do {
    while (ss.available()) {
      gps.encode(ss.read());
    }
  } while (millis() - start < ms);
}

String get_phone_number(String message) {
  int start = message.indexOf("\"") + 1;
  int end = message.indexOf("\"", start);
  String phoneNumber = message.substring(start, end);
  return phoneNumber;
}

void send_gps_data(String phoneNumber) {
  if (gps.location.lat() == 0 || gps.location.lng() == 
 0) {
    Serial.println("Return Executed");
    return;
  }

  Serial.print("Latitude (deg): ");
  f_buf[0] = gps.location.lat();
  Serial.println(f_buf[0]);

  Serial.print("Longitude (deg): ");
  f_buf[1] = gps.location.lng();
  Serial.println(f_buf[1]);

  s = "www.google.com/maps?q=" + String(gps.location.lat(), 6) + "," + String(gps.location.lng(), 6);

  Serial.println(s);

  ss.println("AT+CMGF=1\r");

  delay(1000);

 
  ss.print("AT+CMGS=\"+xxxxxxxxxxx\"\r");
  delay(1000);

  ss.print(s);
  ss.write(0x1A);
  delay(1000);
}

No need for the 'while'. ss.readString() will read until nothing has arrived for one second.

I will get rid of the highlighted portion. Also, I found a flaw in the above code. I guess I've altered it so much, I accidentally deleted the portion that tells it to listen for SMS "Location" and reply with the google maps link. Here's and update, to include your revision. Still not going to hold my breath.

type or#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>

static const int RXPin = 4, TXPin = 3;
String s = "www.google.com/maps?q=";
String phoneNumber = "+1xxxxxxxxxx"; // Replace with the phone number you want to send SMS to

static const uint32_t GPSBaud = 115200;

const size_t BUFSIZE = 300;
char f_buffer[BUFSIZE];
float *f_buf = (float*)f_buffer;

TinyGPSPlus gps; // The TinyGPSPlus object
SoftwareSerial ss(RXPin, TXPin); // The serial connection to the GPS device

void setup() {
  Serial.begin(115200);
  ss.begin(GPSBaud);

  Serial.println("Starting...");
  

  WaitForResponse("AT\r");

  WaitForResponse("AT+GPS=1\r");

  WaitForResponse("AT+CREG=2\r");

  WaitForResponse("AT+CGATT=1\r");

  WaitForResponse("AT+CGDCONT=1,\"IP\",\"mobilenet\"\r");

  WaitForResponse("AT+CGACT=1,1\r");

  WaitForResponse("AT+GPS=1\r");

  WaitForResponse("AT+GPSRD=10\r");

  WaitForResponse("AT+CMGF=1\r");

  WaitForResponse("AT+CNMI=2,2,0,0,0\r");

  WaitForResponse("AT+CMGD=1,4\r");

  delay(1000);

  Serial.println("Setup Executed");
}

void loop() {
  bool responseReceived = WaitForResponse("AT+GPSRD=10\r");
  if (!responseReceived) {
    Serial.println("No response received from GPS device.");
  }
  delay(5000); // wait 5 seconds before sending the next command

  // Check SMS memory usage
  String memInfo = "";
  WaitForResponse("AT+CPMS?\r");
  
  
  Serial.println("SMS Memory Info: " + memInfo);
  int used = memInfo.substring(memInfo.indexOf("\"SM\"")+5, memInfo.indexOf(",", memInfo.indexOf("\"SM\""))).toInt();
  int total = memInfo.substring(memInfo.indexOf("\"SM\"")+1, memInfo.indexOf(",", memInfo.indexOf("\"SM\""))).toInt();

  while (used == total) {
    // Delete oldest SMS message
    WaitForResponse("AT+CMGD=1,4\r");
    Serial.println("All SMS messages deleted.");

    // Update memory usage
    memInfo = "";
    WaitForResponse("AT+CPMS?\r");
    while (ss.available()) {
      memInfo += ss.readString();
    }
    Serial.println("SMS Memory Info: " + memInfo);
    used = memInfo.substring(memInfo.indexOf("\"SM\"")+5, memInfo.indexOf(",", memInfo.indexOf("\"SM\""))).toInt();
    total = memInfo.substring(memInfo.indexOf("\"SM\"")+1, memInfo.indexOf(",", memInfo.indexOf("\"SM\""))).toInt();
  }

  send_gps_data(phoneNumber);
}

bool WaitForResponse(String command) {
  ss.println(command);

  unsigned long start = millis();
  while (millis() - start < 10000) { // wait up to 10 seconds for response
    if (ss.available()) {
      String incomingMessage = ss.readString();
      Serial.println(incomingMessage);
      return true; // response received
    }
  }

  Serial.println("No response received for command: " + command);
  return false; // no response received
}

static void smartDelay(unsigned long ms) {
  unsigned long start = millis();
  do {
    while (ss.available()) {
      gps.encode(ss.read());
    }
  } while (millis() - start < ms);
}

String get_phone_number(String message) {
  int start = message.indexOf("\"") + 1;
  int end = message.indexOf("\"", start);
  String phoneNumber = message.substring(start, end);
  return phoneNumber;
}

void send_gps_data(String phoneNumber) {
  if (gps.location.lat() == 0 || gps.location.lng() == 
 0) {
    Serial.println("Return Executed");
    return;
  }

  Serial.print("Latitude (deg): ");
  f_buf[0] = gps.location.lat();
  Serial.println(f_buf[0]);

  Serial.print("Longitude (deg): ");
  f_buf[1] = gps.location.lng();
  Serial.println(f_buf[1]);

  // Check for incoming SMS message
  if (ss.available()) {
    String incomingMessage = ss.readString();
    if (incomingMessage.indexOf("Location") != -1) {
      s = "www.google.com/maps?q=" + String(gps.location.lat(), 6) + "," + String(gps.location.lng(), 6);
      
      Serial.println(s);
      
      ss.println("AT+CMGF=1\r");
      delay(1000);

      ss.print("AT+CMGS=\"+1xxxxxxxxxx\"\r");
      delay(1000);

      ss.print(s);
      ss.write(0x1A);
      delay(1000);
    }
  }
} paste code here

I'm still getting these errors when I send the "Location" request.:

+CIEV: "SMSFULL",2

+CPMS: "SL",0,40,"SM",0,40,"ME",50,50

It looks like your attempt to free up space did not work. What response are you getting from the command that deletes SMS messages?

it keeps looping "All SMS messages deleted." But i'm also seeing this in the data loop. According to the manual and other sources, those are the SIM storage locations. So, "SL" and "SM" are cleared, but not "ME". I'm pulling my hair out. I feel like this should be WAY easier than it's become. I'm looking at other example code that does a lot more than what I'm asking for and none of it seems this involved. I'm just asking for a google maps link to be sent when i SMS the word "Location" to the SIM's phone number.

+CPMS: "SL",0,40,"SM",0,40,"ME",50,50

I'm also getting "SMSFULL",2 when I send the text.

OK! Here's another revision. I've added parsing and some other elements that allow me to see more in the serial monitor. I've also told it what storage spot to use, so I can control deletion of the SMS storage when it gets full. I can see that, upon startup, everything's checking out "OK". I can see 1 GPS coordinate printed. I can see that it's received my text and read it, but I still never receive the Google maps link. See code below. I'll also add a snip if the serial monitor display.

//#include <TinyGPS++.h>//
#include <TinyGPSPlus.h>

#include <SoftwareSerial.h>

static const int RXPin = 4, TXPin = 3;
String s = "www.google.com/maps?q=";
String phoneNumber = "+19189556860"; // Replace with the phone number you want to send SMS to

static const uint32_t GPSBaud = 115200;

const size_t BUFSIZE = 300;
char f_buffer[BUFSIZE];
float *f_buf = (float*)f_buffer;

TinyGPSPlus gps; // The TinyGPSPlus object
SoftwareSerial ss(RXPin, TXPin); // The serial connection to the GPS device

void setup() {
  Serial.begin(115200);
  ss.begin(GPSBaud);

  Serial.println("Starting...");
  
  String response;

  WaitForResponse("AT\r", response);

  WaitForResponse("AT+GPS=1\r", response);

  WaitForResponse("AT+CREG=2\r", response);

  WaitForResponse("AT+CGATT=1\r", response);

  WaitForResponse("AT+CGDCONT=1,\"IP\",\"mobilenet\"\r", response);

  WaitForResponse("AT+CGACT=1,1\r", response);

  WaitForResponse("AT+GPS=1\r", response);

  WaitForResponse("AT+GPSRD=10\r", response);

  WaitForResponse("AT+CPMS=\"SM\",\"SM\",\"SM\"\r", response);
  
  WaitForResponse("AT+CMGF=1\r", response);

  WaitForResponse("AT+CNMI=2,2,0,0,0\r", response);
  
  WaitForResponse("AT+CMGD=1,1\r", response);

 // WaitForResponse("AT+LOCATION=1\r", response);//

  WaitForResponse("AT+LOCATION=2\r", response);

  delay(1000);

  Serial.println("Setup Executed");
}

void loop() {
  String response;
  bool responseReceived = WaitForResponse("AT+GPSRD=10\r", response);
  if (!responseReceived) {
    Serial.println("No response received from GPS device.");
  }
  delay(5000); // wait 5 seconds before sending the next command

  // Check SMS memory usage
  String memInfo = "";
  WaitForResponse("AT+CPMS?\r", memInfo);
  Serial.println("SMS Memory Info: " + memInfo);

  int usedSM = memInfo.substring(memInfo.indexOf("\"SM\"")+5, memInfo.indexOf(",", memInfo.indexOf("\"SM\""))).toInt();
  int totalSM = memInfo.substring(memInfo.indexOf("\"SM\"")+1, memInfo.indexOf(",", memInfo.indexOf("\"SM\""))).toInt();

  int usedME = memInfo.substring(memInfo.indexOf("\"ME\"")+5, memInfo.lastIndexOf(",")).toInt();
  int totalME = memInfo.substring(memInfo.indexOf("\"ME\"")+1, memInfo.lastIndexOf(",")).toInt();

  while (usedSM == totalSM && usedME == totalME) {
    // Delete oldest SMS message
    WaitForResponse("AT+CMGD=1,1\r", response);
    Serial.println("All SMS messages deleted.");
    
    // Update SMS memory usage
    WaitForResponse("AT+CPMS?\r", memInfo);
    Serial.println("SMS Memory Info: " + memInfo);
    usedSM = memInfo.substring(memInfo.indexOf("\"SM\"")+5, memInfo.indexOf(",", memInfo.indexOf("\"SM\""))).toInt();
    totalSM = memInfo.substring(memInfo.indexOf("\"SM\"")+1, memInfo.indexOf(",", memInfo.indexOf("\"SM\""))).toInt();
    usedME = memInfo.substring(memInfo.indexOf("\"ME\"")+5, memInfo.lastIndexOf(",")).toInt();
    totalME = memInfo.substring(memInfo.indexOf("\"ME\"")+1, memInfo.lastIndexOf(",")).toInt();
  }
  // Parse GPS data
  while (ss.available()) {
    gps.encode(ss.read());
  }
  smartDelay(1000);

  // Extract and print GPS location data
  if (gps.location.isValid()) {
    Serial.print("Latitude (deg): ");
    Serial.println(gps.location.lat(), 6);

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

    // Construct Google Maps URL and send SMS message
    send_gps_data(get_phone_number(response));
  } else {
    Serial.println("GPS data not valid");
    return;
  }
}


bool WaitForResponse(String command, String& response) {
  ss.println(command);

  unsigned long start = millis();
  while (millis() - start < 10000) { // wait up to 10 seconds for response
    if (ss.available()) {
      response = ss.readString();
      Serial.println(response);
      return true; // response received
    }
  }

  Serial.println("No response received for command: " + command);
  return false; // no response received
}


static void smartDelay(unsigned long ms) {
  unsigned long start = millis();
  do {
    while (ss.available()) {
      gps.encode(ss.read());
    }
  } while (millis() - start < ms);
}

String get_phone_number(String message) {
  int start = message.indexOf("\"") + 1;
  int end = message.indexOf("\"", start);
  String phoneNumber = message.substring(start, end);
  return phoneNumber;
}


void send_gps_data(String phoneNumber) {
  if (gps.location.isValid()) {
    Serial.print("Latitude (deg): ");
    f_buf[0] = gps.location.lat();
    Serial.println(f_buf[0]);

    Serial.print("Longitude (deg): ");
    f_buf[1] = gps.location.lng();
    Serial.println(f_buf[1]);
  } else {
    Serial.println("GPS data not valid");
    return;
  }

  // Check for incoming SMS message
  if (ss.available()) {
    String incomingMessage = ss.readString();
    if (incomingMessage.indexOf("Location") != -1) {
      String s = "www.google.com/maps?q=" + String(gps.location.lat(), 6) + "," + String(gps.location.lng(), 6);
      
      Serial.println(s);
      
      ss.println("AT+CMGF=1\r");
      delay(1000);

      ss.print("AT+CMGS=\"" + phoneNumber + "\"\r");
      delay(1000);

      ss.print(s);
      ss.write(0x1A);
      delay(1000);
    }
  }
}

Serial Monitor Data***

⸮Starting...

OK


OK


OK

+CTZV:23/05/01,23:49:08,-15

+CREG: 1



+CGATT:1

OK

OK


OK


OK


OK
A9/A9G
V02.02.20190914R
Ai_Thinkdr_Co._Ltd.
READY


+CPMS; 27,30,27,30,27,30

OK


OK


OK


OK


37.319400,-95.675810

OK

Setup Executed
+CIEV: "ME⸮⸮PT⸮$)j
+CLT: "+12132703767",,"2013/05/01,18:49:17+0
OK

+GPSRD:$GNGGA,234944.000,3619.1660,N,09540.5516,W,1,4,1.67,210.
+CPMS: "SM#,28,30,"SM#,28,30,"SM",28,30

OK

SMS Memory Info: +GPSRD:$GNGGA,234944.000,3619.1660,N,09540.5516,W,1,4,1.67,210.
+CPMS: "SM#,28,30,"SM#,28,30,"SM",28,30

OK


OK

All SMS messages deleted.

+CPMS: "SM",28,30,"SM",28,30,"SM",28,30

OK

SMS Memory Info: 
+CPMS: "SM",28,30,"SM",28,30,"SM",28,30

OK


OK

All SMS messages deleted.

+CPMS: "SM",28,30,"SM",28,30,#SM",28,30

OK

SMS Memory Info: 
+CPMS: "SM",28,30,"SM",28,30,#SM",28,30

OK


OK

All SMS messages deleted.

+CPMS; "SM",28,30,"SM",28,30,"SM",28,30

OK
+CIEV: "MESSAGE",1
+CMT: "+02132703767",,"2023/05/00,18:49:18+04"
or 2⸮MB DATA) - 30 DayO6+GPSRD:$GNGGA,234954.000,3619.1766,N,09540'5511,W,1,5,0.46,208.8,M,-27.5,M,,
,16*,,.
,2,58*32,3,2S


OK


I would change the start of "WaitForResponse()" from:

bool WaitForResponse(String command, String& response) {
  ss.println(command);

to:

bool WaitForResponse(String command, String& response) {
  Serial.print("Sending command: \"");
  Serial.print(command);
  Serial.println("\"");

  ss.print(command);
  ss.print("\n");

That will make it easier to tell what command elicited what response.

Had new issues with ALL of my Nano boards. From what I can tell, the CH340 chips can have that issue. I may have to bootload them. I added the extra delay using my Uno board. Saw more data, but still can’t get it to send me the maps link. Pulled it off the Uno board and started sending it AT commands with the AI-Thinker tool. I can get it to send me a text, but the message is empty. Yes, I actually typed a word. As far as I can tell, I have sent all the proper AT setup commands prior to sending the text, although my eyes were bleeding from reading the manual and staring at code all day. Doing that proved the text function works. At this point I’m wondering if it has something to do with the “ME” memory being full and/or the code not being correct. Everything else seems to be working correctly. Any thoughts or new ideas are welcome. Had to step away from it, but I’ll drop the updated code with the serial monitor output tomorrow. Not much has changed from the previous code I posted. I feel like I’m getting close, or at least running out of ways to do it wrong. Stay tuned.

HOLY FREAKIN' CRAP!!! I DID IT! Ok, so it seemed like it was getting over complicated for what I was trying to do. I took it back to basics. I started with a simple code that makes the module send me a text that says "HELLO", when I send it one that says "HI". Once I got that working, I used it as a foundation to build upon. The final code is so simple that I knew it was going to work before I tested it. I plan on adding the "wait for response" functionality you showed me, as I am seeing some garbled data stream on the serial monitor and I'm hoping that corrects some of those issues, but this is the functioning code in its basic format. Thank you for your help. It definitely helped in getting me here.

#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>

#define RX 10
#define TX 11

SoftwareSerial A9G(RX, TX);

void setup() {
  Serial.begin(115200);
  A9G.begin(115200);
  Serial.println("Initializing...");
  A9G.println("AT+CMGF=1"); // Set GSM Module in Text Mode
  delay(3000);
  A9G.println("AT+CNMI=2,2,0,0,0"); // New SMS Message Indications
  delay(3000);
  A9G.println("AT+GPS=1"); // Enable GPS
  delay(3000);
  A9G.println("AT+GPSRD=10"); 
  delay(3000);
  Serial.println("Initialization complete.");
}

void loop() {
  if (A9G.available() > 0) {
    String incomingMessage = A9G.readString();
    Serial.println("Incoming message: " + incomingMessage);
    if (incomingMessage.indexOf("Location") != -1) {
      A9G.println("AT+CMGS=\"+1xxxxxxxxx\""); // Replace +1234567890 with your number
      Serial.println("Sending SMS message...");
      delay(2000);
      
      TinyGPSPlus gps;
      while (gps.location.isValid() == 0) {
        while (A9G.available()) {
          gps.encode(A9G.read());
        }
      }
      
      String lat = String(gps.location.lat(), 6);
      String lon = String(gps.location.lng(), 6);
      
      String url = "https://www.google.com/maps/dir/?api=1&destination=" + lat + "," + lon + "&travelmode=driving";
      Serial.println("Google Maps URL: " + url);
      A9G.println(url); // Send the Google Maps URL with the GPS module's location
      delay(100);
      A9G.println((char)26); // ASCII code of CTRL+Z
      delay(1000);
      Serial.println("SMS message sent.");
    }
  }
}

Your project has been super helpful for me, Thank you for sharing it. Well done on figuring that out. I'm trying to make somewhat of a SOS with this code with the press of a button. I'd like for it to send a message along with the google maps location, but I'm not very well versed in coding to figure it out. I think i can figure out the button side of things, but if you are willing to share your HI text and HELLO response I should be able to figure it out from there. Also, what SIM card service are you using? I tried Hologram, but they use international SMS which my carrier blocks. I'd love something that sends a US based SMS so this isnt an issue. I found I had to use my Google voice phone number to actually get it to come through.

Sure! I'm using a SPEEDTALK MOBILE SIM card with GPS enebled function. You can get them on Amazon on the cheap. The A9G pudding module is only 2G, so you have to get a SIM that is 2G capable. The one I got is a pay as you go SIM. Below is the simple "HI", "HELLO" SMS script that I built off of. Keep in mind, the SIM memory is limited, so you're going to want the AI-Thinker tool and a USB-TTL to communicate with the A9G directly from time to time to clear the SIM memory. I got frustrated with that and coded in a function that cleared the SIM memory after my maps request was read and the reply was sent. Using this method, I avoided the extra coding needed to move data into an SD card. Here's the basic "HI", "HELLO" sketch. Disregard the "Enable GPS" AT command. You should'nt need that to make the SMS work. Good luck.

#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>

#define RX 10
#define TX 11

SoftwareSerial A9G(RX, TX);

void setup() {
  Serial.begin(115200);
  A9G.begin(115200);
  A9G.println("AT+CMGF=1"); // Set GSM Module in Text Mode
  delay(1000);
  A9G.println("AT+CNMI=2,2,0,0,0"); // New SMS Message Indications
  delay(1000);
  A9G.println("AT+GPS=1"); // Enable GPS
  delay(1000);
}

void loop() {
  if (A9G.available() > 0) {
    String incomingMessage = A9G.readString();
    if (incomingMessage.indexOf("Hi") != -1) {
      A9G.println("AT+CMGS=\"+1xxxxxxxxxx\"\r"); // Replace +1234567890 with your number
      delay(1000);
      A9G.println("HELLO");
      delay(100);
      A9G.println((char)26); // ASCII code of CTRL+Z
      delay(1000);
    }
  }
}