skaarj1989 / mWebSockets

WebSockets for microcontrollers
https://skaarj1989.github.io/mWebSockets/autobahn-testsuite/servers/
MIT License
108 stars 23 forks source link

Unable to ping IP of Arduino Uno (ATmega328) w/ W5500 after uploading simple-server.ino #44

Closed Perfectmistake closed 3 years ago

Perfectmistake commented 3 years ago

I have been able to successfully compile and upload simple-server.ino to my ATmega328 board with a W5500 Ethernet Shield, but I have noticed a few issues with it. Firstly, If I open the Serial Monitor, I obtain something like

14:28:02.662 -> ⸮x⸮⸮⸮

Secondly, when I try and ping the IP Address via a Terminal using an Ethernet connection connected to the same subnet as the Arduino, I cannot successfully ping it:

PING 198.162.1.177 (198.162.1.177) 56(84) bytes of data.
From 198.162.1.21 icmp_seq=1 Destination Host Unreachable
From 198.162.1.21 icmp_seq=2 Destination Host Unreachable
From 198.162.1.21 icmp_seq=3 Destination Host Unreachable

What could be causing these errors? For reference, here is the example I uploaded:

#include <WebSocketServer.h>
using namespace net;

#if PLATFORM_ARCH == PLATFORM_ARCHITECTURE_SAMD21
#  define _SERIAL SerialUSB
#else
#  define _SERIAL Serial
#endif

#if NETWORK_CONTROLLER == NETWORK_CONTROLLER_WIFI
constexpr char kSSID[]{"SKYNET"};
constexpr char kPassword[]{"***"};
#else
byte mac[]{0xA8, 0x61, 0x0A, 0xAE, 0x69, 0x13};
IPAddress ip(198, 162, 1, 177);

#endif

constexpr uint16_t port = 3000;
WebSocketServer wss{port};

void setup() {
  _SERIAL.begin(115200);
  while (!_SERIAL)
    ;

#if NETWORK_CONTROLLER == NETWORK_CONTROLLER_WIFI
  //_SERIAL.setDebugOutput(true);
  _SERIAL.printf("\nConnecting to %s ", kSSID);

  WiFi.mode(WIFI_STA);
  WiFi.begin(kSSID, kPassword);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    _SERIAL.print(F("."));
  }

  _SERIAL.println(F(" connected"));

  WiFi.printDiag(_SERIAL);

  _SERIAL.print(F("Device IP: "));
  _SERIAL.println(WiFi.localIP());
#else
  _SERIAL.println(F("Initializing ... "));

  // Ethernet.init(10);
  Ethernet.init(53); // Mega2560
  // Ethernet.init(5); // ESPDUINO-32
  // Ethernet.init(PA4); // STM32

  Ethernet.begin(mac, ip);

  _SERIAL.print(F("Server running at "));
  _SERIAL.print(Ethernet.localIP());
  _SERIAL.print(F(":"));
  _SERIAL.println(port);
#endif

  wss.onConnection([](WebSocket &ws) {
    const auto protocol = ws.getProtocol();
    if (protocol) {
      _SERIAL.print(F("Client protocol: "));
      _SERIAL.println(protocol);
    }

    ws.onMessage([](WebSocket &ws, const WebSocket::DataType dataType,
                   const char *message, uint16_t length) {
      switch (dataType) {
      case WebSocket::DataType::TEXT:
        _SERIAL.print(F("Received: "));
        _SERIAL.println(message);
        break;
      case WebSocket::DataType::BINARY:
        _SERIAL.println(F("Received binary data"));
        break;
      }

      ws.send(dataType, message, length);
    });

    ws.onClose([](WebSocket &, const WebSocket::CloseCode, const char *,
                 uint16_t) { _SERIAL.println(F("Disconnected")); });

    _SERIAL.print(F("New client: "));
    _SERIAL.println(ws.getRemoteIP());

    const char message[]{"Hello from Arduino server!"};
    ws.send(WebSocket::DataType::TEXT, message, strlen(message));
  });

  wss.begin();
}

void loop() { wss.listen(); }
skaarj1989 commented 3 years ago
  1. When you open the serial monitor, make sure that it is set to 115200 baud instead of default 9600
  2. Turn on debug output in config.h
Perfectmistake commented 3 years ago

After changing the values suggested, I now obtain this in my serial monitor:

Initializing...
Server running at 0.0.0.0:80

So somehow, my server is not being assigned the IP address I gave it

skaarj1989 commented 3 years ago

(...) my ATmega328 board

Take look at this:

Ethernet.init(53); // Mega2560
Perfectmistake commented 3 years ago

What do I need to change the init value to for a ATmega328 board?

skaarj1989 commented 3 years ago

10

Perfectmistake commented 3 years ago

Changing this number still does nothing, I still obtain:

Initializing...
Server running at 0.0.0.0:80
skaarj1989 commented 3 years ago

One more thing that you can do is to remove the IP address from begin()

Ethernet.begin(mac);
Perfectmistake commented 3 years ago

That doesn't work either. I still obtain the prior messages on my serial monitor with a long hang time between the two messages (around 1 minute between them)

skaarj1989 commented 3 years ago

Try to upload this sketch: File -> Examples -> Ethernet -> WebServer

Perfectmistake commented 3 years ago

The WebServer example works. This gives me the expected result

Ethernet WebServer Example
server is at 198.162.1.177
skaarj1989 commented 3 years ago

Then just copy init phase from the WebServer

Perfectmistake commented 3 years ago

Well that is still just Ethernet.init(10) so copying it over and moving it to the top of the setup() section does not change anything, I still do not get any IP address showing up.

skaarj1989 commented 3 years ago

By default the WebServer example does not use init() at all.

Perfectmistake commented 3 years ago

Even if the init line is commented out entirely, the code still does not function, whereas the WebServer example works fine.

skaarj1989 commented 3 years ago

This is very strange. Looks like some compiler/linker issue. Try to copy WebSocketServer to the WebServer sketch.

Perfectmistake commented 3 years ago

As in copy over WebSocketServer.h ?

skaarj1989 commented 3 years ago

No, I mean: Try to build your WebSocket server on the WebServer example.

Perfectmistake commented 3 years ago

Sorry, I am still a bit confused by what you are asking here. Coping over the simple-server.ino file into the WebServer does nothing and simply gives me the same result. In addition, I am also noticing that I get a warning when I compile this:

/home/user/Arduino/libraries/WebSocketServer.cpp:8:1: note: '__comp_dtor' was previously declared here
WebSocketServer::~WebSocketServer() { shutdown(); }
^
/home/user/Arduino/libraries/mWebSocketServer.cpp:8:1: note: code may be misoptimised unless -fno-strict-aliasing is used
skaarj1989 commented 3 years ago

I meant something like that:

#include <WebSocketServer.h>
using namespace net;

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177);

constexpr uint16_t port = 3000;
WebSocketServer wss{port};

void setup() {
  // You can use Ethernet.init(pin) to configure the CS pin
  //Ethernet.init(10);  // Most Arduino shields
  //Ethernet.init(5);   // MKR ETH shield
  //Ethernet.init(0);   // Teensy 2.0
  //Ethernet.init(20);  // Teensy++ 2.0
  //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
  //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Ethernet WebServer Example");

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start the server
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

  wss.onConnection([](WebSocket & ws) {
    const auto protocol = ws.getProtocol();
    if (protocol) {
      Serial.print(F("Client protocol: "));
      Serial.println(protocol);
    }

    ws.onMessage([](WebSocket & ws, const WebSocket::DataType dataType,
    const char *message, uint16_t length) {
      switch (dataType) {
        case WebSocket::DataType::TEXT:
          Serial.print(F("Received: "));
          Serial.println(message);
          break;
        case WebSocket::DataType::BINARY:
          Serial.println(F("Received binary data"));
          break;
      }

      ws.send(dataType, message, length);
    });

    ws.onClose([](WebSocket &, const WebSocket::CloseCode, const char *,
    uint16_t) {
      Serial.println(F("Disconnected"));
    });

    Serial.print(F("New client: "));
    Serial.println(ws.getRemoteIP());

    const char message[] {"Hello from Arduino server!"};
    ws.send(WebSocket::DataType::TEXT, message, strlen(message));
  });

  wss.begin();
}

void loop() {
  wss.listen();
}
Perfectmistake commented 3 years ago

Unfortunately, this still leads to the IP address not being detected

server is at 0.0.0.0

I am also still getting the same warning message

/home/user/Arduino/libraries/WebSocketServer.cpp:8:1: note: '__comp_dtor' was previously declared here
WebSocketServer::~WebSocketServer() { shutdown(); }
^
/home/user/Arduino/libraries/mWebSocketServer.cpp:8:1: note: code may be misoptimised unless -fno-strict-aliasing is used
skaarj1989 commented 3 years ago

For me, it works like a charm. Something is wrong with your environment. I can't help you if I cannot reproduce your issue.

Ethernet WebServer Example
server is at 192.168.46.180
Pinging 192.168.46.180 with 32 bytes of data:
Reply from 192.168.46.180: bytes=32 time<1ms TTL=128
Reply from 192.168.46.180: bytes=32 time<1ms TTL=128
Reply from 192.168.46.180: bytes=32 time<1ms TTL=128
Reply from 192.168.46.180: bytes=32 time<1ms TTL=128

Ping statistics for 192.168.46.180:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms
Perfectmistake commented 3 years ago

hmm I see, what do you mean by environment? As in the IDE version I am using (1.8.14)

skaarj1989 commented 3 years ago

Things I would do:

  1. Upgrade the IDE to latest version.
  2. Clean the Arduino cache (AppData/Local/Temp) image
Perfectmistake commented 3 years ago

Ok, ill have to find where these files are located since I am working in Linux OpenSUSE Leap 15.4

Perfectmistake commented 3 years ago

Ok so I have done the following:

  1. Updated Arduino IDE 1.8.14 to 1.8.15 running on OpenSUSE Leap 15.2
  2. There are few resources online regarding clearing the cache on an OpenSUSE system, some suggest that this should not be cached system wide.
  3. Redownloaded the master branch of mWebSockets and stored in with other libraries in /user/Home/Arduino/libraries/mWebSockets-master
  4. Double checked that WebServer returned the desired ip address when using Ethernet.localip(), which it does.
  5. Checked the Ethernet connection settings, which provides the following results:
    • IPv4 communication
    • IP Address: 198.162.1.21
    • Netmask: 255.255.255.0
    • Gateway: 0.0.0.0

All of these still haven't helped unfortunately. I still get the same warning described earlier

/home/user/Arduino/libraries/WebSocketServer.cpp:8:1: note: '__comp_dtor' was previously declared here
WebSocketServer::~WebSocketServer() { shutdown(); }
^
/home/user/Arduino/libraries/mWebSocketServer.cpp:8:1: note: code may be misoptimised unless -fno-strict-aliasing is used

and the local IP still isn't being picked up, indicating that the system is not connecting properly

Perfectmistake commented 3 years ago

If I explicitly specify the DNSserver, the gateway and the subnet inside the sketch and add the into Etherent.begin(), the appropriate IP address is now assigned. I suspect this issue was from a network connection issue as opposed to an Arduino hardware or software issue.

Thank you very much for your help!!