The latest development version of this page may be more current than this released 0.4.3 version.

AT Command Set

This chapter will specifically introduce how to use various AT commands.

It is strongly recommended to read the following content before using commands to understand some basic information about AT commands.

AT Command Classification

There are four types of universal AT commands:

Type

Command format

Explanation

Test command

AT+<Command Name>=?

Get the internal parameters of the setting command and its example commands

Get command

AT+<Command Name>?

Return the current parameter value

Set command

AT+<Command Name>=<…>

Set user-defined parameter values and run commands

Execute command

AT+<Command Name>

Run commands without user-defined parameters

  • Not every AT command has the four types of commands mentioned above.

  • Input parameters in the command, currently only string parameters and integer parameters are supported.

  • The parameters within the angle brackets < > cannot be omitted.

  • The parameters within square brackets [ ] can be omitted, and default values will be used when omitted. For example, when running the command AT+CWJAP , some parameters are omitted:

    AT+CWJAP="WinnerMicro","12345678"
    AT+CWJAP="WinnerMicro","12345678","11:22:33:44:55:66"
    
  • When there are still parameters to be filled in after omitted parameters, , must be used to separate them, for example:

    AT+CWJAP="ssid","password",,1
    
  • Use double quotation marks to represent string parameters, such as:

    AT+CWSAP="WinnerMicro","12345678",1,4
    
  • Special characters need to be escaped, such as ,"\ , etc.

    • \\: Escape the back slash.

    • \,:Escape commas, commas separating parameters do not need to be escaped.

    • \": Escape double quotes, indicating that double quotes for string parameters do not need to be escaped.

    • \<any>: Escaping the <any> character, which means only using the <any> character and not using a back slash.

  • Only special characters in the AT command need to be escaped, no escape is required elsewhere. For example, when the AT command port prints > and waits for input data, the data does not need to be escaped.

    AT+CWJAP="comma\,backslash\\ssid","1234567890"
    AT+MQTTPUB=0,"topic","\"{\"sensor\":012}\"",1,0
    
  • The default baud rate for AT command is 115200.

  • The length of each AT command should not exceed 256 bytes.

  • The AT command ends with a new line (CR-LF), so the serial port tool should be set to “new line mode”.

  • The definition of AT command error codes can be found in the Pending AT Code :

AT command to save parameter information in flash

The parameter changes for the following AT commands will always be saved in the NVS area of the flash, so they will be used directly after a restart.

Whether parameter changes for some other commands are saved to flash can be configured using the AT+SYSSTORE command. Please refer to the detailed description of the command.

Note

The parameter saving in AT commands is implemented through the NVS library . Therefore, if a command configures the same parameter value, it will not write to the flash; if a command configures a different parameter value, the flash will not be frequently erased.

AT Messages

The WinnerMicro-AT messages returned from the WinnerMicro-AT command port have two types: WinnerMicro-AT responses (passive) and WinnerMicro-AT message reports (active).

  • WinnerMicro-AT Responses (Passive)

    Each input AT command returns a response, telling the sender the execution result of the WinnerMicro-AT command. The last message of the response will inevitably be OK or ERROR.

    WinnerMicro-AT Responses

    AT Response

    Description

    OK

    The AT command has been processed and returns OK.

    ERROR

    The AT command is incorrect or an error occurred during execution.

    SEND OK

    Data has been sent to the protocol stack (for the AT+CIPSEND and AT+CIPSENDEX commands), but it does not mean the data has been sent to the peer.

    SEND FAIL

    An error occurred while sending data to the protocol stack (for the AT+CIPSEND and AT+CIPSENDEX commands).

    +<Command Name>:...

    Detailed description of the AT command processing result.

    CMD FORMAT ERR

    The AT command does not exist.

  • WinnerMicro-AT message Reports (Active)

    WinnerMicro-AT will report important status changes or messages in the system.

    WinnerMicro-AT Message Reports

    WinnerMicro-AT Message Report

    Description

    busy …

    The system is busy processing the previous command and cannot process a new command.

    WIFI CONNECTED

    Wi-Fi station interface has connected to the AP.

    WIFI GOT IP

    The Wi-Fi station interface has obtained an IPv4 address.

    WIFI DISCONNECT

    The Wi-Fi station interface has disconnected from the AP.

    [<conn_id>,]CONNECT

    A network connection with ID <conn_id> has been established (default ID is 0).

    [<conn_id>,]CLOSED

    A network connection with ID <conn_id> has been closed (default ID is 0).

    +STA_CONNECTED: <sta_mac>

    A station has connected to the Wi-Fi softAP interface of WinnerMicro-AT.

    +DIST_STA_IP: <sta_mac>,<sta_ip>

    The Wi-Fi softAP interface of WinnerMicro-AT has assigned an IP address to the station.

    +STA_DISCONNECTED: <sta_mac>

    The station has disconnected from the Wi-Fi softAP interface of WinnerMicro-AT.

    +IPD

    WinnerMicro-AT has received data from the network in non-transparent mode. The message format is as follows:

    • If AT+CIPMUX=0 and AT+CIPRECVMODE=1, it prints: +IPD,<length>

    • If AT+CIPMUX=1 and AT+CIPRECVMODE=1, it prints: +IPD,<link_id>,<length>

    • If AT+CIPMUX=0 and AT+CIPRECVMODE=0 and AT+CIPDINFO=0, it prints: +IPD,<length>:<data>

    • If AT+CIPMUX=1 and AT+CIPRECVMODE=0 and AT+CIPDINFO=0, it prints: +IPD,<link_id>,<length>:<data>

    • If AT+CIPMUX=0 and AT+CIPRECVMODE=0 and AT+CIPDINFO=1, it prints: +IPD,<length>,<"remote_ip">,<remote_port>:<data>

    • If AT+CIPMUX=1 and AT+CIPRECVMODE=0 and AT+CIPDINFO=1, it prints: +IPD,<link_id>,<length>,<"remote_ip">,<remote_port>:<data>

    Where link_id is the connection ID, length is the data length, remote_ip is the remote IP address, remote_port is the remote port number, and data is the data.

    Note: When this is an SSL connection, in passive receiving mode (AT+CIPRECVMODE=1), the length returned by the AT command port may not match the actual readable SSL data length. The AT will first return the readable data length at the SSL layer; if the readable data length at the SSL layer is 0, the AT will return the readable data length at the socket layer.

Customize AT commands

This chapter will specifically introduce how to carry out AT secondary development.

Command registration

typedef struct wm_atcmd_item {
    char *cmd_name;
    wm_atcmd_act cmd_handle;
#if CONFIG_WM_ATCMD_USAGE_ENABLE
    char *cmd_usg;
#endif /* CONFIG_WM_ATCMD_USAGE_ENABLE */
} wm_atcmd_item_t;

#define WM_ATCMD_SECTION                    ".wm_at_table"

#if CONFIG_WM_ATCMD_USAGE_ENABLE
#define WM_ATCMD_DEFINE(cmd, func, usage)                                                                  \
    static const struct wm_atcmd_item __atcmd_##func __attribute__((used, section(WM_ATCMD_SECTION))) =    \
    {                                                                                                      \
        .cmd_name  = cmd,                                                                                  \
        .cmd_handle = func,                                                                                \
        .cmd_usg = usage,                                                                                  \
    };
#else /* CONFIG_WM_ATCMD_USAGE_ENABLE */
#define WM_ATCMD_DEFINE(cmd, func, usage)                                                                  \
    static const struct wm_atcmd_item __atcmd_##func __attribute__((used, section(WM_ATCMD_SECTION))) =    \
    {                                                                                                      \
        .cmd_name  = cmd,                                                                                  \
        .cmd_handle = func,                                                                                \
    };
#endif /* CONFIG_WM_ATCMD_USAGE_ENABLE */
  • cmd_name is a character pointer that can be used to store the name of a command.

  • cmd_handle is a member of type wm_atcmd_act, which is a function pointer that can be used to handle specific commands.

  • cmd_usg is a character pointer used to store help information for AT commands.

Device registration

typedef struct wm_atcmd_dev {
  wm_atcmd_dev_type_e type;
  wm_dev_ops_t ops;
} wm_atcmd_dev_t;
typedef enum wm_atcmd_dev_type {
   WM_ATCMD_DEV_TYPE_UART = 0,
   WM_ATCMD_DEV_TYPE_WIFI,
   WM_ATCMD_DEV_TYPE_BT,
   WM_ATCMD_DEV_TYPE_BLE,
   WM_ATCMD_DEV_TYPE_MAX
} wm_atcmd_dev_type_e;
  • In order to register different devices with AT, the above structure includes device types, device sending and receiving capabilities.

  • wm_atcmd_dev_type: The type of device used to distinguish between different types of devices.

  • wm_dev_ops_t: Operation interface used to define various operations or methods of the device.

Instruction type

AT_TYPE_QUERY = 0, //?    It is an AT command of inquiry or query type.
AT_TYPE_TEST  = 1, //=?   It is an AT instruction of testing or verification type.
AT_TYPE_EXEC  = 2,        It is an AT instruction of execution or operation type.
AT_TYPE_MAX               Maximum value of enumeration type

AT return value

WM_AT_RESULT_OK = 0,              /* AT result Ok */  Indicates successful execution of AT instruction, with a value of 0
WM_AT_RESUT_FAIL,                /* AT result have a generic error */  Indicates AT instruction execution failure, this is a general error
WM_AT_RESULT_NULL,              /* AT result no string return */   Indicates that the AT command did not return any string result
WM_AT_RESULT_CMD_ERR,          /* AT command can not find */     Indicates that the AT command cannot be found or does not exist.
WM_AT_RESULT_PARSE_FAIL,      /* AT command parse  error */     Indicates an AT instruction parsing error.
AT_RESULT_MAX     List the maximum value

API Introduction

1 Initialize AT command

/**
* @brief     init atcmd model
*
* @param     void
*
* @return
*    - WM_ERR_SUCCESS: succeed
*    - others: failed
*/
int wm_atcmd_init(void);

2 Registration of AT devices

/**
* @brief     register atcmd dev ops
*
* @param     dev_type  device type
*            ops       device ops func
*
* @return
*    - WM_ERR_SUCCESS: succeed
*    - others: failed
*/
int wm_atcmd_dev_register(wm_atcmd_dev_type_e dev_type, wm_dev_ops_t ops);

3 AT outputs printing information to the terminal

 /**
 * @brief     print result
 *
 * @param     format  format str
 *
 * @return    None
 */
void wm_atcmd_print_result(char *format,...);

4 AT enters transparent transmission

 /**
 * @brief     enter passthrough mode
 *
 * @param     pt_tx_handle  passthrough tx func
 *            priv          user private data
 *            pt_exit_notify passthrough exit notify func
 *            timeout       passthrough timeout
 *
 * @return    None
 */
void wm_atcmd_enter_passthrough(wm_atcmd_tx_passthrough pt_tx_handle, wm_atcmd_tx_passthrough_exit_notify pt_exit_notify, void *priv, uint32_t timeout);

5 AT exits transparent transmission

/**
* @brief     exit passthrough mode
*
* @param     reason  exit reason
*
* @return    None
*/
void wm_atcmd_exit_passthrough(wm_atcmd_exit_passthrough_reason_e reason);

Demo

#include <stdio.h>
#include <string.h>

#include "wm_atcmd.h"
#include "wm_drv_uart.h"

void uart1_init(void)
{
    wm_drv_uart_options_s uart_option;

    memset(&uart_option, 0, sizeof(uart_option));
    uart_option.baudrate = WM_DRV_UART_BAUD_RATE_B115200;
    uart_option.data_bits = WM_DRV_UART_DATA_8BITS;
    uart_option.flow_ctrl = WM_DRV_UART_FLOW_CTRL_NONE;
    uart_option.parity_type = WM_DRV_UART_PARITY_DISABLED;
    uart_option.stop_bits = WM_DRV_UART_ONE_STOP_BITS;
    uart_option.event_callback = wm_at_uart_rx_callback;

    wm_drv_uart_init(ATCMD_UART_INDEX, &uart_option);
}

static int wm_cmd_test1(wm_at_type_e type, int argc, char **argv)
{
    if (AT_TYPE_QUERY == type)
    {
        wm_atcmd_print_result("This is used to query the parameters of user-defined AT commands and return the current value.\r\n");

        return WM_AT_RESULT_OK;
    }
    else if (AT_TYPE_EXEC == type)
    {
        /* do some things... */
        wm_atcmd_print_result("This is used to set the parameter values for user-defined AT commands and run this command.\r\n");

        return WM_AT_RESULT_OK;
    }
    else if (AT_TYPE_TEST == type)
    {
        wm_atcmd_print_result("This is used to set the help information for user-defined AT commands.\r\n");

        return WM_AT_RESULT_OK;
    }
    else
    {
        return WM_AT_RESULT_FAIL;
    }
}

/* The third parameter of the AT command registration can be filled in as NULL, indicating the use of help information defined by the user in the command; The third parameter can also be set as a string of help information, indicating the help information set using the parameter. */
WM_ATCMD_DEFINE("AT+TEST1",  wm_cmd_test1,  NULL)

int main(void)
{
    wm_dev_ops_t ops;
    int err = wm_atcmd_init();

    if (!err)
    {
        wm_log_info("atcmd init finished.");
    }
    else
    {
        wm_log_error("atcmd init failed.");
    }

    uart1_init();
    ops.atcmd_recv = atcmd_recv;
    ops.atcmd_send = atcmd_send;
    wm_atcmd_dev_register(WM_ATCMD_DEV_TYPE_UART, ops);

    return 0;
}