ESP8266 crashes after simple http request

狂风中的少年 提交于 2021-02-08 11:35:53

问题


I am working with the NodeMCU V3 module. Whenever I try to make an http request to my server, the module crashes.

Here's the code:

void setup() {
    WiFi.begin("wifi-name", "wifi-password");  

    while (WiFi.status() != WL_CONNECTED) {  //Wait for the WiFI to connect }
}
void loop() {
   HTTPClient http; 
   WiFiClient client;

   http.begin( client, "server-address" );  

   int httpCode = http.GET();  
   String payload = http.getString();  //Get the response payload

   Serial.println(httpCode);   //Print HTTP return code
   Serial.println(payload);    //Print request response payload

   http.end();  //Close connection

   delay( 1000 );
}

Here's the result, as seen in the serial monitor:

200
["JSON response from the server"]

Exception (28):
epc1=0x40212e82 epc2=0x00000000 epc3=0x00000000 excvaddr=0x000001b6 depc=0x00000000

>>>stack>>>

ctx: cont
sp: 3ffffc90 end: 3fffffc0 offset: 01a0
3ffffe30:  00000000 4bc6a7f0 0000333f 3ffee5f8  
3ffffe40:  00000000 00000000 4bc6a7f0 00000000  
[...] 
3fffffb0:  feefeffe feefeffe 3ffe84e8 40100c41  
<<<stack<<<

The strange thing is that it retrieves the response from the server correctly, but then, about one second later, it spits out the exception to the serial monitor and resets. At first I thought it could be because I am running ESP8266WebServer at the same time, but it still crashes even when I run the most basic example I could find on the internet. I tried compiling the same code on the Arduino IDE instead of PlatformIO, or even using a different NodeMCU, to no avail.

EDIT: After playing around a bit more, it seems like setting the delay to at least 10 seconds makes the NodeMCU crash after 3 requests instead of after the first one. Could it be that it's memory overflows after a few requests? Am I missing a crucial part that should prepare the ESP8266 for a new request?


回答1:


There is no need to re-create the WiFi and HTTP clients in the loop() over and over again. You can declare them once globally. Here's a stable version of this simple sketch:

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESPHTTPClient.h>

HTTPClient http; 
WiFiClient client;

void setup() {
  Serial.begin(115200);
  Serial.println();
  WiFi.begin("****", "****");  

  Serial.print("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("done.");
}

void loop() {
  http.begin(client, "http://httpbin.org/get"); // <1KB payload
//  http.begin(client, "http://www.geekstips.com/esp8266-arduino-tutorial-iot-code-example/"); // 30KB payload

  int httpCode = http.GET();  
  String payload = http.getString();  //Get the response payload

  Serial.println(httpCode);   //Print HTTP return code
  Serial.println(payload);    //Print request response payload

  http.end();  //Close connection

  Serial.printf("Free heap: %d\n", ESP.getFreeHeap());
  delay(1000);
}

The reported free heap is very stable over time. Please take note of the second URL I added for testing in the commented line. That http.getString() is convenient and works well for small resources but yields unexpected i.e. wrong results for larger resources - you only see a small fraction of the body printed to the console.

For larger payloads you should use the low-level WiFiClient directly and read/parse the response line-by-line or character-by-character. See the documentation at https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/client-examples.html for a template.

void loop()
{
  WiFiClient client;

  Serial.printf("\n[Connecting to %s ... ", host);
  if (client.connect(host, 80))
  {
    Serial.println("connected]");

    Serial.println("[Sending a request]");
    client.print(String("GET /") + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +
                 "Connection: close\r\n" +
                 "\r\n"
                );

    Serial.println("[Response:]");
    while (client.connected() || client.available())
    {
      if (client.available())
      {
        String line = client.readStringUntil('\n');
        Serial.println(line);
      }
    }
    client.stop();
    Serial.println("\n[Disconnected]");
  }
  else
  {
    Serial.println("connection failed!]");
    client.stop();
  }
  delay(5000);
}


来源:https://stackoverflow.com/questions/59697417/esp8266-crashes-after-simple-http-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!