Skip to content

Commit c365fd9

Browse files
authored
Ethernet Support (wled#1316)
Ethernet Support
1 parent 560f72a commit c365fd9

File tree

9 files changed

+191
-41
lines changed

9 files changed

+191
-41
lines changed

platformio.ini

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ default_envs = travis_esp8266, travis_esp32
3939
; default_envs = d1_mini_5CH_Shojo_PCB
4040
; default_envs = wemos_shield_esp32
4141
; default_envs = m5atom
42+
; default_envs = esp32_poe
4243

4344
[common]
4445
# ------------------------------------------------------------------------------
@@ -248,6 +249,15 @@ lib_ignore =
248249
ESPAsyncTCP
249250
ESPAsyncUDP
250251

252+
[env:esp32_poe]
253+
board = esp32-poe
254+
255+
upload_speed = 921600
256+
build_flags = ${common.build_flags_esp32} ${common.debug_flags} -D RLYPIN=-1 -D WLED_USE_ETHERNET
257+
lib_ignore =
258+
ESPAsyncTCP
259+
ESPAsyncUDP
260+
251261
[env:esp8285_4CH_MagicHome]
252262
board = esp8285
253263
platform = ${common.platform_latest}

wled00/Network.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include "Network.h"
2+
3+
IPAddress NetworkClass::localIP()
4+
{
5+
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
6+
if (ETH.localIP()[0] != 0) {
7+
return ETH.localIP();
8+
}
9+
#endif
10+
if (WiFi.localIP()[0] != 0) {
11+
return WiFi.localIP();
12+
}
13+
return INADDR_NONE;
14+
}
15+
16+
IPAddress NetworkClass::subnetMask()
17+
{
18+
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
19+
if (ETH.localIP()[0] != 0) {
20+
return ETH.subnetMask();
21+
}
22+
#endif
23+
if (WiFi.localIP()[0] != 0) {
24+
return WiFi.subnetMask();
25+
}
26+
return IPAddress(255, 255, 255, 0);
27+
}
28+
29+
IPAddress NetworkClass::gatewayIP()
30+
{
31+
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
32+
if (ETH.localIP()[0] != 0) {
33+
return ETH.gatewayIP();
34+
}
35+
#endif
36+
if (WiFi.localIP()[0] != 0) {
37+
return WiFi.gatewayIP();
38+
}
39+
return INADDR_NONE;
40+
}
41+
42+
bool NetworkClass::isConnected()
43+
{
44+
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
45+
return (WiFi.localIP()[0] != 0 && WiFi.status() == WL_CONNECTED) || ETH.localIP()[0] != 0;
46+
#else
47+
return (WiFi.localIP()[0] != 0 && WiFi.status() == WL_CONNECTED);
48+
#endif
49+
}
50+
51+
bool NetworkClass::isEthernet()
52+
{
53+
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
54+
return (ETH.localIP()[0] != 0);
55+
#endif
56+
return false;
57+
}
58+
59+
NetworkClass Network;

wled00/Network.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifdef ESP8266
2+
#include <ESP8266WiFi.h>
3+
#else // ESP32
4+
#include <WiFi.h>
5+
#include <ETH.h>
6+
#endif
7+
8+
#ifndef Network_h
9+
#define Network_h
10+
11+
class NetworkClass
12+
{
13+
public:
14+
IPAddress localIP();
15+
IPAddress subnetMask();
16+
IPAddress gatewayIP();
17+
bool isConnected();
18+
bool isEthernet();
19+
};
20+
21+
extern NetworkClass Network;
22+
23+
#endif

wled00/src/dependencies/e131/ESPAsyncE131.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919

2020
#include "ESPAsyncE131.h"
21+
#include "Network.h"
2122
#include <string.h>
2223

2324
// E1.17 ACN Packet Identifier
@@ -75,7 +76,7 @@ bool ESPAsyncE131::initMulticast(uint16_t port, uint16_t universe, uint8_t n) {
7576
ip4_addr_t ifaddr;
7677
ip4_addr_t multicast_addr;
7778

78-
ifaddr.addr = static_cast<uint32_t>(WiFi.localIP());
79+
ifaddr.addr = static_cast<uint32_t>(Network.localIP());
7980
for (uint8_t i = 1; i < n; i++) {
8081
multicast_addr.addr = static_cast<uint32_t>(IPAddress(239, 255,
8182
(((universe + i) >> 8) & 0xff), (((universe + i) >> 0)

wled00/src/dependencies/espalexa/Espalexa.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#endif
4848
#endif
4949
#include <WiFiUdp.h>
50+
#include "Network.h"
5051

5152
#ifdef ESPALEXA_DEBUG
5253
#pragma message "Espalexa 2.4.6 debug mode"
@@ -207,7 +208,7 @@ class Espalexa {
207208
void serveDescription()
208209
{
209210
EA_DEBUGLN("# Responding to description.xml ... #\n");
210-
IPAddress localIP = WiFi.localIP();
211+
IPAddress localIP = Network.localIP();
211212
char s[16];
212213
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
213214
char buf[1024];
@@ -281,7 +282,7 @@ class Espalexa {
281282
//respond to UDP SSDP M-SEARCH
282283
void respondToSearch()
283284
{
284-
IPAddress localIP = WiFi.localIP();
285+
IPAddress localIP = Network.localIP();
285286
char s[16];
286287
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
287288

@@ -333,7 +334,7 @@ class Espalexa {
333334
#ifdef ARDUINO_ARCH_ESP32
334335
udpConnected = espalexaUdp.beginMulticast(IPAddress(239, 255, 255, 250), 1900);
335336
#else
336-
udpConnected = espalexaUdp.beginMulticast(WiFi.localIP(), IPAddress(239, 255, 255, 250), 1900);
337+
udpConnected = espalexaUdp.beginMulticast(Network.localIP(), IPAddress(239, 255, 255, 250), 1900);
337338
#endif
338339

339340
if (udpConnected){

wled00/udp.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void notify(byte callMode, bool followUp)
6161
udpOut[28] = (t >> 0) & 0xFF;
6262

6363
IPAddress broadcastIp;
64-
broadcastIp = ~uint32_t(WiFi.subnetMask()) | uint32_t(WiFi.gatewayIP());
64+
broadcastIp = ~uint32_t(Network.subnetMask()) | uint32_t(Network.gatewayIP());
6565

6666
notifierUdp.beginPacket(broadcastIp, udpPort);
6767
notifierUdp.write(udpOut, WLEDPACKETSIZE);
@@ -157,7 +157,7 @@ void handleNotifications()
157157

158158
//notifier and UDP realtime
159159
if (!packetSize || packetSize > UDP_IN_MAXSIZE) return;
160-
if (!isSupp && notifierUdp.remoteIP() == WiFi.localIP()) return; //don't process broadcasts we send ourselves
160+
if (!isSupp && notifierUdp.remoteIP() == Network.localIP()) return; //don't process broadcasts we send ourselves
161161

162162
uint8_t udpIn[packetSize +1];
163163
if (isSupp) notifier2Udp.read(udpIn, packetSize);

wled00/wled.cpp

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,68 @@ bool oappend(const char* txt)
4343
return true;
4444
}
4545

46+
void prepareHostname(char* hostname)
47+
{
48+
const char *pC = serverDescription;
49+
uint8_t pos = 5;
50+
51+
while (*pC && pos < 24) { // while !null and not over length
52+
if (isalnum(*pC)) { // if the current char is alpha-numeric append it to the hostname
53+
hostname[pos] = *pC;
54+
pos++;
55+
} else if (*pC == ' ' || *pC == '_' || *pC == '-' || *pC == '+' || *pC == '!' || *pC == '?' || *pC == '*') {
56+
hostname[pos] = '-';
57+
pos++;
58+
}
59+
// else do nothing - no leading hyphens and do not include hyphens for all other characters.
60+
pC++;
61+
}
62+
// if the hostname is left blank, use the mac address/default mdns name
63+
if (pos < 6) {
64+
sprintf(hostname + 5, "%*s", 6, escapedMac.c_str() + 6);
65+
} else { //last character must not be hyphen
66+
while (pos > 0 && hostname[pos -1] == '-') {
67+
hostname[pos -1] = 0;
68+
pos--;
69+
}
70+
}
71+
}
72+
73+
//handle Ethernet connection event
74+
void WiFiEvent(WiFiEvent_t event)
75+
{
76+
char hostname[25] = "wled-";
77+
78+
switch (event) {
79+
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
80+
case SYSTEM_EVENT_ETH_START:
81+
DEBUG_PRINT("ETH Started");
82+
break;
83+
case SYSTEM_EVENT_ETH_CONNECTED:
84+
DEBUG_PRINT("ETH Connected");
85+
if (!apActive) {
86+
WiFi.disconnect(true);
87+
}
88+
if (staticIP != (uint32_t)0x00000000 && staticGateway != (uint32_t)0x00000000) {
89+
ETH.config(staticIP, staticGateway, staticSubnet, IPAddress(8, 8, 8, 8));
90+
} else {
91+
ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
92+
}
93+
// convert the "serverDescription" into a valid DNS hostname (alphanumeric)
94+
prepareHostname(hostname);
95+
ETH.setHostname(hostname);
96+
showWelcomePage = false;
97+
break;
98+
case SYSTEM_EVENT_ETH_DISCONNECTED:
99+
DEBUG_PRINT("ETH Disconnected");
100+
forceReconnect = true;
101+
break;
102+
#endif
103+
default:
104+
break;
105+
}
106+
}
107+
46108
void WLED::loop()
47109
{
48110
handleIR(); // 2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too
@@ -120,7 +182,7 @@ void WLED::loop()
120182
lastWifiState = WiFi.status();
121183
DEBUG_PRINT("State time: "); DEBUG_PRINTLN(wifiStateChangedTime);
122184
DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime);
123-
DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP());
185+
DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(Network.localIP());
124186
DEBUG_PRINT("Loops/sec: "); DEBUG_PRINTLN(loops / 10);
125187
loops = 0;
126188
debugTime = millis();
@@ -187,6 +249,7 @@ void WLED::setup()
187249
if (strcmp(clientSSID, DEFAULT_CLIENT_SSID) == 0)
188250
showWelcomePage = true;
189251
WiFi.persistent(false);
252+
WiFi.onEvent(WiFiEvent);
190253

191254
if (macroBoot > 0)
192255
applyMacro(macroBoot);
@@ -303,6 +366,10 @@ void WLED::initConnection()
303366
ws.onEvent(wsEvent);
304367
#endif
305368

369+
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
370+
ETH.begin();
371+
#endif
372+
306373
WiFi.disconnect(true); // close old connections
307374
#ifdef ESP8266
308375
WiFi.setPhyMode(WIFI_PHY_MODE_11N);
@@ -338,29 +405,7 @@ void WLED::initConnection()
338405

339406
// convert the "serverDescription" into a valid DNS hostname (alphanumeric)
340407
char hostname[25] = "wled-";
341-
const char *pC = serverDescription;
342-
uint8_t pos = 5;
343-
344-
while (*pC && pos < 24) { // while !null and not over length
345-
if (isalnum(*pC)) { // if the current char is alpha-numeric append it to the hostname
346-
hostname[pos] = *pC;
347-
pos++;
348-
} else if (*pC == ' ' || *pC == '_' || *pC == '-' || *pC == '+' || *pC == '!' || *pC == '?' || *pC == '*') {
349-
hostname[pos] = '-';
350-
pos++;
351-
}
352-
// else do nothing - no leading hyphens and do not include hyphens for all other characters.
353-
pC++;
354-
}
355-
// if the hostname is left blank, use the mac address/default mdns name
356-
if (pos < 6) {
357-
sprintf(hostname + 5, "%*s", 6, escapedMac.c_str() + 6);
358-
} else { //last character must not be hyphen
359-
while (pos > 0 && hostname[pos -1] == '-') {
360-
hostname[pos -1] = 0;
361-
pos--;
362-
}
363-
}
408+
prepareHostname(hostname);
364409

365410
#ifdef ESP8266
366411
WiFi.hostname(hostname);
@@ -381,9 +426,9 @@ void WLED::initInterfaces()
381426
DEBUG_PRINTLN(F("Init STA interfaces"));
382427

383428
if (hueIP[0] == 0) {
384-
hueIP[0] = WiFi.localIP()[0];
385-
hueIP[1] = WiFi.localIP()[1];
386-
hueIP[2] = WiFi.localIP()[2];
429+
hueIP[0] = Network.localIP()[0];
430+
hueIP[1] = Network.localIP()[1];
431+
hueIP[2] = Network.localIP()[2];
387432
}
388433

389434
// init Alexa hue emulation
@@ -482,7 +527,7 @@ void WLED::handleConnection()
482527
wasConnected = false;
483528
return;
484529
}
485-
if (!WLED_CONNECTED) {
530+
if (!Network.isConnected()) {
486531
if (interfacesInited) {
487532
DEBUG_PRINTLN(F("Disconnected!"));
488533
interfacesInited = false;
@@ -495,7 +540,7 @@ void WLED::handleConnection()
495540
} else if (!interfacesInited) { // newly connected
496541
DEBUG_PRINTLN("");
497542
DEBUG_PRINT(F("Connected! IP address: "));
498-
DEBUG_PRINTLN(WiFi.localIP());
543+
DEBUG_PRINTLN(Network.localIP());
499544
initInterfaces();
500545
userConnected();
501546
usermods.connected();

wled00/wled.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,15 @@
5454
}
5555
#else // ESP32
5656
#include <WiFi.h>
57+
#include <ETH.h>
5758
#include "esp_wifi.h"
5859
#include <ESPmDNS.h>
5960
#include <AsyncTCP.h>
6061
#include "SPIFFS.h"
6162
#endif
6263

64+
#include "Network.h"
65+
6366
#include <ESPAsyncWebServer.h>
6467
#include <EEPROM.h>
6568
#include <WiFiUdp.h>
@@ -521,8 +524,11 @@ WLED_GLOBAL UsermodManager usermods _INIT(UsermodManager());
521524
WLED_GLOBAL int loops _INIT(0);
522525
#endif
523526

524-
525-
#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED)
527+
#ifdef ARDUINO_ARCH_ESP32
528+
#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED || ETH.localIP()[0] != 0)
529+
#else
530+
#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED)
531+
#endif
526532
#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0)
527533
#define WLED_MQTT_CONNECTED (mqtt != nullptr && mqtt->connected())
528534

wled00/xml.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,10 @@ void URL_response(AsyncWebServerRequest *request)
8383

8484
char s[16];
8585
oappend(SET_F("http://"));
86-
IPAddress localIP = WiFi.localIP();
86+
IPAddress localIP = Network.localIP();
8787
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
8888
oappend(s);
89+
8990
oappend(SET_F("/win&A="));
9091
oappendi(bri);
9192
oappend(SET_F("&CL=h"));
@@ -219,11 +220,15 @@ void getSettingsJS(byte subPage, char* dest)
219220
sappend('c',SET_F("WS"),noWifiSleep);
220221

221222

222-
if (WiFi.localIP()[0] != 0) //is connected
223+
if (Network.isConnected()) //is connected
223224
{
224-
char s[16];
225-
IPAddress localIP = WiFi.localIP();
225+
char s[32];
226+
IPAddress localIP = Network.localIP();
226227
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
228+
229+
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
230+
if (Network.isEthernet()) strcat_P(s ,SET_F(" (Ethernet)"));
231+
#endif
227232
sappends('m',SET_F("(\"sip\")[0]"),s);
228233
} else
229234
{

0 commit comments

Comments
 (0)