arduino-libraries / Ethernet

Ethernet Library for Arduino
http://arduino.cc/
257 stars 262 forks source link

Fix enum redeclaration issue when using WiFi and Ethernet for EthernetLinkStatus #260

Open rpineau opened 5 months ago

rpineau commented 5 months ago

When using other library that also declare this enum there is a conflict and triggers a compiler error. Adding the #ifdef fixes the issue as if it's already declared in another include (arduino pico code for wifi from earlephilhower for example) there will not be a re-declaration.

diff --git a/src/Ethernet.h b/src/Ethernet.h
index 0045de8..73abfa3 100644
--- a/src/Ethernet.h
+++ b/src/Ethernet.h
@@ -53,11 +53,14 @@
 #include "Server.h"
 #include "Udp.h"

+#ifndef __EthernetLinkStatus__
+#define __EthernetLinkStatus__
 enum EthernetLinkStatus {
-       Unknown,
-       LinkON,
-       LinkOFF
+       Unknown,
+       LinkON,
+       LinkOFF
 };
+#endif

 enum EthernetHardwareStatus {
        EthernetNoHardware,
JAndrassy commented 5 months ago

why would you use this Ethernet library together with the Pico Core WiFi library? as you know, there is a library for W5500 which works over same LwIP stack as WiFi in Pico Core (I care because I added EthernetLinkStatus to Pico Core)

rpineau commented 5 months ago

I see your other question on the issue I opened for the Pico. I use the standard Ethernet library as I ported some of my code from Arduino DUE to RP2040 (pico) and when both the standard Ethernet library and the pico WiFi library are used they both define this. The lwIP_w5500 from the pico is not a 1:1 mapping to the Ethernet library specially for the WiFiServer versus the EthernetServer

JAndrassy commented 5 months ago

WiFiServer versus the EthernetServer

are you sure the difference matters for your sketch? can't you use accept()?

rpineau commented 5 months ago

The main issue is in the configuration of the interface (and yes I do use accept). the Ethernet.init is totally different but I can pre-declare the server with the CS ping for it. That's the easy part. The main issue I would say is that the begin methods are not matching and the WiFiServer class uses a config call for the IPAdress and associated variables. There is no "proper" example of a server so I guess I'll have to experiment to see if I need to call begin before config or after (specially in the case where I try dhcp first and if it fails reconfigure with a know default ip address).

The goal was to add wifi support to replace a XBee on my project (and still use Ethernet as the main communication path to the device).

JAndrassy commented 5 months ago

WiFiServer doesn't have config. The WiFi/Ethernet class has config for static IP configuration and it works the same for both.

https://github.com/JAndrassy/NetApiHelpers/blob/master/examples/ModernEthernetTest/ModernEthernetTest.ino

rpineau commented 5 months ago

Thanks for the link, It should help. I need to change quite a bit of code as now I have 2 interfaces and the WifiServer object need to bind to the right interface.

rpineau commented 5 months ago

Wiznet5500lwIPc Ethernet works fine for standard TCP connectivity, but UDP begin return 1

discoveryServer = new WiFiUDP();
nErr = discoveryServer->begin(m_UDPPort);

When using the standard Ethernet library with EternetUDP, the discovery works. When changing to WiFiUDP , it gets the broadcast packet and replies, but the discovery service doesn't recognise the response. tcpdump doesn't really show any difference in the payload so it's probably related to the failure on begin Looking at the code for begin in WiFiUdp.cpp it uses a IPAddress() call to get the ip to listen on, but there is no way to set this IP (or I haven't found it). The constructor for WiFiServer does take an IP and port as parameters, the constructor for WiFiUDP takes no parameters. I'm for now only testing with the Ethernet side of my project as I can't move to Wiznet5500lwIPc + WiFi if I'm not able to get parity with what I have working with the standard Ethernet library. May be the real problem I'm facing is how do I tie a server to an interface (on Linux or macOS I would bind to the respective interfaces IP to run services on different IP or 0.0.0.0 for all interfaces)

rpineau commented 5 months ago

So after a lot more time spend on this, turn out the code works, but the lwIP_w5500 library is more than 20 times slower than the standard Arduino Ethernet library with a W5500. The code implements a simple REST server and the exact same code returns a reponse in ~ 40ms with the standard Ethernet library versus slightly over a second with the lwIP_w5500 library. During the discovery after replying to the UDP broadcast, the service then query 3 of the API endpoint successively. As the lwIP_w5500 is slow to respond it fails the discovery. So the question is why is lwIP_w5500 so much slower ?