SIM900A not sending sms

Hi, I'm trying to send an SMS text to my phone and the response is "OK" but I receive nothing. Here's the code:

#include <SoftwareSerial.h>
SoftwareSerial SIM900A(2, 3);
// Connect the SIM900A TX to Arduino pin 2 RX.
// Connect the SIM900A RX to Arduino pin 3 TX.
char c = ' ';
void setup()
{
  // start th serial communication with the host computer
  Serial.begin(19200);
  while (!Serial);
  Serial.println("Arduino with SIM900A is ready");
  // start communication with the SIM900A in 19200
  SIM900A.begin(19200);
  Serial.println("SIM900A started at 19200");
  delay(1000);
  Serial.println("Setup Complete! SIM900A is Ready!");
}
void loop()
{
  // Keep reading from SIM900 and send to Arduino Serial Monitor
  if (SIM900A.available())
  { c = SIM900A.read();
    Serial.write(c);
  }
  // Keep reading from Arduino Serial Monitor and send to SIM900A
  if (Serial.available())
  { c = Serial.read();
    if(c=='s'){SendMessage();}
    else{
    SIM900A.write(c);}
  }
}
void SendMessage()
{
  SIM900A.println("AT+CMGF=1\r\n");    //Sets the GSM Module in Text Mode
  delay(2000);  // Delay of 1000 milli seconds or 1 second
  SIM900A.println("AT+CMGW=\"+639358861057\"\r\n"); // Replace x with mobile number
  delay(2000);
  SIM900A.println("sim900a sms");// The SMS text you want to send
  delay(2000);
  SIM900A.println((char)26, "\r\n");// ASCII code of CTRL+Z
  delay(2000);
  SIM900A.println("AT+CMSS=1");
  delay(2000);
}

+CMGW doesn’t send a message, it writes the message to the currently selected message storage location…

You’ll either need to specify the message number, or use +CMGS

Read the AT command set documentation.

I've tried using the +CMGS in SIM900A.println("AT+CMGW=\"+639358861057\"\r\n"); but an error SIM900A.println((char)26, "\r\n"); in this part. I've also tried this SIM900A.println("AT+CMSS=1,\""+number+"\""); it responses "OK" but I still receive nothing. :frowning:

You can't send Ctrl-Z and CRLF together that way. Try:

  SIM900A.print((char)26); // ASCII code of CTRL+Z
  SIM900A.print("\r\n"); // Send CRLF

I fixed that sir but now the response that I get is "ERROR"

All of the other commands end with "\r\n" (CRLF) but this one ends with just "\n" (LF). Perhaps you should try:

SIM900A.print("AT+CMSS=1\r\n");

You should probably change the others to .print() instead .println() so you don't get "\r\n\n" (CRLFLF).

  SIM900A.print("AT+CMGF=1\r\n");    //Sets the GSM Module in Text Mode
  delay(2000);
  SIM900A.print("AT+CMGW=\""+number+"\"\r"); // Replace x with mobile number
  delay(2000);
  SIM900A.println("sim900a sms");// The SMS text you want to send
  delay(2000);
  SIM900A.print(char(26));// ASCII code of CTRL+Z
  SIM900A.print("\r\n");
  delay(2000);
  SIM900A.print("AT+CMSS=1\r\n");
  delay(2000);

I've updated it to this sir and I got a response as shown in pic below
image_2021-08-17_230641

Great, so you have saved the message in slot #2,
Is that what you wanted to do ?

Yes, save and then send using +CMSS
Tried also the +CMGS but it responses "ERROR" when it comes to the SIM900A.print((char)26);

How about

SIM900A.write(26);

That might solve your issue.

  SIM900A.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(2000);
  SIM900A.println("AT+CMGS=\""+number+"\"\r"); // Replace x with mobile number
  delay(2000);
  SIM900A.println("sim900a sms");// The SMS text you want to send
  delay(2000);
  SIM900A.write(26);// ASCII code of CTRL+Z
  delay(2000);

Still responses "ERROR". I've put +CMEE in the setup() and it presents CMS ERROR: 302 which is operation is not allowed.

Is ‘number’ a cstring or a String ?

Ive never used a modem with Strings, only c-strings…

You may need to some work to format the command… + doesn’t work with c-strings.

Try

SIM900A.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(2000);
  //SIM900A.println("AT+CMGS=\""+number+"\"\r"); // Replace x with mobile number
 SIM900A.println("AT+CMGS=\"xxxxxxxxx\""); // Replace x with mobile number
  delay(2000);
  SIM900A.println("sim900a sms");// The SMS text you want to send
  delay(2000);
  SIM900A.write(26);// ASCII code of CTRL+Z
  delay(2000);

Try this sketch. It looks for output after each command rather than running all of the commands and then looking for input. Maybe it will report an error somewhere along the way.

The SIM900 manual I found shows only a CR (\r) between the AT+CMGS="number" and the SMS text, not a CRLF (\r\n).

#include <SoftwareSerial.h>
SoftwareSerial SIM900A(2, 3);
// Connect the SIM900A TX to Arduino pin 2 RX.
// Connect the SIM900A RX to Arduino pin 3 TX.

String number = "+639358861057";

void setup()
{
  // start th serial communication with the host computer
  Serial.begin(19200);
  while (!Serial);
  Serial.println("Arduino with SIM900A is ready");
  // start communication with the SIM900A in 19200
  SIM900A.begin(19200);
  Serial.println("SIM900A started at 19200");
  delay(1000);
  Serial.println("Setup Complete! SIM900A is Ready!");

  // Turn on verbose messages
  SendCommand("AT+CMEE", 2000);

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

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

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

  // Test for CMGS command support:
  SendCommand("AT+CMGS=?", 2000);
}

void loop()
{
  // Keep reading from SIM900 and send to Arduino Serial Monitor
  if (SIM900A.available())
  {
    char c = SIM900A.read();
    Serial.write(c);
  }

  // Keep reading from Arduino Serial Monitor and send to SIM900A
  if (Serial.available())
  {
    char c = Serial.read();
    if (c == 's')
    {
      SendMessage();
    }
  }
}

bool WaitForResponse(unsigned long waitTime)
{
  unsigned long startTime = millis();
  while (millis() - startTime < waitTime)
  {
    String reply = SIM900A.readStringUntil('\n');
    if (reply != "")
    {
      Serial.print("Received: \"");
      Serial.print(reply);
      Serial.println("\"");
      if (reply.startsWith("OK"))
        return true;
    }
  }
  Serial.println("Did not receive OK.");
  return false;
}

bool SendCommand(String command, unsigned long waitTime)
{
  Serial.print("Sending command: \"");
  Serial.print(command);
  Serial.println("\"");

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

  return WaitForResponse(waitTime);
}

void SendMessage()
{
  Serial.println("Sending SMS text followed by Ctrl-Z/ESC");
  Serial.print("Sending: ");
  Serial.println("AT+CMGS=\"" + number + "\"(CR)");
  Serial.print("sim900a sms");
  Serial.println("(ESC)");

  // NOTE: Command ends with CR, not CRLF:
  SIM900A.print("AT+CMGS=\"" + number + "\"\r");
  SIM900A.print("sim900a sms"); // The SMS text you want to send
  SIM900A.write(26);// ASCII code of CTRL+Z
  
  WaitForResponse(2000);
}

Thank you for the sketch sir. I still get the same error :frowning:. Are there any initial configurations that needs to be done before using it?

What does the sketch produce on Serial Monitor?

This is the output on the Serial Monitor

You can copy and paste text from the Serial Monitor. No need to post a picture of text.

Looks like the sketch crashed just after the command "AT+CMGS=?". Does it always go wrong in the same place? That is the point at which it enters loop() and is looking for a 's' from Serial. Are you sending an 's' to tell it to send the message? Does it crash BEFORE you send an 's' or after?

I found a mistake in my sketch. I had accidentally turned "CMGW" into "CMGS" and I also left out the "CMSS" which does the actual send. One problem is that the CMSS command needs to know what SMS memory location was set by CMGW. I added code to "WaitForReply" that grabs the number reported by CMGW and then I can use that when sending "AT+CMSS: n".

Try this new version:

#include <SoftwareSerial.h>

SoftwareSerial ATCommandStream(2, 3);
// Connect the ATCommandStream TX to Arduino pin 2 RX.
// Connect the ATCommandStream RX to Arduino pin 3 TX.

const char * number = "+639358861057";
int MemoryWriteLocation = 1;

void setup()
{
  // start th serial communication with the host computer
  Serial.begin(19200);
  while (!Serial);
  Serial.println("Arduino with ATCommandStream is ready");
  // start communication with the ATCommandStream in 19200
  ATCommandStream.begin(19200);
  Serial.println("ATCommandStream started at 19200");
  delay(1000);
  Serial.println("Setup Complete! ATCommandStream is Ready!");

  // 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=?");
}

void loop()
{
  // Keep reading from SIM900 and send to Arduino Serial Monitor
  if (ATCommandStream.available())
  {
    char c = ATCommandStream.read();
    Serial.write(c);
  }

  // Keep reading from Arduino Serial Monitor and send to ATCommandStream
  if (Serial.available())
  {
    char c = Serial.read();
    if (c == 's')
    {
      SendSMSMessage(number, "sim900a sms");
    }
  }
}

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("+CMGW:"))
      {
        reply.remove(0, 6); // Strip off "+CMGW:"
        MemoryWriteLocation = reply.toInt();
      }
      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 followed by Ctrl-Z/ESC");
  
  Serial.print("Sending: ");
  Serial.print("AT+CMGW=\"");
  Serial.print(number);
  Serial.println("\"(CR)");
  Serial.print(message); // The SMS text you want to send
  Serial.println("(ESC)");


  ATCommandStream.print("AT+CMGW=\"");  // Write message to memory
  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 code of CTRL+Z

  WaitForResponse();

  String command = "AT+CMSS=" + String(MemoryWriteLocation);
  SendShortCommand(command);  // Send message in memory location 1
}