我将如何解析我的 AT 命令的响应?
是的,这是正确的问题。
发送 AT 命令后,如何删除串行中打印的第一行?
不,这是一个错误的问题,因为如果您关心 echo 是否打开,那么您做错了。
解析AT命令输出的正确策略如下:
- 发送 AT 命令行(以 正确终止
"\r"
)。
- 读取从调制解调器接收到的一个字符和一个字符,直到您有一个完整的行终止,
"\r\n"
然后解析该行。
- 如果该行等于最终结果代码,则命令行的所有输出都已完成(并且调制解调器已准备好接收新命令)。这一定是你测试的第一件事!
- 如果运行的 AT 命令对其信息文本响应行有前缀(几乎所有都有),请检查该行是否以该前缀开头,如果是则处理该行,否则忽略它。
- 如果运行的 AT 命令没有前缀,您可能希望打印所有内容,直到收到最终结果代码。这仅适用于像 之类的遗留命令
ATI
,并且对于解析这些命令,您可能会合理地关心 echo 与否。
现在对于AT+CMGL
命令来说,它需要做更多的工作,因为响应被分成多行。
首先,最好的信息来源应该是制造商特定的 AT 文档,其次是标准化命令的官方 3GPP 27.005规范。AT+CMGL
文本模式下 AT+CMGL 的响应指定为
+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>[...]]
因此,在收到以“+CMGL:”开头的行之后,直到您读取空行(“\r\n”)之前的所有行都属于此。
请参阅有关一般代码结构和流程的答案,尽管如上所述,响应的多行属性需要更多处理。我会使用类似以下的东西(未经测试的代码):
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))