#include <EthernetESP32.h>
#include <WiFi.h>
#include <ESPmDNS.h>
#include <MacAddress.h>
#include "esp_mac.h"
#define ETH_RST_PIN -1 // gpio pin number for ETH_RST on ESP32 (-1 si pas cablé)
#define ETH_INT_PIN -1 // gpio pin number for ETH_INT on ESP32 (-1 si pas cablé)
// pour les 4 pins qui suivent, on peux assigner les gpio par defaut
// sur ESP32 (VSPI): 18 SPI_CLK, 23 SPI_MOSI, 19 SPI_MISO, 5 SPI_CS,
#define ETH_CS_PIN 21 // SPI gpio pin number or (Default is SS 5 for ESP32 => #define ETH_CS_PIN SS)
#define ETH_SCLK_PIN 15 // SPI gpio pin number or (Default is SCK 18 for ESP32 => #define ETH_SCLK_PIN SCK)
#define ETH_MOSI_PIN 12 // SPI gpio pin number or (Default is MOSI 23 for ESP32 => #define ETH_MOSI_PIN MOSI)
#define ETH_MISO_PIN 39 // SPI gpio pin number or (Default is MISO 19 for ESP32 => #define ETH_MISO_PIN MISO)
#ifdef CONFIG_ETH_USE_ESP32_EMAC // EMAC & interface RMII PHY not supported in new ESP ...
// ESP32-ETH01 utilise ces gpio (Interface RMII) : 13,16,17,18,19,21,22,23,25,26,27
EMACDriver driverL(ETH_PHY_LAN8720, 23, 18, 16); // Model, mdc pin, mdio pin, power pin
EMACDriver driverR(ETH_PHY_RTL8201, 23, 18, 16); // Model, mdc pin, mdio pin, power pin
// Potential interface can be : ETH_PHY_LAN8720, ETH_PHY_TLK110, ETH_PHY_RTL8201, ETH_PHY_DP83848, and ETH_PHY_KSZ80XX
#endif
W5500Driver driverW(ETH_CS_PIN, ETH_INT_PIN, ETH_RST_PIN); // SS pin, INT pin, RST pin
ENC28J60Driver driverE(ETH_CS_PIN, ETH_INT_PIN, ETH_RST_PIN); // SS pin, INT pin, RST pin
char hostname[26] = {0};
bool imposeMAC = false; // if we want place our mac identifiant
uint8_t macWifi[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEC}; // if mac not imposed, it is the defaut Id for ESP card
uint8_t macEth[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; // if mac not imposed, it is the default Id provide or macWifi +1 on right value of 6 bytes
bool eth_connected = false;
bool useDHCP = true; // IP choice by router else (if set to false, impose IP define hereafter)
IPAddress local_IP(192, 168, 1, 99);
IPAddress primaryDNS(192, 168, 1, 1);
IPAddress secondaryDNS(8, 8, 8, 8);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
byte connectEthernet = 0;
const char* ssid = "XWokwi-GUEST";
const char* password = "";
bool printEthernetStatus() {
byte mac[6] = {0,0,0,0,0,0};
Ethernet.MACAddress(mac);
Serial.println(MacAddress(mac));
if (mac[0] & 1) { // unicast bit is set
Serial.println("\t is the ordering of the MAC address bytes reversed?");
}
Serial.print("IP Address: ");Serial.println(Ethernet.localIP());
Serial.print("gateway IP Address: ");Serial.println(Ethernet.gatewayIP());
Serial.print("subnet IP mask: ");Serial.println(Ethernet.subnetMask());
Serial.print("DNS server: ");
IPAddress dns = Ethernet.dnsServerIP();
if (dns == INADDR_NONE) {
Serial.println("not set");
} else {
Serial.println(dns);
}
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found :");
//return false;
}
Serial.print("Checking link ...");
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("\tretry...");
delay(500);
}
switch (Ethernet.linkStatus()) {
case LinkOFF:
Serial.println("\tEthernet cable is not connected.");
return false;
break;
case LinkON:
Serial.println("\tEthernet cable is connected.");
break;
default:
Serial.printf("\tLink state %d unknown.\n",Ethernet.linkStatus());
break;
}
return true;
}
bool setup_Network() {
bool beginFail = false;
char interface[20] = {0};
IPAddress ip;
if (!imposeMAC) { // obtient l'adresse mac de la puce
esp_read_mac(macWifi, ESP_MAC_WIFI_STA);
esp_read_mac(macEth, ESP_MAC_ETH);
}
sprintf(hostname,"ESP32-%02X%02X%02X",macEth[3],macEth[4],macEth[5]);
Serial.printf("\nhostname pour Ethernet : %s\n",hostname);
// start by trying usage of module EMAC PHY
#ifdef CONFIG_ETH_USE_ESP32_EMAC // EMAC & interface RMII PHY not supported in new ESP ...
sprintf(interface,"LAN8720");
Serial.printf("\n------\nTry to start network with interface %s\n",interface);
Ethernet.init(driverL); // init interface LAN8720
beginFail = false;
if (useDHCP) {
if (!Ethernet.begin(macEth)) beginFail = true;
} else {
Ethernet.begin(macEth, local_IP, primaryDNS, gateway, subnet);
}
if (Ethernet.hardwareStatus() == EthernetNoHardware) beginFail = true;
ip = Ethernet.localIP();
if (ip[0] == 0) beginFail = true;
printEthernetStatus();
if (!beginFail) {
Serial.printf("begin %s success\n",interface);
return true;
}
Ethernet.end();
sprintf(interface,"RTL8201");
Serial.printf("\n------\nTry to start network with interface %s\n",interface);
Ethernet.init(driverR); // init interface RTL8201
beginFail = false;
if (useDHCP) {
if (!Ethernet.begin(macEth)) beginFail = true;
} else {
Ethernet.begin(macEth, local_IP, primaryDNS, gateway, subnet);
}
if (Ethernet.hardwareStatus() == EthernetNoHardware) beginFail = true;
ip = Ethernet.localIP();
if (ip[0] == 0) beginFail = true;
printEthernetStatus();
if (!beginFail) {
Serial.printf("begin %s success\n",interface);
return true;
}
Ethernet.end();
#endif
// start test with SPI interface
SPI.begin(ETH_SCLK_PIN, ETH_MISO_PIN, ETH_MOSI_PIN, ETH_CS_PIN);
sprintf(interface,"W5500");
Serial.printf("\n------\nTry to start network with interface %s\n",interface);
Ethernet.init(driverW); // init interface W5500
beginFail = false;
if (useDHCP) {
if (!Ethernet.begin(macEth)) beginFail = true;
} else {
Ethernet.begin(macEth, local_IP, primaryDNS, gateway, subnet);
}
if (Ethernet.hardwareStatus() == EthernetNoHardware) beginFail = true;
ip = Ethernet.localIP();
if (ip[0] == 0) beginFail = true;
printEthernetStatus();
if (!beginFail) {
Serial.printf("begin %s success\n",interface);
return true;
}
Ethernet.end();
sprintf(interface,"ENC28J60");
Serial.printf("\n------\nTry to start network with interface %s\n",interface);
Ethernet.init(driverE); // init interface ENC28J60
beginFail = false;
if (useDHCP) {
if (!Ethernet.begin(macEth)) beginFail = true;
} else {
Ethernet.begin(macEth, local_IP, primaryDNS, gateway, subnet);
}
if (Ethernet.hardwareStatus() == EthernetNoHardware) beginFail = true;
ip = Ethernet.localIP();
if (ip[0] == 0) beginFail = true;
printEthernetStatus();
if (!beginFail) {
Serial.printf("begin %s success\n",interface);
return true;
}
Ethernet.end();
// on passe sur tentative en Wifi STA
sprintf(hostname,"ESP32-%02X%02X%02X",macWifi[3],macWifi[4],macWifi[5]);
Serial.printf("\nhostname pour Wifi : %s\n",hostname);
sprintf(interface,"WiFi STA");
Serial.printf("\n------\nTry to start network with interface %s\n",interface);
WiFi.hostname(hostname);
WiFi.disconnect(true);
WiFi.mode(WIFI_STA);
beginFail = false;
if (!useDHCP) {
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) beginFail = true;
}
WiFi.begin(ssid, password, 6);
// timeout
uint32_t startmillis = millis();
while (WiFi.status() != WL_CONNECTED && (millis() - startmillis < 20000)) { // Attente connexion au Wifi
delay(250);
Serial.print(".");
}
Serial.println();
if ((WiFi.status() != WL_CONNECTED)) beginFail = true;
byte mac[6] = {0,0,0,0,0,0};
WiFi.macAddress(mac);
Serial.println(MacAddress(mac));
Serial.print("IP Address: ");Serial.println(WiFi.localIP());
Serial.print("gateway IP Address: ");Serial.println(WiFi.gatewayIP());
Serial.print("subnet IP mask: ");Serial.println(WiFi.subnetMask());
if (!beginFail) {
Serial.printf("begin %s success\n",interface);
return true;
}
WiFi.disconnect();
// en dernier recours, on se place en Wifi AP
sprintf(interface,"WiFi AP");
Serial.printf("\n------\nTry to start network with interface %s\n",interface);
WiFi.mode(WIFI_AP);
if (!WiFi.softAP(hostname, NULL)) {
beginFail = true;
} else {
IPAddress myIP = WiFi.softAPIP();
Serial.printf("start %s mode with IP address: ", interface);
Serial.println(myIP);
return true;
}
return false;
}
void onEvent(arduino_event_id_t event) {
switch (event) {
case ARDUINO_EVENT_ETH_START: //20
Serial.println("ETH Started");
// The hostname must be set after the interface is started, but needs
// to be set before DHCP, so set it from the event handler thread.
Ethernet.setHostname(hostname);
break;
case ARDUINO_EVENT_ETH_CONNECTED: //22
Serial.println("ETH Connected");
break;
case ARDUINO_EVENT_ETH_GOT_IP: //24
Serial.println("ETH Got IP");
Serial.println(Ethernet);
eth_connected = true;
break;
case ARDUINO_EVENT_ETH_GOT_IP6: //19
Serial.println("ETH Got IP V6");
Serial.println(Ethernet);
eth_connected = true;
break;
case ARDUINO_EVENT_ETH_LOST_IP: // 6 ??? ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE
Serial.println("ETH Lost IP");
eth_connected = false;
break;
case ARDUINO_EVENT_ETH_DISCONNECTED: //23
Serial.println("ETH Disconnected");
eth_connected = false;
break;
case ARDUINO_EVENT_ETH_STOP: //21
Serial.println("ETH Stopped");
eth_connected = false;
break;
default: break;
}
}
void setup() {
char macWifi[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEC}; // if mac not imposed, it is the defaut Id for ESP card
char macEth[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF}; // if mac not imposed, it is the default Id provide or macWifi +3 on right value of 6 bytes
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println();
Network.onEvent(onEvent);
WiFi.onEvent(onEvent);
setup_Network();
Serial.println("\nFini !!");
}
void loop() {
// put your main code here, to run repeatedly:
delay(10); // this speeds up the simulation
}