gpt4 book ai didi

c - Arduino ESP8266 Softwareserial 没有足够的缓冲区大小用于 HTTP 获取请求

转载 作者:行者123 更新时间:2023-12-01 11:48:03 24 4
gpt4 key购买 nike

我正在做一个项目,我使用 arduino uno 和 ESP8266ex 作为 wifi 模块。电线的连接:

Arduino 5V --> 3.3V Regulator --> ESP:CH_PD(带 10k 电阻)和 VCC Arduino GND --> 3.3V Regulator --> ESP:GND 和 RST(通过按钮和电阻连接复位) Arduino RX - -> ESP TX Arduino TX--> 分压器(2k 1k 电阻)--> ESP RX 5uF 电容器--> 稳压器以防止 ESP 自行复位。

现在让我解释一下我遇到的问题。我有两个代码正在处理,我使用 ESP8266 作为 arduino uno 的 wifi 模块。在我的第一个程序中,我手动发送了命令:

#define ard_rx_esp_tx 2
#define ard_tx_esp_rx 3

#include <SoftwareSerial.h>

SoftwareSerial ESPserial(ard_rx_esp_tx, ard_tx_esp_rx); // RX | TX

void setup()
{
int i = 0;
Serial.begin(9600); // communication with the host computer
while (!Serial);

// Start the software serial for communication with the ESP8266
ESPserial.begin(9600);
Serial.println("");
Serial.println(F("Remember to to set Both NL & CR in the serial monitor."));
Serial.println(F("Ready"));
Serial.println(F(""));
Serial.println(F("start"));
delay(1000);
}
void loop()
{

if ( ESPserial.available() ) {
char c = ESPserial.read();
Serial.print(c);
}

if ( Serial.available() ) {
ESPserial.write( Serial.read() );
}
}

我成功打开与服务器的 TCP 连接,发送一个长(超过 600 个字符)的 GET 请求,并通过 SoftwareSerial read() 函数处理所有长响应并将它们全部打印到串行监视器。简而言之,此代码可以处理服务器的 600+ 字符响应,即:

enter image description here

目的是通过“SoftwareSerial.print()”发送这些 AT 命令,并将整个响应放入字符数组中以解析其 API-KEY。到目前为止我为此编写的代码:
#define ard_rx_esp_tx 2
#define ard_tx_esp_rx 3
char response[625];
#include <SoftwareSerial.h>
SoftwareSerial ESPserial(ard_rx_esp_tx, ard_tx_esp_rx); // RX | TX
int i;

void setup()
{

Serial.begin(9600); // communication with the host computer
while (!Serial);

// Start the software serial for communication with the ESP8266
ESPserial.begin(9600);

Serial.println("");
Serial.println(F("Remember to to set Both NL & CR in the serial monitor."));
Serial.println(F("Ready"));
Serial.println(F(""));
Serial.println(F("start"));
delay(1000);

ESPserial.println("AT+CIPSTART=\"TCP\",\"domainname\",80");
delay(5000);

i = 0;
while ( ESPserial.available() ) {
response[i] = ESPserial.read();
i++;
}
response[i++] = '\0';
Serial.println(response);
for (i = 0; i < 625; i++) {
response[i] = '\0';
}

ESPserial.println("AT+CIPSEND=107");
delay(5000);

i = 0;
while ( ESPserial.available() ) {
response[i] = ESPserial.read();
i++;
}
response[i++] = '\0';
Serial.println(response);
for (i = 0; i < 625; i++) {
response[i] = '\0';
}

ESPserial.println("GET request to the server which has length 107 as indicated");
delay(5000);

i = 0;
while ( ESPserial.available() ) {
response[i] = ESPserial.read();
i++;
}
response[i++] = '\0';
Serial.println(response);
for (i = 0; i < 625; i++) {
response[i] = '\0';
}
}
void loop() {
// put your main code here, to run repeatedly:

}

它在“setup()”范围的末尾打印响应。让我也放输出的照片:

enter image description here

总之,问题是:SoftwareSerial 有 64 字节缓冲区,可以增加到 256 字节,当我增加它时,程序这次能够打印 256 个字符,但是,在我的第一个代码中,我手动发送了 AT 命令,尽管它有 64 字节的缓冲区,但它可以处理整个响应,并且能够将其打印到串行监视器。在第二个中,我无法处理整个响应并将其存储到 char 数组中。

我希望我能解释我的问题,并详细指出我在我的过程中的确切位置。

你建议我怎么做。在处理这个大响应并将其放入字符数组时我能做什么?如何处理最初停留在 ESP8266ex 缓冲区上并通过 SoftwareSerial 类由 Arduino RX 引脚读取的整个响应,其中函数 read() 具有 64 字节数组并且可以增加到 256 但不能再增加?

最佳答案

所以,这里的问题都是关于时间的。您知道您对软件串行的缓冲区大小有限制(对于任何硬件 UART 也是如此),即 256 字节,波特率为 9600 位/秒。

由于有一个起始位、8 个数据位和一个停止位(假设您在这里使用 9600 8N1,因为它是最常见的),您将每 (1/9600) * 10 - 秒或 1.04 接收一个数据字节毫秒。因此,要接收 256 个字节,大约需要 266 毫秒。这意味着 266 毫秒后,您的缓冲区将完全充满,之后您收到的任何内容都将开始删除之前收到的数据。

这就是问题的症结所在-您正在向 ESP 发送命令以从服务器接收数据,然后休眠 5 秒钟,这意味着没有任何东西从缓冲区中提取数据,因此它会回绕,导致数据丢失。串行缓冲区的重点不是保存您将在单个点接收的整个数据集,而是保存足够长的时间直到您可以将其读出,这就是它们通常很小的原因。

您需要做的是发送命令,让您的 Arduino 立即运行代码以尽可能快地从缓冲区检索数据,直到找到预期的结束或超时。

像这样基本的东西会让你继续前进:

char espBuffer[1024] = {0};
int readCount = 0;
long startTime = millis();

ESPserial.println("AT+CIPSTART=\"TCP\",\"domainname\",80");

while (millis() - startTime < 5000) { // Run for at least 5 seconds
// Check to make sure we don't exceed espBuffer's boundaries
if (ESPserial.available() > readCount + sizeof espBuffer - 1)
break;
readCount += ESPserial.readBytes(espBuffer + readCount, ESPserial.available());
}

Serial.println(espBuffer);

现在,您需要修改此代码,使其在收到所有预期的数据后结束。此外,这个简单的设置将响应的最大大小限制为 1023 字节,这也没有太大帮助。理想情况下,您会一直阅读,直到找到 HTTP 正文,然后丢弃其他所有内容,这意味着查找数据的缓冲区很小,而实际存储正文的缓冲区可能要大得多。

关于c - Arduino ESP8266 Softwareserial 没有足够的缓冲区大小用于 HTTP 获取请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38372030/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com