Links2004 / arduinoWebSockets

arduinoWebSockets
GNU Lesser General Public License v2.1
1.86k stars 551 forks source link

ENC28J60 WebsocketClient connection drops after 20-30min of use #653

Open slowpoison4 opened 3 years ago

slowpoison4 commented 3 years ago

Hi,

I have a NodeJS ws server running and my ESP8266 connected to ENC28J60 acts as a websocket client. The connection gets established and everything works fine initially. But after 20 to 30 min the connection just drops and doesn't reconnect again. I am sending JSON packets to the server from my device. I am using the basic Websocket client code.

The ENC28J60 does run hot. I've given it external power supply of 3.3V. The supply is capable of delivering up to 1A of continuous current. I've tried 2-3 different modules but ends up with the same problem. I'm unsure what is going on. My connection is as per the following link: https://github.com/UIPEthernet/UIPEthernet/blob/master/hardware/NodeMCU_enc28j60_wiring.PNG

Ive not used the BS170 transistors. Instead i manually disconnect the D8 (cs) pin during upload and wait for the [SETUP] BOOT WAIT 4... and insert it. I get the IP Address localIP: 192.168.0.108 subnetMask: 255.255.255.0 gatewayIP: 192.168.0.1 dnsServerIP: 192.168.0.1

It connects to my websocket server and exchanges all the messages successfully for 20-30min. after which it fails. I have another ESP8266 connected to my UART0 which sends the JSON packets. The ENC28J60 system only acts as a transmitter and receiver for ETH websocket connection

My Code:

/*
   WebSocketClient.ino

*/
#define WEBSOCKETS_NETWORK_TYPE NETWORK_ENC28J60
#include <Arduino.h>
#include <WebSocketsClient.h>
#include <Hash.h>
#include <UIPEthernet.h>
#include <ArduinoJson.h>
//------------------------------------------------DEFINITIONS----------------------------------------------------------------
#define USE_SERIAL Serial1
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0x5E, 0xA9, 0xBE, 0xE7, 0xFE, 0xED };

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192, 168, 1, 177);
WebSocketsClient webSocket;
EthernetClient client;
EthernetClient dclient;
//---------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------GLOBAL-VARIABLES-----------------------------------------------------------
bool configCheck = false;
bool configEnd = false;
String serverAddress, path, deviceID, protocol;
int serverPort;
String username, password, URL, portFTP, pathFTP, location, fileName, pathFile, retrieve_date, startTime, stopTime;
int Index1, Index2, Index3, Index4, Index5, Index6;
char outBuf[128];
char outCount;
int port;
bool ftp_download_flag = true;
//---------------------------------------------------------------------------------------------------------------------------

//---------------------------------------------------------------------------------------------------------------------------
void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) {

  switch (type) {
    case WStype_DISCONNECTED:
      USE_SERIAL.printf("[WSc] Disconnected!\n");
      eth_sendMessage("ETHWSCDISCONNECTED");
      break;
    case WStype_CONNECTED:
      {
        USE_SERIAL.printf("[WSc] Connected to url: %s\n",  payload);
        eth_sendMessage("ETHSENDBOOTNOTIFICATION");
      }
      break;
    case WStype_TEXT:
      USE_SERIAL.printf("[WSc] get text: %s\n", payload);
      recv_message(payload);

      // send message to server
      // webSocket.sendTXT("message here");
      break;
    case WStype_BIN:
      USE_SERIAL.printf("[WSc] get binary lenght: %u\n", lenght);
      hexdump(payload, lenght);

      // send data to server
      // webSocket.sendBIN(payload, lenght);
      break;
  }

}
void call_response(String message)
{
   webSocket.sendTXT(message);
}

void recv_message(uint8_t * payload)
{
   webSocket.loop();
  String message;
  USE_SERIAL.println("Inside Recieve Message Function");
  message = String((char *)payload);
  USE_SERIAL.println(message);
  DynamicJsonDocument doc(2048);
  deserializeJson(doc, payload);
  String Action = doc[2];
    eth_sendMessage(message);
}

void eth_sendMessage(String message)
{
  webSocket.loop();
  message = message + '\n';
  Serial.print(message);
  USE_SERIAL.println(message);
}

void setup() {
  // USE_SERIAL.begin(921600);
  USE_SERIAL.begin(115200);
  Serial.begin(115200);
  //Serial.setDebugOutput(true);
  USE_SERIAL.setDebugOutput(false);

  USE_SERIAL.println();
  USE_SERIAL.println();
  USE_SERIAL.println();

  for (uint8_t t = 4; t > 0; t--) {
    USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
    USE_SERIAL.flush();
    delay(1000);
  }
  //Ethernet.init(10);

  if (Ethernet.begin(mac) == 0) {
    USE_SERIAL.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
    eth_sendMessage("DAETHOFF");
  } else {
    USE_SERIAL.print("localIP: ");
    USE_SERIAL.println(Ethernet.localIP());
    USE_SERIAL.print("subnetMask: ");
    USE_SERIAL.println(Ethernet.subnetMask());
    USE_SERIAL.print("gatewayIP: ");
    USE_SERIAL.println(Ethernet.gatewayIP());
    USE_SERIAL.print("dnsServerIP: ");
    USE_SERIAL.println(Ethernet.dnsServerIP());

  webSocket.begin("192.168.0.115",8080, "/TEST001","ccp1.6");
  webSocket.onEvent(webSocketEvent);
  webSocket.setReconnectInterval(5000);
  webSocket.enableHeartbeat(37000, 7000, 5);
}

void communication()
{
  if (Serial.available() > 0)
  {
     webSocket.loop();
    String recvControllerMsg = Serial.readStringUntil('\n');
    USE_SERIAL.println(recvControllerMsg);
    if (recvControllerMsg.equals("ETHRESET"))
    {
      ESP.restart();
    }
    else
    {
      webSocket.sendTXT(recvControllerMsg);
    }
  }
}

void loop() {
  webSocket.loop();
  communication();
}
Links2004 commented 3 years ago

are you still able to ping the ESP via the ENC28J60 when this happens?

slowpoison4 commented 3 years ago

The ESP works since it communicates with the other main controller. But ENC28j60 never reconnects. It works again when i restart the ESP8266. Sometimes not immediately. takes like 3-4 resets for it to work again

Links2004 commented 3 years ago

what I where trying to check with this is if the ENC28j60 is still working and communicating with the ESP. ping will only work when the ENC28j60 sends the data to the ESP and the ESP instructs the ENC28j60 to answer with a ping. if ping or any other connection is not working the problem is with the ENC28j60 or the ENC28j60 lib for sure and its nothing that can be fixed a the websocket level.

one other thing to check is if you are using DHCP is if the not working comes in the same time frame with a DHCP renew. a simple test for this is to do the config statically and it is working then its related to DHCP problems. from looking at your code I miss the call to maintain of UIPEthernet.h which will handle the DHCP renew

enabling the debug output ouf the lib will help too to see whats going on ;)

https://github.com/UIPEthernet/UIPEthernet/blob/0e823e59fc5a16dc96d4ba90d3b515ec0d0adb14/UIPEthernet.h#L96-L100

slowpoison4 commented 3 years ago

Hi,

I tried adding Ethernet.maintain() to my void loop. still having the same problem. Ive enabled the websockets debug output. This is what im getting:

[WS][0][sendFrame] fin: 1 opCode: 10 mask: 1 length: 0 headerToPayload: 0 09:58:14.894 -> [write] n: 6 t: 2841841 09:58:14.894 -> [WS][0][sendFrame] sending Frame Done (2511us). 09:58:31.874 -> [WS-Client] sending HB ping 09:58:31.874 -> [WS][0][sendFrame] ------- send message frame ------- 09:58:31.874 -> [WS][0][sendFrame] fin: 1 opCode: 9 mask: 1 length: 0 headerToPayload: 0 09:58:31.874 -> [write] n: 6 t: 2858797 09:58:31.874 -> [WS][0][sendFrame] sending Frame Done (2326us). 09:58:31.874 -> [WS][0][handleWebsocketWaitFor] size: 2 cWsRXsize: 0 09:58:31.874 -> [readCb] n: 2 t: 2858814 09:58:31.874 -> [WS][0][handleWebsocketWaitFor][readCb] size: 2 ok: 1 09:58:31.874 -> [WS][0][handleWebsocket] ------- read massage frame ------- 09:58:31.874 -> [WS][0][handleWebsocket] fin: 1 rsv1: 0 rsv2: 0 rsv3 0 opCode: 10 09:58:31.874 -> [WS][0][handleWebsocket] mask: 0 payloadLen: 0 09:58:31.874 -> [WS][0][handleWebsocket] get pong () 09:58:51.882 -> [WS][0][handleWebsocketWaitFor] size: 2 cWsRXsize: 0 09:58:51.882 -> [readCb] n: 2 t: 2878814 09:58:51.882 -> [WS][0][handleWebsocketWaitFor][readCb] size: 2 ok: 1 09:58:51.882 -> [WS][0][handleWebsocket] ------- read massage frame ------- 09:58:51.882 -> [WS][0][handleWebsocket] fin: 1 rsv1: 0 rsv2: 0 rsv3 0 opCode: 9 09:58:51.882 -> [WS][0][handleWebsocket] mask: 0 payloadLen: 0 09:58:51.882 -> [WS][0][handleWebsocket] ping received () 09:58:51.882 -> [WS][0][sendFrame] ------- send message frame ------- 09:58:51.882 -> [WS][0][sendFrame] fin: 1 opCode: 10 mask: 1 length: 0 headerToPayload: 0 09:58:51.882 -> [write] n: 6 t: 2878845 09:58:51.882 -> [WS][0][sendFrame] sending Frame Done (2411us). 09:59:08.862 -> [WS-Client] sending HB ping 09:59:08.862 -> [WS][0][sendFrame] ------- send message frame ------- 09:59:08.862 -> [WS][0][sendFrame] fin: 1 opCode: 9 mask: 1 length: 0 headerToPayload: 0 09:59:08.862 -> [write] n: 6 t: 2895806 09:59:08.862 -> [WS][0][sendFrame] sending Frame Done (2318us). 09:59:08.862 -> [WS][0][handleWebsocketWaitFor] size: 2 cWsRXsize: 0 09:59:08.862 -> [readCb] n: 2 t: 2895827 09:59:08.862 -> [WS][0][handleWebsocketWaitFor][readCb] size: 2 ok: 1 09:59:08.862 -> [WS][0][handleWebsocket] ------- read massage frame ------- 09:59:08.862 -> [WS][0][handleWebsocket] fin: 1 rsv1: 0 rsv2: 0 rsv3 0 opCode: 10 09:59:08.862 -> [WS][0][handleWebsocket] mask: 0 payloadLen: 0 09:59:08.862 -> [WS][0][handleWebsocket] get pong () 09:59:28.880 -> [WS][0][handleWebsocketWaitFor] size: 2 cWsRXsize: 0 09:59:28.880 -> [readCb] n: 2 t: 2915828 09:59:28.880 -> [WS][0][handleWebsocketWaitFor][readCb] size: 2 ok: 1 09:59:28.880 -> [WS][0][handleWebsocket] ------- read massage frame ------- 09:59:28.880 -> [WS][0][handleWebsocket] fin: 1 rsv1: 0 rsv2: 0 rsv3 0 opCode: 9 09:59:28.880 -> [WS][0][handleWebsocket] mask: 0 payloadLen: 0 09:59:28.880 -> [WS][0][handleWebsocket] ping received () 09:59:28.880 -> [WS][0][sendFrame] ------- send message frame ------- 09:59:28.880 -> [WS][0][sendFrame] fin: 1 opCode: 10 mask: 1 length: 0 headerToPayload: 0 09:59:28.880 -> [write] n: 6 t: 2915858 09:59:28.880 -> [WS][0][sendFrame] sending Frame Done (2411us). 09:59:45.879 -> [WS-Client] sending HB ping 09:59:45.879 -> [WS][0][sendFrame] ------- send message frame ------- 09:59:45.879 -> [WS][0][sendFrame] fin: 1 opCode: 9 mask: 1 length: 0 headerToPayload: 0 09:59:45.879 -> [write] n: 6 t: 2932815 09:59:45.879 -> [WS][0][sendFrame] sending Frame Done (2328us). 09:59:45.879 -> [WS][0][handleWebsocketWaitFor] size: 2 cWsRXsize: 0 09:59:45.879 -> [readCb] n: 2 t: 2932838 09:59:45.879 -> [WS][0][handleWebsocketWaitFor][readCb] size: 2 ok: 1 09:59:45.879 -> [WS][0][handleWebsocket] ------- read massage frame ------- 09:59:45.879 -> [WS][0][handleWebsocket] fin: 1 rsv1: 0 rsv2: 0 rsv3 0 opCode: 10 09:59:45.879 -> [WS][0][handleWebsocket] mask: 0 payloadLen: 0 09:59:45.879 -> [WS][0][handleWebsocket] get pong () 10:00:22.867 -> [WS-Client] sending HB ping 10:00:22.867 -> [WS][0][sendFrame] ------- send message frame ------- 10:00:22.867 -> [WS][0][sendFrame] fin: 1 opCode: 9 mask: 1 length: 0 headerToPayload: 0 10:00:22.867 -> [write] n: 6 t: 2969824 10:00:22.867 -> [WS][0][sendFrame] sending Frame Done (2409us). 10:00:29.832 -> [HBtimeout] pong TIMEOUT! lp=2939331 millis=2976831 pi=7001 count=1 10:00:29.866 -> [WS-Client] sending HB ping 10:00:29.866 -> [WS][0][sendFrame] ------- send message frame ------- 10:00:29.866 -> [WS][0][sendFrame] fin: 1 opCode: 9 mask: 1 length: 0 headerToPayload: 0 10:00:29.866 -> [write] n: 6 t: 2976839 10:00:29.866 -> [WS][0][sendFrame] sending Frame Done (2388us). 10:00:36.844 -> [HBtimeout] pong TIMEOUT! lp=2946346 millis=2983846 pi=7001 count=2 10:00:36.879 -> [WS-Client] sending HB ping 10:00:36.879 -> [WS][0][sendFrame] ------- send message frame ------- 10:00:36.879 -> [WS][0][sendFrame] fin: 1 opCode: 9 mask: 1 length: 0 headerToPayload: 0 10:00:36.879 -> [write] n: 6 t: 2983854 10:00:36.879 -> [WS][0][sendFrame] sending Frame Done (2313us). 10:00:43.909 -> [HBtimeout] pong TIMEOUT! lp=2953361 millis=2990861 pi=7001 count=3 10:00:43.909 -> [WS-Client] sending HB ping 10:00:43.909 -> [WS][0][sendFrame] ------- send message frame ------- 10:00:43.909 -> [WS][0][sendFrame] fin: 1 opCode: 9 mask: 1 length: 0 headerToPayload: 0 10:00:43.909 -> [write] n: 6 t: 2990869 10:00:43.909 -> [WS][0][sendFrame] sending Frame Done (2348us). 10:00:50.902 -> [HBtimeout] pong TIMEOUT! lp=2960376 millis=2997876 pi=7001 count=4 10:00:50.937 -> [WS-Client] sending HB ping 10:00:50.937 -> [WS][0][sendFrame] ------- send message frame ------- 10:00:50.937 -> [WS][0][sendFrame] fin: 1 opCode: 9 mask: 1 length: 0 headerToPayload: 0 10:00:50.937 -> [write] n: 6 t: 2997884 10:00:50.937 -> [WS][0][sendFrame] sending Frame Done (2400us). 10:00:57.921 -> [HBtimeout] pong TIMEOUT! lp=2967391 millis=3004891 pi=7001 count=5 10:00:57.921 -> [HBtimeout] count=5, DISCONNECTING 10:00:57.921 -> [WS-Client] client disconnected. 10:00:57.921 -> [WSc] Disconnected! 10:01:22.897 -> [WS-Client] connection to 192.168.0.115:8080 Failed 10:01:22.897 -> ETHWSCDISCONNECTED 10:01:22.897 -> 10:01:22.897 -> [WS-Client] client disconnected. 10:01:22.897 -> [WSc] Disconnected! 10:01:22.897 -> ETHWSCDISCONNECTED 10:01:22.897 -> 10:01:52.921 -> [WS-Client] connection to 192.168.0.115:8080 Failed 10:01:52.921 -> [WS-Client] client disconnected. 10:01:52.921 -> [WSc] Disconnected!

as you can see, it works perfectly fine and then suddenly the Ping-pong connection stops being able to send and receive.

EDIT: I put Ethernet.linkStatus() to be checked periodically in my void loop (every10s). it returns 1 even after the websocket is disconnected. do this mean that the ESP is able to communicate with the ENC? EDIT2: I removed the LAN cable from the module and the LinkStatus value returned 2. So im sure the ENC module is able to communicate with the ESP.

Links2004 commented 3 years ago

ok strange the log shows that the Websocket code sends a ping and the ENC says it has send it, but after 5 pings and no pongs the code declares the current connection dead and tries to create a new one and only gets failed from the ENC.

form the websocket side the code does what it is designed to do (on to many ping fails create a new connection). but why no nonnection is possible is a good question, have you used tcpdump or wireshark to check if you see any SYN/ACK or any other traffic from the ENC on you network when the problem starts?

currently this looks like a problem in the lower levels (ENC or Network) to me.

d-a-v commented 3 years ago

If I may, FWIW, there's another enc28j60 driver integrated with the network stack in the git version of the esp8266 arduino core.

slowpoison4 commented 3 years ago

@Links2004 ill try wireshark and check. @d-a-v Ill try the esp8266 version of the repo and get back to you

slowpoison4 commented 3 years ago

Hi @Links2004 Sorry it took me time to respond back. Was busy with work. I tried everything to see what caused the problem. Eventually i decided to try w5100 and a Mega. It works like a charm. But i am limited by the Mega's capabilities and wish to connect to either ESP8266 or ESP32.

  1. Create a system that can connect to my Ws server either by Ethernet or WiFi. I am unsure how to go about this as the Network selection is done at compile time.By default it will try for Ethernet. But if its not connected, then fallback to wifi.
  2. What are the connections for w5100 shield to ESP8266 or ESP32? I changed the definition to w5100 in websocket.h but it never initialized(Connections: i just replaced the ENC28j60 to W5100(tried both ICSP pins and regular Pins.was not successful in both)). I couldn't find any guides for 8266 or 32 with w5100 although i read saying it supports it, Strange.
d-a-v commented 3 years ago

Speaking of the integrated drivers in the git version of the esp8266 arduino core, you can use an ethernet chip (W5500, W5100, enc28j60). The esp will connect to wifi or ethernet whatever is powered on and configured - or on which a dhcpserver will answer first. These boards connect through the standards SPI GPIOs (MISO, MOSI, CLK, vcc, gnd) + the CS/SS pin (name: ChipSelect or SlaveSelect though any free GPIO pin that you chose and give to the board c++ constructor).