esp8266 / Arduino

ESP8266 core for Arduino
GNU Lesser General Public License v2.1
15.99k stars 13.33k forks source link

ESP8266HTTPClient error -1 #6180

Closed Loucotolo closed 4 years ago

Loucotolo commented 5 years ago

Basic Infos

Platform

Settings in IDE

Problem Description

Hello, I have the following problem: I am using a esp8266, via an httpclient to connect to a server, but after some time (random), it returns me the following error: httpCode: -1 (Connection Refused). With wireshark I noticed that it [TCP PORT numbers reused] 57490-> 8000 [SYN].

I would like to know what I am doing wrong in my code to receive this error.

[Sketch]

#include <Arduino.h>
#include <ESP8266WiFi.h> /// fix http://blog.flynnmetrics.com/uncategorized/esp8266-exception-3/
#include <ESP8266HTTPClient.h>
//#include <WiFiClient.h>
#include <ESPAsyncWebServer.h>
#include <ArduinoJson.h>
#include <ESP8266httpUpdate.h>
#include <Hash.h>
#include <FS.h>
#include <user_interface.h> //Biblioteca necessaria para acessar os Timer`s.

#include "OneButton.h" // https://github.com/mathertel/OneButton
#include <EEPROM.h>
#include <WiFiUdp.h>

bool connect2WiFI()
{

  WiFi.setAutoReconnect( true );

#if (ADEBUG == 1 )
  Serial.printf("Wifi State changed to %s\n", WlStatusToStr(WiFi.status()));
#endif

  WiFi.persistent(false);   // Solve possible wifi init errors (re-add at 6.2.1.16 #4044, #4083)
  WiFi.disconnect(true);    // Delete SDK wifi config
  delay(200);
  WiFi.mode(WIFI_STA);      // Disable AP mode
  WiFi.setSleepMode(WIFI_MODEM_SLEEP);  // Disable sleep (Esp8288/Arduino core and sdk default)

  WiFi.begin("DEMO", "DEMO");

  uint32_t AwifiTimeout = 20000;
  uint32_t maxTime = millis() + AwifiTimeout;

  while ((WiFi.status()  != WL_CONNECTED) && (millis() < maxTime)) {
    yield();
  }

  if (WiFi.status()  != WL_CONNECTED)
  {

    return false;
  }

  Serial.println(WiFi.localIP());         // Send the IP address of the ESP8266 to the computer

  return true;

}

bool test()
{

more_send_data:

  int txlen = 0;

  WiFiClient client;

  HTTPClient http;

  http.setTimeout(500); // 500ms
  String md_ip = "192.168.0.31";
  String md_port = "8000";
  String path = "http://" + md_ip + ":" + md_port + "/index.php";

  const char * headerkeys[] = {"Set-Cookie", "Cookie"} ;
  size_t headerkeyssize = sizeof(headerkeys) / sizeof(char*);

  http.begin(client, path);    //Specify request destination
  //  http.begin(path);
  http.addHeader("Content-Type", "application/json");  //Specify content-type header

  http.collectHeaders(headerkeys, headerkeyssize);

  int httpCode = http.POST("Hello");  //Send the request
  String payload = http.getString();                                        //Get the response payload

  if (httpCode > 0)
  {

    if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {

      http.end();  //Close connection

      return true;

    } // end  payload != ""

    client.stop();
    http.end();  //Close connection

    return true;
  }

  Serial.print("httpCode:");
  Serial.println(httpCode, DEC );

  http.end();  //Close connection
  return false;
}

void setup() {
  // put your setup code here, to run once:

  WiFi.mode(WIFI_STA);

  EEPROM.begin(512);

  Serial.begin(115200);
connect2WiFI();
}

void loop() {
  // put your main code here, to run repeatedly:

  test();

  delay(500);
}

Debug Messages

16:33:26.338 -> 192.168.0.192 16:33:34.254 -> pm open,type:2 0 16:33:37.970 -> httpCode:-1

wireshark report : https://mega.nz/#!jJ4wRIyQ!6ayDTjoxEgaxO82yBo-0I4PwqH33TpPVC9XijBe2EXg

d-a-v commented 4 years ago

To summarize: when library is not used, httpclient works. When library is used, httpclient sometimes does not work. When it does not work, it is unrelated to the sensor library: httpclient request is asking for some version. Relevant code is

    HTTPClient updHttp;
    updHttp.setReuse(true);
    updHttp.begin(fwVerURL);

    int httpCode = updHttp.GET();

    Serial.println("HTTP Respose Code: " + String(httpCode));

    if (httpCode == 200) {
      String newFwTmpVersion = updHttp.getString();
      Serial.println("HTTP Update Version: " + newFwTmpVersion);
    } else {
      Serial.println("Error HTTP Update!");
    }
    updHttp.end();

Can you enable terminal timestamp and show an error with all debug options enabled ? Better, also with these prints (so we know when things happen) even better, with the wireshark log matching timestamp (netdump, netdumpv2 would have been useful here)

Serial.print("t1");
    HTTPClient updHttp;
    updHttp.setReuse(true);
    updHttp.begin(fwVerURL);
Serial.print("t2");

    int httpCode = updHttp.GET();
Serial.print("t3");

    Serial.println("HTTP Respose Code: " + String(httpCode));

    if (httpCode == 200) {
      String newFwTmpVersion = updHttp.getString();
      Serial.println("HTTP Update Version: " + newFwTmpVersion);
    } else {
      Serial.println("Error HTTP Update!");
    }
    updHttp.end();
beicnet commented 4 years ago

@d-a-v Thank you for replying, your summation is 99% correct.

with Function Enabled:

t1t2:ref 1
:ctmo
:abort
:ur 1
:dsrcv 0
:del
t3HTTP Response Code: -1
Error HTTP Update!
t1t2:ref 1
:ctmo
:abort
:ur 1
:dsrcv 0
:del
t3HTTP Response Code: -1
Error HTTP Update!
t1t2:ref 1
:ctmo
:abort
:ur 1
:dsrcv 0
:del
t3HTTP Response Code: -1
Error HTTP Update!

with Function Disabled:

t1t2:ref 1
:wr 185 0
:wrc 185 185 0
:ack 185
:rn 378
t3HTTP Response Code: 200
:c0 1, 378
HTTP Update Version: 3.9
:close
:ur 1
:dsrcv 0
:del
t1t2:ref 1
:wr 185 0
:wrc 185 185 0
:ack 185
:rn 378
t3HTTP Response Code: 200
:c0 1, 378
HTTP Update Version: 3.9
:close
:ur 1
:dsrcv 0
:del
t1t2:ref 1
:wr 185 0
:wrc 185 185 0
:ack 185
:rn 378
t3HTTP Response Code: 200
:c0 1, 378
HTTP Update Version: 3.9
:close
:ur 1
:dsrcv 0
:del

Also I tried to implement the ArduinoHttpClient.h library from another source, but got almost the same results.

d-a-v commented 4 years ago

With console timestamps + wireshark, or with one of the two netdumps, as described above, we will be able to check if packets are arriving onto the esp during the http timeout.

beicnet commented 4 years ago

@d-a-v I accidentally found out the solution,...

I put my hand onto PN532 module and it's started to give correct reading/requests. If I removed my hand from it then I got bad reading/requests again.

And it's no matter how long cable you will put on the PN532 module (10cm or 20cm) or distance you put the module from ESP device.

Even after I taped Copper foil on the back of the PN532 module wouldn't do nothing.

@earlephilhower was almost right about one thing, but it was not the RF signal interference, it was the EMI impulses so hard that it was killing the whole ESP device.

So, I made an ESD cage for the PN532 module from Aluminium and Copper adhesive tape over Plexiglas stand.

Sorry for bother you, now we know a little bit more about red PN532 module and how can be used properly.

earlephilhower commented 4 years ago

Thanks for the follow up, @beicnet ! You may want to post something about this on the Adafruit library github so they can put it in their readme.md.

beicnet commented 4 years ago

@earlephilhower I already did that before 6 days ago, nobody replayed (nor interested), so I closed the issue yesterday on the Adafruits GIT page.

Anyway I got immediate response and better support here! :1st_place_medal: :wink: