【发布时间】:2017-08-23 22:59:01
【问题描述】:
我正在使用带有 sim900 gps/gprs 模块的 Arduino Uno,并且我正在使用 at 命令,我怎样才能获得 at 命令的响应(即 OK、ERROR),以便我可以做一些事情 if response == "OK" 或 @ 987654322@
【问题讨论】:
标签: arduino sms at-command
我正在使用带有 sim900 gps/gprs 模块的 Arduino Uno,并且我正在使用 at 命令,我怎样才能获得 at 命令的响应(即 OK、ERROR),以便我可以做一些事情 if response == "OK" 或 @ 987654322@
【问题讨论】:
标签: arduino sms at-command
如果您还没有阅读V.250 specification 中的第 5 章的全部内容,请停止阅读并立即阅读,这是此答案其余部分的重要基础,我会等您回来。一些对字母表的引用(简短版本:忽略它/将其视为 ASCII)和 S 寄存器可能看起来很神秘,但不要放弃,它会很快在你身上成长。
处理调制解调器输出的唯一正确方法是将输出分成完整的行,并同时迭代一个完整的行。这是通用的,并且绝对适用于所有 AT 命令(我能想到的只有一个例外1)。
让我强调一下:您应该只在严格的行尾边界 ("\r\n") 上拆分调制解调器响应文本,并在一次操作中处理生成的行字符串。所以你真的应该去实现我在previous answer 中建议的read_line_from_modem 函数。
这意味着,无论何时您要检查 OK 结果代码,您都应该只使用 strcmp(line, "OK\r\n") 而不是 strstr 或类似的,因为您知道您正在处理一个完整的完整行,该行应该以最终结果代码开头开头,后面总是有"\r\n"2。
现在有更多的最终结果代码,而不仅仅是OK 和ERROR,而不是试图自己弄清楚所有事情3
我建议查看this answer 中列出的 is_final_result_code 或 isFinalResponseSuccess。
1AT+CMGS 的 "\r\n> " 前缀是您做一些不同的事情的唯一地方,即开始处理调制解调器响应而不是严格的线路边界。
2
除非您错误地配置了 S3 和 S4,否则您永远不应该这样做。
3 V.250 中的列表不完整,在 27.005 和 27.007 中还有更多定义。
【讨论】:
您可以在发出 AT 命令后使用以下代码读取 SIM900 GSM 模块的响应。
char response[200];
for(int i = 0 ; Serial.available() > 0 && i<200 ; i++) {
response[i++] = Serial.read();
}
读取响应后,您可以使用strstr() 函数来检查它是'OK'还是'ERROR',如下所示:
if(strstr(responce, "OK"){
/*Do your code to handle OK response*/
}
else if(strstr(responce, "ERROR"){
/*Do your code to handle ERROR response*/
}
else {
/* You got some other response*/
}
【讨论】:
strcmp 可能不起作用。返回会有一些\r\n。 strstr 更适合这个。
if 和else if 的条件之后添加另一个) 来修复代码?
我只是想补充一下 K.H.A.J.A.S 的答案对我有帮助,但我必须先修改它才能像这样工作:
char response[200];
for(int i = 0 ; Serial.available() > 0 && i<200 ; i++) {
response[i] = Serial.read();
}
而他的答案是 [i++],所以它在 for 循环中递增 i,然后在将该 char 存储在响应索引 i 中时再次递增 i。
【讨论】:
您需要从与模块通信的串行连接中读取响应,例如:
String getResponse() {
String response = "";
while(mySerial.available()!=0){
response += mySerial.read();
}
return response;
}
(mySerial指的是你在模块上使用的串口,如果你只是在pin 0和pin上使用普通串口,那么你应该用Serial替换它)
您可能希望使用response.trim() 从开头和结尾修剪任何空白字符,然后再检查它是否等于您要查找的响应之一。
【讨论】: