AT命令响应(了解Arduino上代码执行的顺序) [英] AT command responses (understanding order of code execution on Arduino)

查看:780
本文介绍了AT命令响应(了解Arduino上代码执行的顺序)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从Arduino Uno/Nano(ATmega328)向ESP8266发送AT命令,并尝试解析接收到的字符串的末尾以响应,以确定ESP的反应方式以及它是否成功(以及是否准备就绪)接收另一个命令).我知道这里之前已经讨论了解析AT命令响应:获取AT命令响应

I'm sending AT commands to an ESP8266 from an Arduino Uno/Nano (ATmega328) and attempting to parse the end of the strings received in response to establish how the ESP reacted and whether it was successful (and whether it's ready to receive another command yet). I'm aware that parsing AT command responses has been discussed before here: Get AT command response

但是我有一个没有解决的特定问题,这里的其他人也可能会感兴趣...

But I have a specific issue not covered there that might also be of interest to other people on here...

首先,调用一个函数,该函数将AT命令发送到ESP以连接到ThingSpeak(数据记录服务器).这在手动模式下可以正常工作,并且在尝试解析响应时也可以连接,但它仅解析返回的第一行.例如,串行监视器中的预期输出将是:

First, a function is called which sends the AT command to the ESP to connect to ThingSpeak (datalogging server). This works fine in manual mode and also connects when trying to parse the response BUT it only parses the first line that comes back. For example, the expected output in the serial monitor would be:

c
AT+CIPSTART="TCP","api.thingspeak.com",80
CONNECT

OK
Connected to ThingSpeak!

c只是我键入的用于启动连接的命令字符.

Where c is just the command character I type to initiate the connection.

但是,实际响应如下:

c
AT+CIPSTART="TCP","api.thingspeak.com",80
Cannot connect to ThingSpeak!


CONNECT

OK

这意味着解析函数在收到响应之前就结束了...如下面的代码所示,当前指定了10秒的超时.即使超时20秒,也会发生相同的事情,尽管实际上在手动执行时,响应会在大约一秒钟后到达.

This means that the parsing function is ending before it receives the response... As shown in the code below, there is a 10 second timeout currently specified. Even with a 20 second timeout, the same thing happens, despite the fact that when executed manually, the response arrives in around one second.

只是为了测试解析功能,我尝试搜索"80",它返回true,因为它在响应的第一行末尾找到.无论是搜索"OK"还是"OK\r\n",结果都是相同的,它返回false,然后接收其余响应.

Just to test the parsing function, I tried searching for "80" and it returned true as this is found at the end of the first line of the response. Whether it searches for "OK" or "OK\r\n" the result is the same, it returns false and THEN the rest of the response is received.

代码如下:

boolean waitForResponse(String target, unsigned long timeout)
{
  unsigned long startTime = millis();
  String responseBuffer;
  char charIn;

  //keep checking for ESP response until timeout expires
  while ((millis() - startTime) < timeout)
  {
    if (ESP.available())
    {
      responseBuffer += ESP.read();
    }
  }
  Serial.println(responseBuffer);
  if (responseBuffer.endsWith(target))
  {
    return true;
  } else {
    return false;
  }
}

void openCxn()
{
  ESP.print("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",80");
  delay(500);
  if (waitForResponse("80",10000L))
  {
    Serial.println("Connected to ThingSpeak!");
  } else {
    Serial.println("Cannot connect to ThingSpeak!");
  }
}

您知道为什么它会在收到完整响应之前(在超时时间内)返回吗?与endsWith()函数有关吗?

Any idea why it returns before the full response is received (well within the timeout period)? Is it something to do with the endsWith() function?

因此,您对如何使其解析整个响应而不只是第一行有任何想法吗?

Consequently, do you have any ideas of how to make it parse the entire response instead of just the first line?

重申一下,我只对回复的结尾感兴趣(例如"OK""OK\r\n").

To reiterate, I am only interested in the end of the response (e.g. "OK" or "OK\r\n").

推荐答案

您知道为什么它会在收到完整响应之前(在超时时间内)返回吗?

Any idea why it returns before the full response is received (well within the timeout period)?

是的,您的主要问题是以下

Yes, your main problem is the following

if (ESP.available())

这使得每当UART(或其他串行IO缓冲区)为空时,waitForResponse函数都会返回-这不是您想要的.您想要的是从串行端口读取,直到收到以"\r\n"终止的行.

This makes the waitForResponse function return whenever the UART (or some other serial IO buffer) is empty - which is not what you want. What you want is to read from the serial port until you have received a line terminated with "\r\n".

与endsWith()函数有关吗?

Is it something to do with the endsWith() function?

是的,这是与ESP.available结合使用的另一个问题,因为您试图将调制解调器响应线的末端与串行路径中发生的随机数据斩波进行匹配.如果您非常幸运,这将是界限,但很可能不是,并且您不应该依赖于此.

Yes, that is an additional problem combined with ESP.available because you are attempting to match the end of a response line from the modem with what ever random data chopping occurs in the serial path. If you are extremely lucky this will be on line boundaries, but most likely not and you should not rely on that.

这是一个常见的协议问题,称为框架,适用于任何类型异步串行通信.对于调制解调器通信,成帧字符为\r\n.

This is a general protocol problem known as framing that applies to any kind of asynchronous serial communication. For modem communications the framing characters are \r and \n.

帮自己一个忙,实现一个readline函数,该函数逐个读取一个字符,直到前一个字符为\r并且当前字符为\n,然后返回到目前为止已读取的所有内容.

Do yourself a favour and implement a readline function that reads one by one character until it the previous character was \r and the current character is \n and then return everything it read so far.

然后专门使用该功能 1 读取调制解调器响应数据.这适用于中间结果代码(例如CONNECT)以及最终结果代码(例如OK等). 然后,解析"响应行就可以简单到

Then use that function exclusively1 for reading modem response data. This applies both to Intermediate result codes like CONNECT as well as Final result codes (e.g. OK etc). "Parsing" the response lines can then be as simple as

if (responseLine.equals("CONNECT\r\n")) ...

if (isFinalResultCode(responseLine)) ...

正如我之前所述,处理调制解调器输出的唯一正确方法是将输出分成完整的行,然后一次迭代一行.

1 唯一的例外是在解析AT + CMGS响应数据时.

1 The only exception is when parsing AT+CMGS response data.

这篇关于AT命令响应(了解Arduino上代码执行的顺序)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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