SIM900 AT命令响应解析 [英] SIM900 AT Commands response parsing

查看:701
本文介绍了SIM900 AT命令响应解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用连接到一个Arduino欧诺SIM900 GPS / GPRS模块盾,我将如何能够解析我的AT命令的响应?或如何将能够发送AT命令后删除在串行打印的第一线?

  AT + CMGL =ALL+ CMGL:1,REC READ,+ XXXXXXXXXX,,16/04 / 25,15:20:59 + 32
HILP AKP SI ralphh的POGI 1 mmalit英里比萨饼hehehehehe+ CMGL:2,REC READ,+ XXXXXXXXXX,,16/04 / 25,21:51:33 + 32
佑!好

例如在输出上面,我想摆脱AT + CMGL =ALL,然后解析余下的数据,什么是最好的方式解析


解决方案

  我将

如何能够解析我的AT命令的响应?


是的,这就是问正确的问题。


  我将

如何能发送AT命令后删除在串行打印的第一线?


没有,这是错误的问题,因为如果你关心回声是否或不是你做错了。

解析AT命令的输出正确的策略如下:


  • 发送AT命令行(以为\\ r正常终止)。

  • 阅读从调制解调器接收,直到你跟终止的完整产品线之一,一个字符为\\ r \\ n,然后解析该行。

    • 如果该行等于最终结果code,然后在命令行中的所有输出结束(和调制解调器已准备好接受新的命令)。这必须是您测试!
    • 的第一件事
    • 如果AT命令的运行有它的信息文本响应线preFIX(几乎所有有)检查是否符合启动,如果这样处理其他行忽略它。

    • 如果AT命令运行没有你可能要直到收到最终的结果code打印一切preFIX。这仅适用于传统的命令,如 ATI ,并为这些解析你可能合法地关心回声与否。



现在的 AT + CMGL 命令是一点点的工作,因为响应在多行分割。

首先,最好的信息来源应该是具体的AT文档制造商,第二个最好的是官方的3GPP的 AT + CMGL nofollow的> 27.005 规范命令。

在文本模式AT + CMGL响应被指定为

  + CMGL:其中;索引>,<统计>,< OA / DA> [<阿尔法>],[< SCTS>] [,< tooa /户>中
&所述;长度]的计算值与所述; CR>&下; LF><数据>并[d CR 1 GT;&下; LF>
+ CMGL:其中;索引>,<统计>,< D​​A / OA> [<阿尔法>],[< SCTS>] [,< tooa /户>中
<长度GT;< CR>< LF><数据> [...]

因此​​,接收开头的行之后+ CMGL:所有以下,直到你读一个空行(\\ r \\ n)的行属于这种

请参阅对普通code结构和流程这个答案,虽然多行属性上面所写响应需要多一点的处理。我会用类似如下(未经测试code):

 枚举CMGL_state {
    CMGL_NONE,
    CMGL_ preFIX,
    CMGL_DATA
};//额外的原型,因为需要的Arduino的自动生成原型使用枚举时,往往打破了汇编。
枚举CMGL_state parse_CMGL(枚举CMGL_state状态,串线);
枚举CMGL_state parse_CMGL(枚举CMGL_state状态,串线)
{
    如果(line.equals(\\ r \\ n){
        返回CMGL_NONE;
    }
    如果(line.startsWith(+ CMGL:){
        返回CMGL_ preFIX;
    }
    如果(状态== CMGL_ preFIX ||状态== CMGL_DATA){
        返回CMGL_DATA;
    }
    返回CMGL_NONE;
}...write_to_modem(AT + CMGL = \\ALL \\\\ r);
CMGL_state = CMGL_NONE;
转到启动;
做{
    CMGL_state = parse_CMGL(CMGL_state,线);
    开关(CMGL_state){
    案例CMGL_ preFIX:
        process_ preFIX(线); //或者任何你想要的这条线做
        打破;
    案例CMGL_DATA:
        process_data(线); //或者任何你想要的这条线做
        打破;
    案例CMGL_NONE:
    默认:
        打破;
    }
开始:
    行= read_line_from_modem();
}而(!is_final_result_ code(线))

i am using sim900 gps/gprs module shield connected to an Arduino Uno, how will i be able to parse the response of my AT commands? Or how will i be able to remove the 1st line printed in the serial after sending an AT command?

AT+CMGL="ALL"

+CMGL: 1,"REC READ","+XXXXXXXXXX","","16/04/25,15:20:59+32"
Hilp akp si ralphh the pogi one mmalit mi pizza hehehehehe

+CMGL: 2,"REC READ","+XXXXXXXXXX","","16/04/25,21:51:33+32"
Yow!!!

OK

example on the output above, i want to get rid of the AT+CMGL="ALL" and then parse the data left, what is the best way in parsing

解决方案

How will i be able to parse the response of my AT commands?

Yes, this is the right question to ask.

How will i be able to remove the 1st line printed in the serial after sending an AT command?

No, this is the wrong question to ask, because if you care about whether echo is on or not you are doing it wrong.

The correct strategy for parsing AT command output is as follows:

  • Send the AT command line (correctly terminated with "\r").
  • Read one and one character received from the modem until you have a complete line terminated with "\r\n" and then parse that line.
    • If the line equals a final result code, then all output from the command line is finished (and the modem is ready to receive new commands). This must be the first thing you test for!
    • If the AT command running has a prefix for its information text response lines (almost all have) check if the line starts with that, and if so process the line else ignore it.
    • If the AT command running does not have a prefix you probably want to print everything until the final result code is received. This applies only for legacy commands like ATI, and for parsing these you might legitimately care about echo or not.

Now for the AT+CMGL command it is a little bit more work since the responses are split on multiple lines.

First of all, the best source of information should be the manufacturer specific AT documentation, the second best being the official 3GPP 27.005 specification that standardize the AT+CMGL command.

The response for AT+CMGL in text mode is specified as

+CMGL: <index>,<stat>,<oa/da>,[<alpha>],[<scts>][,<tooa/toda>,
<length>]<CR><LF><data>[<CR><LF>
+CMGL: <index>,<stat>,<da/oa>,[<alpha>],[<scts>][,<tooa/toda>,
<length>]<CR><LF><data>[...]]

hence after receiving a line starting with "+CMGL: " all the lines following until you read a blank line ("\r\n") belongs to this.

See this answer on the general code structure and flow, although as written above the multi-line property of the response needs a bit more handling. I would have used something like the following (untested code):

enum CMGL_state {
    CMGL_NONE,
    CMGL_PREFIX,
    CMGL_DATA
};

// Extra prototype needed because of Arduino's auto-prototype generation which often breaks compilation when enums are used.
enum CMGL_state parse_CMGL(enum CMGL_state state, String line);
enum CMGL_state parse_CMGL(enum CMGL_state state, String line)
{
    if (line.equals("\r\n") {
        return CMGL_NONE;
    }
    if (line.startsWith("+CMGL: ") {
        return CMGL_PREFIX;
    }
    if (state == CMGL_PREFIX || state == CMGL_DATA) {
        return CMGL_DATA;
    }
    return CMGL_NONE;
}

...

write_to_modem("AT+CMGL=\"ALL\"\r");
CMGL_state = CMGL_NONE;
goto start;
do {
    CMGL_state = parse_CMGL(CMGL_state, line);
    switch (CMGL_state) {
    case CMGL_PREFIX:
        process_prefix(line); // or whatever you want to do with this line
        break;
    case CMGL_DATA:
        process_data(line); // or whatever you want to do with this line
        break;
    case CMGL_NONE:
    default:
        break;
    }
start:
    line = read_line_from_modem();
} while (! is_final_result_code(line))

这篇关于SIM900 AT命令响应解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆