Purpose of delay in sim800l at commands

Do I have to use 3 sec delay after every AT commands in sim800l.
Every site I browse has delay between every commands, some has low some has very high.

The project I am working on is monitor temperature of temperature sensitive material using DHT every second and upload to server and I think using delay is bad. I wouldn't mind not monitoring temperature for few seconds until at commands run but using 60 sec delay total is I think bad.

Can't this have any workaround like creating a recursive loop of 10 sec which check temperature instead of delay. Will it interfere with sim800l?

No the proper way to handle AT commands is to parse the answers you get and handle those correctly. If you get OK for example then you can proceed.

Poor code written by lazy programmers will just wait for what they think is long enough for the module to execute the command and be ready for the next one… often this is too long but other times it’s not long enough and the next command fails silently and you have a bug….

You just come across bad examples.
In fact, between commands there should be no delays, but waiting and parsing responses from the modem. That is, it is necessary not only to wait 3 seconds, but to check. whether the modem answered OK or not. If the modem has already answered, then you can give a new command

This is mostly correct, but commands take time to respond, and ‘waiting’ could easily affect any other real time activities in your code.

I’m using a self-written version of the FONA library that runs asynchronously with multiple ‘states’ and callbacks - that allow the main program to run continuously.

It’s pretty poorly hacked together out of necessity, but I’m still able to handle polled inputs, serial comms and timed output events at better than 20mS resolution at any time whether the modem is busy or not.

If there’s a hardcore experienced developer that would like to take it further, DM me, and we might be able to move forward.

where Did i write you needed to do this synchronously? :slight_smile:

(I do use also a quickly hacked together custom class when needed and you can do things synchronously or asynchronously - see Facing problem on sending SMS on different condition Using GSM module and Arduino mega - #17 by sreekanthmp)

I tried searching online and doing experiments but can't figure out how to parse 'OK'
Do I run a loop like this

while (!strcmp(gprsSerial.read(), "OK"))
{
//wait
}

It isn't working for me and I go into infinite loop

Read gets you only one byte when there is something to read, so not only it’s not a pointer to a cString you can use in strcmp() but it’s not accumulating the characters you get.

I would suggest to study Serial Input Basics to handle this

Or look at the source code of the StreamDevice class I have In the previous link.

I wrote an example that uses a "WaitForResponse();" function instead of a fixed delay.

#include <SoftwareSerial.h>

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

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

void setup()
{
  // start th 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();
}
1 Like

No offence intended, I was merely pointing out for the OP, that network related commands to the modem may take a couple of seconds to respond.

(As you and I already understand this is disappointing if we have to ‘wait’ for the OK/ERROR/… response.)

no worries, there was a smiley !

most code I have seen though will happily wait for the SMS to be sent, so an active wait is often OK, but no need to wait 3s if 50ms is enough !

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