Cellular::command, command, Cellular.command

Cellular.command() is a powerful API that allows users access to directly send AT commands to, and parse responses returned from, the Cellular module. Commands may be sent with and without printf style formatting. The API also includes the ability pass a callback function pointer which is used to parse the response returned from the cellular module.

Since 0.9.0: On the Boron, Cellular.command requires Device OS 0.9.0 or later; it is not supported on 0.8.0-rc versions.

Note: Obviously for this command to work the cellular module needs to be switched on, which is not automatically the case in SYSTEM_MODE(MANUAL) or SYSTEM_MODE(SEMI_AUTOMATIC). This can be achieved explicitly via Cellular.on() or implicitly by calling Cellular.connect() or Particle.connect().

You can download the latest u-blox AT Commands Manual.

Another good resource is the u-blox AT Command Examples Application Note.

LTE Cat M1 devices (SARA-R410M-02B) have a slightly different AT command set in the u-blox SARA-R4 AT Commands Manual.

The B Series B523 SoM and Tracker T523 SoM (EMEA) have a Quectel EG91-E, the AT commands can be found in the Quectel EG9x AT Commands Manual (version 1.1)..

The Tracker T402 SoM (North America) has a Quectel BG96-MC, the AT commands cann be found in the Quectel BG96 AT Commands Manual (version 2.1)..

The prototype definition is as follows:

int Cellular.command(_CALLBACKPTR_MDM cb, void* param, system_tick_t timeout, const char* format, ...);

Cellular.command() takes one or more arguments in 4 basic types of signatures.

// SYNTAX (4 basic signatures with/without printf style formatting)
int ret = Cellular.command(cb, param, timeout, format, ...);
int ret = Cellular.command(cb, param, timeout, format);
int ret = Cellular.command(cb, param, format, ...);
int ret = Cellular.command(cb, param, format);
int ret = Cellular.command(timeout, format, ...);
int ret = Cellular.command(timeout, format);
int ret = Cellular.command(format, ...)
int ret = Cellular.command(format);
  • cb: callback function pointer to a user specified function that parses the results of the AT command response.
  • param: (void*) a pointer to the variable that will be updated by the callback function.
  • timeout: (system_tick_t) the timeout value specified in milliseconds (default is 10000 milliseconds).
  • format: (const char*) contains your AT command and any desired format specifiers, followed by \r\n.
  • ...: additional arguments optionally required as input to their respective format string format specifiers.

Cellular.command() returns an int with one of the following 6 enumerated AT command responses:

  • NOT_FOUND = 0
  • WAIT = -1 // TIMEOUT
  • RESP_OK = -2
  • RESP_ERROR = -3
  • RESP_PROMPT = -4
// EXAMPLE - Get the ICCID number of the inserted SIM card
SerialLogHandler logHandler;

int callbackICCID(int type, const char* buf, int len, char* iccid)
  if ((type == TYPE_PLUS) && iccid) {
    if (sscanf(buf, "\r\n+CCID: %[^\r]\r\n", iccid) == 1)
  return WAIT;

void setup()
  char iccid[32] = "";
  if ((RESP_OK == Cellular.command(callbackICCID, iccid, 10000, "AT+CCID\r\n"))
    && (strcmp(iccid,"") != 0))
    Log.info("SIM ICCID = %s\r\n", iccid);
    Log.info("SIM ICCID NOT FOUND!");

void loop()
  // your loop code

The cb function prototype is defined as:

int callback(int type, const char* buf, int len, void* param);

The four Cellular.command() callback arguments are defined as follows:

  • type: (int) one of 13 different enumerated AT command response types.
  • buf: (const char*) a pointer to the character array containing the AT command response.
  • len: (int) length of the AT command response buf.
  • param: (void*) a pointer to the variable or structure being updated by the callback function.
  • returns an int - user specified callback return value, default is return WAIT; which keeps the system invoking the callback again as more of the AT command response is received. Optionally any one of the 6 enumerated AT command responses previously described can be used as a return type which will force the Cellular.command() to return the same value. AT commands typically end with an OK response, so even after a response is parsed, it is recommended to wait for the final OK response to be parsed and returned by the system. Then after testing if(Cellular.command() == RESP_OK) and any other optional qualifiers, should you act upon the results contained in the variable/structure passed into the callback.

There are 13 different enumerated AT command responses passed by the system into the Cellular.command() callback as type. These are used to help qualify which type of response has already been parsed by the system.

  • TYPE_UNKNOWN = 0x000000
  • TYPE_OK = 0x110000
  • TYPE_ERROR = 0x120000
  • TYPE_RING = 0x210000
  • TYPE_CONNECT = 0x220000
  • TYPE_NOCARRIER = 0x230000
  • TYPE_NODIALTONE = 0x240000
  • TYPE_BUSY = 0x250000
  • TYPE_NOANSWER = 0x260000
  • TYPE_PROMPT = 0x300000
  • TYPE_PLUS = 0x400000
  • TYPE_TEXT = 0x500000
  • TYPE_ABORTED = 0x600000