1.为什么要使用AT cmd
拿我最近在公司实习的一个项目进行举例,需要对RSSI进行滤波,其中用到了kalman滤波函数,而其中Q和R参数决定了kalman滤波函数的性能,但是我每次如果一个个修改Q、R的值,再进行烧录调试,也太麻烦了。所以我需要用到AT指令,来打开一个接口,对Q、R进行参数调试。
2.AT cmd设置步骤
1.打开一个接口,定义一个函数将AT cmd
将AT拿来的值传入到需要操作函数的参数中,这样说可能有点抽象,就是我需要定义一个中间函数,把AT cmd传入的值传到一个结构体或者全局变量中,然后在功能函数中,再调用这个结构体或者全局变量。
extern bts_debug_kalman g_bts_kal;
void bts_debug_kalman_config(float Q, float R)
{
BT_DEBUG("bts_debug_kalman_config=set_Q[%f], set_R[%f]",Q, R);
g_bts_kal.Q = Q;
g_bts_kal.R = R;
}
typedef struct {
float R;
float Q;
} bts_debug_kalman;
static float bts_get_kalman_from_tbl(kalman_state_t *state, int8_t z)
{
float x_priori, P_priori, K_gain;
Q = g_bts_kal.Q;
R = g_bts_kal.R;
// printf("Q = %f\t R = %f\n", Q, R);
x_priori = state->x;
P_priori = state->P + Q;
K_gain = P_priori / (P_priori + R);
state->x = x_priori + K_gain * (z - x_priori);
state->P = (1 - K_gain) * P_priori;
state->K = K_gain;
}
其中,bts_debug_kalman_config()就是这个中间函数。
2.定义AT cmd接口
#define RETURNCODE_T utlReturnCode_T
extern void bts_debug_kalman_config(float Q, float R);
RETURNCODE_T ql_bts_rssi_kalman
(
const utlAtParameterOp_T op, /* AT cmd type */
const char *command_name_p, /* AT cmd name */
const utlAtParameterValue_P2c parameter_values_p, /* AT cmd value */
const size_t num_parameters, /* AT cmd number */
const char *info_text_p, /* AT cmd usage string */
unsigned int *xid_p, /* AT cmd handle */
void *arg_p /* AT cmd parser number */
)
{
RETURNCODE_T rc = INITIAL_RETURN_CODE;
CiReturnCode ret = CIRC_SUCCESS;
UINT32 atHandle = MAKE_AT_HANDLE(*(TelAtParserID*)arg_p);
*xid_p = atHandle;
#define PARAM_STR_MAX_LEN 24
char buf[128]={0};
char *p = buf;
int param1, param2;
float paramQ, paramR;
switch (op)
{
case TEL_EXT_GET_CMD: /* AT+BTKALMAN? */
{
sprintf(buf,"+QLAPPTEST:GET OK\r\n");
ret = ATRESP(atHandle, ATCI_RESULT_CODE_OK, 0, buf); //���AT����ִ�н��??
break;
}
case TEL_EXT_SET_CMD: /* AT+BTKALMAN= */
{
if (getExtValue(parameter_values_p, 0, ¶m1, 0, 1000, param1)) {
if (getExtValue(parameter_values_p, 1, ¶m2, 0, 1000, param2)) {
paramQ = param1 / 100.0;
paramR = param2 / 100.0;
bts_debug_kalman_config(paramQ, paramR);
}
ret = ATRESP(atHandle, ATCI_RESULT_CODE_OK, 0, buf);
} else {
ret = ATRESP(atHandle, ATCI_RESULT_CODE_CME_ERROR, CME_INVALID_PARAM, NULL);
}
break;
}
case TEL_EXT_TEST_CMD: /* AT+QLAPPTEST=? */
case TEL_EXT_ACTION_CMD:
default:
{
ret = ATRESP(atHandle, ATCI_RESULT_CODE_CME_ERROR, CME_OPERATION_NOT_SUPPORTED, NULL);
break;
}
}
rc = HANDLE_RETURN_VALUE(ret); /* handle the return value */
return(rc);
}
utlAtCommand_T ql_at_srv_app_shell_cmds[] =
{
#ifdef QL_APP_AT_EXAMPLE //
utlDEFINE_EXTENDED_AT_COMMAND(QL_APP_AT_TEST, "+QLAPPTEST", ql_app_at_test, "+QLAPPTEST:OK",ql_app_at_test_cmd, ql_app_at_test_cmd),//AT+QLAPPTEST
utlDEFINE_EXACTION_AT_COMMAND(QL_APP_AT_TEST_EXACTION, "+QLAPPTESTACT", NULL, "+QLAPPTESTACT:OK", ql_app_at_test_act_cmd),
utlDEFINE_EXTENDED_AT_COMMAND(QL_APP_AT_TEST, "+QLAPPTESTEX", ql_app_at_test_ex, "+QLAPPTESTEX:OK",ql_app_at_test_cmd_ex, ql_app_at_test_cmd_ex),//AT+QLAPPTESTEX
#endif //QL_APP_AT_EXAMPLE
#ifdef QL_APP_AT_BTS_TEST
utlDEFINE_EXTENDED_AT_COMMAND(QL_APP_AT_BTS, "+BTBONDINFO", NULL, "+QLAPPBTS:OK", ql_bts_get_bonded_info, ql_bts_get_bonded_info),
utlDEFINE_EXTENDED_AT_COMMAND(QL_APP_AT_BTS, "+BTPEERINFO", NULL, "+QLAPPBTS:OK", ql_bts_get_peer_info, ql_bts_get_peer_info),
utlDEFINE_EXTENDED_AT_COMMAND(QL_APP_AT_BTS, "+BTUNLOCKEN", ql_app_at_bts_unlock, "+QLAPPBTS:OK", ql_bts_unlock_config, ql_bts_unlock_config),
utlDEFINE_EXTENDED_AT_COMMAND(QL_APP_AT_BTS, "+BTUNBOND", ql_app_at_bts_1_param, "+QLAPPBTS:OK", ql_bts_unbond_config, ql_bts_unbond_config),
utlDEFINE_EXTENDED_AT_COMMAND(QL_APP_AT_BTS, "+BTRSSICALI", ql_app_at_bts_2_param, "+QLAPPBTS:OK", ql_bts_rssi_cali, ql_bts_rssi_cali),
utlDEFINE_EXTENDED_AT_COMMAND(QL_APP_AT_BTS, "+BTRECORDINFO", NULL, "+QLAPPBTS:OK", ql_bts_get_record_info, ql_bts_get_record_info),
utlDEFINE_EXTENDED_AT_COMMAND(QL_APP_AT_BTS, "+BTRECONN", ql_app_at_bts_1_param, "+QLAPPBTS:OK", ql_bts_reconn_dbg, ql_bts_reconn_dbg),
utlDEFINE_EXTENDED_AT_COMMAND(QL_APP_AT_BTS,"+BTKALMAN",ql_app_at_bts_2_param,"+QLAPPBTS:OK",ql_bts_rssi_kalman, ql_bts_rssi_kalman),
utlDEFINE_EXTENDED_AT_COMMAND(QL_APP_AT_BTS, "+BTRECONNCONF", ql_app_at_bts_2_param, "+QLAPPBTS:OK", ql_bts_reconn_dbg, ql_bts_reconn_dbg),
#endif
};
static utlAtParameter_T ql_app_at_bts_2_param[] = {
utlDEFINE_DECIMAL_AT_PARAMETER(utlAT_PARAMETER_ACCESS_READ_WRITE,utlAT_PARAMETER_PRESENCE_REQUIRED),
utlDEFINE_DECIMAL_AT_PARAMETER(utlAT_PARAMETER_ACCESS_READ_WRITE,utlAT_PARAMETER_PRESENCE_REQUIRED),
};
其中,有个注意的地方,如果输入的参数是两个,就用到ql_app_at_bts_2_param。
3.调试步骤
打开串口调试助手,输入AT+BTRSSICALI=param1,param2,发送即可。输入AT+BTRSSICALI?可查看设置的参数。