Very useful code for sending AT commands

Hello folks,

While building a reporting system that uses a SIM900 module, I came across this VERY handy piece of code that deals with AT commands. A tyical example of calling the function looks like this:

(sendATcommand(F("AT+CIPSPRT=0"), F("OK"), 1000));

This repeats the said AT command every 1000 ms until a response of “OK” is returned from Serial2. This makes life very easy when dealing with many AT commands and timeouts etc.

I’ll admit that I don’t know exactly how it works, when looking at its code below.

 template <typename ATcommandType>int8_t sendATcommand(const ATcommandType ATcommand, const __FlashStringHelper* expected_answer, unsigned int timeout)
   {
     uint8_t x = 0, answer = 0;
     char response[200];
     unsigned long previous;
     memset(response, '\0', 200);            // initalize string
     delay(100);
     while (Serial2.available() > 0)
       Serial2.read();                        // clears the buffer
     Serial2.println(ATcommand);
     x = 0;
     previous = millis();
     const char* expected_answer_pointer = (const char PROGMEM *)expected_answer;
     do
     {
       if (Serial2.available() != 0)
       {
         response[x] = Serial2.read();
         x++;
         if (strstr_P(response, expected_answer_pointer) != NULL)
         {
           answer = 1;
         }
       }
     } 
     while ((answer == 0) && ((millis() - previous) < timeout));
     Serial.println(response);
     return answer;
   }

Now my question: I need to send an AT command to the modem which contains a variable: manually done it looks like this:

Serial2.print(F("AT+CIPSEND="));
    Serial2.println(getRequest.length());

Now the function I use to deal with my AT commands does not allow “getRequest.length()” to be thrown in there with “AT+CIPSEND=” - does anyone know how I can overcome this?

Thanks in advance.

char cmd[100];
sprintf(cmd, "AT+CIPSEND=%d", getRequest.length());

sendATcommand(cmd, F("OK"), 1000);

Much appreciated, PaulS. Off we go again.

BTW, while functions like the OP’s reference are very useful, keep in mind they use ‘blocking’ strategies.

This means that all your other code waits for the response from the function.

Example: If you have a heartbeat blinking LED using millis(), the heartbeat will stutter for the duration of the response or function timeout, and resume once the function has returned.

There are ways around this, but they’re not trivial.