1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

make WiFi/Ethernet interface compatible with Arduino Ethernet API (#8645)

* make WiFi/Ethernet interface compatible with Arduino Ethernet API
provide some minimaly adapted examples from legacy

* move ethernet compat globals to EthernetCompat.h

* LegacyEthernet: add UDP example

* adjust comments

Co-authored-by: Max Prokhorov <prokhorov.max@outlook.com>
This commit is contained in:
david gauchard 2022-07-28 00:00:56 +02:00 committed by GitHub
parent 646bdfc060
commit ee7ac2f79d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 590 additions and 2 deletions

View File

@ -41,7 +41,7 @@ public:
// ---- + --------- ------------- // ---- + --------- -------------
// local_ip | local_ip local_ip // local_ip | local_ip local_ip
// arg1 | gateway dns1 // arg1 | gateway dns1
// arg2 | netmask [Agateway // arg2 | netmask gateway
// arg3 | dns1 netmask // arg3 | dns1 netmask
// //
// result stored into gateway/netmask/dns1 // result stored into gateway/netmask/dns1

View File

@ -104,7 +104,6 @@ public:
} }
// ESP8266WiFi API compatibility // ESP8266WiFi API compatibility
wl_status_t status(); wl_status_t status();
protected: protected:

View File

@ -0,0 +1,126 @@
/*
Advanced Chat Server
A more advanced server that distributes any incoming messages
to all connected clients but the client the message comes from.
To use, telnet to your device's IP address and type.
You can see the client's input in the serial monitor as well.
Using an Arduino Wiznet Ethernet shield.
Circuit:
* Ethernet Wiznet5500/Wiznet5100/ENC28J60 on esp8266
created 18 Dec 2009
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
redesigned to make use of operator== 25 Nov 2013
by Norbert Truchsess
*/
// specific to esp8266 w/lwIP
#include <EthernetCompat.h>
ArduinoWiznet5500lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware
// ArduinoWiznet5100lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware
// ArduinoENC28J60lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network.
// gateway and subnet are optional:
byte notNeededButAllowed_mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
byte* mac = nullptr; // automatic mac
IPAddress ip(192, 168, 1, 177);
IPAddress myDns(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 0, 0);
// telnet defaults to port 23
EthernetServer server(23);
EthernetClient clients[8];
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
// // esp8266 w/lwIP: SS set in Ethernet constructor
// initialize the Ethernet device
Ethernet.begin(mac, ip, myDns, gateway, subnet);
// 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
}
// 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 listening for clients
server.begin();
Serial.print("Chat server address:");
Serial.println(Ethernet.localIP());
}
void loop() {
// check for any new client connecting, and say hello (before any incoming data)
EthernetClient newClient = server.accept();
if (newClient) {
for (byte i = 0; i < 8; i++) {
if (!clients[i]) {
Serial.print("We have a new client #");
Serial.println(i);
newClient.print("Hello, client number: ");
newClient.println(i);
// Once we "accept", the client is no longer tracked by EthernetServer
// so we must store it into our list of clients
clients[i] = newClient;
break;
}
}
}
// check for incoming data from all clients
for (byte i = 0; i < 8; i++) {
if (clients[i] && clients[i].available() > 0) {
// read bytes from a client
byte buffer[80];
int count = clients[i].read(buffer, 80);
// write the bytes to all other connected clients
for (byte j = 0; j < 8; j++) {
if (j != i && clients[j].connected()) {
clients[j].write(buffer, count);
}
}
}
}
// stop any clients which disconnect
for (byte i = 0; i < 8; i++) {
if (clients[i] && !clients[i].connected()) {
Serial.print("disconnect client #");
Serial.println(i);
clients[i].stop();
}
}
}

View File

@ -0,0 +1,105 @@
/*
Chat Server
A simple server that distributes any incoming messages to all
connected clients. To use, telnet to your device's IP address and type.
You can see the client's input in the serial monitor as well.
Using an Arduino Wiznet Ethernet shield.
Circuit:
* Ethernet Wiznet5500/Wiznet5100/ENC28J60 on esp8266
created 18 Dec 2009
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
*/
// specific to esp8266 w/lwIP
#include <EthernetCompat.h>
ArduinoWiznet5500lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware
// ArduinoWiznet5100lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware
// ArduinoENC28J60lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network.
// gateway and subnet are optional:
byte notNeededButAllowed_mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
byte* mac = nullptr; // automatic mac
IPAddress ip(192, 168, 1, 177);
IPAddress myDns(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 0, 0);
// telnet defaults to port 23
EthernetServer server(23);
bool alreadyConnected = false; // whether or not the client was connected previously
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
// // esp8266 w/lwIP: SS set in Ethernet constructor
// initialize the ethernet device
Ethernet.begin(mac, ip, myDns, gateway, subnet);
// 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
}
// 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 listening for clients
server.begin();
Serial.print("Chat server address:");
Serial.println(Ethernet.localIP());
}
void loop() {
// wait for a new client:
EthernetClient client = server.available();
// when the client sends the first byte, say hello:
if (client) {
if (!alreadyConnected) {
// clear out the input buffer:
client.flush();
Serial.println("We have a new client");
client.println("Hello, client!");
alreadyConnected = true;
}
if (client.available() > 0) {
// read the bytes incoming from the client:
char thisChar = client.read();
// echo the bytes back to the client:
server.write(thisChar);
// echo the bytes to the server as well:
Serial.write(thisChar);
}
}
}

View File

@ -0,0 +1,101 @@
/*
DHCP-based IP printer
This sketch uses the DHCP extensions to the Ethernet library
to get an IP address via DHCP and print the address obtained.
using an Arduino Wiznet Ethernet shield.
Circuit:
* Ethernet Wiznet5500/Wiznet5100/ENC28J60 on esp8266
created 12 April 2011
modified 9 Apr 2012
by Tom Igoe
modified 02 Sept 2015
by Arturo Guadalupi
*/
// specific to esp8266 w/lwIP
#include <EthernetCompat.h>
ArduinoWiznet5500lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware
// ArduinoWiznet5100lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware
// ArduinoENC28J60lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte notNeededButAllowed_mac[] = {
0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02
};
byte* mac = nullptr; // automatic mac
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
// // esp8266 w/lwIP: SS set in Ethernet constructor
// 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
}
// start the Ethernet connection:
Serial.println("Initialize Ethernet with DHCP:");
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
} else if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
// no point in carrying on, so do nothing forevermore:
while (true) {
delay(1);
}
}
// print your local IP address:
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());
}
void loop() {
switch (Ethernet.maintain()) {
case 1:
// renewed fail
Serial.println("Error: renewed fail");
break;
case 2:
// renewed success
Serial.println("Renewed success");
// print your local IP address:
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());
break;
case 3:
// rebind fail
Serial.println("Error: rebind fail");
break;
case 4:
// rebind success
Serial.println("Rebind success");
// print your local IP address:
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());
break;
default:
// nothing happened
break;
}
}

View File

@ -0,0 +1,156 @@
/*
UDPSendReceiveString:
This sketch receives UDP message strings, prints them to the serial port
and sends an "acknowledge" string back to the sender
A Processing sketch is included at the end of file that can be used to send
and received messages for testing with a computer.
Circuit:
* Ethernet Wiznet5500/Wiznet5100/ENC28J60 on esp8266
created 21 Aug 2010
by Michael Margolis
This code is in the public domain.
*/
// specific to esp8266 w/lwIP
#include <EthernetCompat.h>
ArduinoWiznet5500lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware
// ArduinoWiznet5100lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware
// ArduinoENC28J60lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte notNeededButAllowed_mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
byte* mac = nullptr; // automatic mac
IPAddress ip(192, 168, 1, 177);
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged"; // a string to send back
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
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
// // esp8266 w/lwIP: SS set in Ethernet constructor
// 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
}
// start the Ethernet
// Ethernet.begin(mac, ip);
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
while (true) {
delay(1000); // do nothing, no point running without Ethernet hardware
}
}
// 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(1000); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
Serial.println("Started and waiting");
Serial.print("IP Address: ");
Serial.println(Ethernet.localIP());
Serial.print("UDP port: ");
Serial.println(localPort);
// start UDP
Udp.begin(localPort);
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i = 0; i < 4; i++) {
Serial.print(remote[i], DEC);
if (i < 3) {
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
// read the packet into packetBufffer
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
Serial.println("Contents:");
Serial.println(packetBuffer);
// send a reply to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
}
delay(10);
}
/*
Processing sketch to run with this example
=====================================================
// Processing UDP example to send and receive string data from Arduino
// press any key to send the "Hello Arduino" message
import hypermedia.net.*;
UDP udp; // define the UDP object
void setup() {
udp = new UDP( this, 6000 ); // create a new datagram connection on port 6000
//udp.log( true ); // <-- printout the connection activity
udp.listen( true ); // and wait for incoming message
}
void draw()
{
}
void keyPressed() {
String ip = "192.168.1.177"; // the remote IP address
int port = 8888; // the destination port
udp.send("Hello World", ip, port ); // the message to send
}
void receive( byte[] data ) { // <-- default handler
//void receive( byte[] data, String ip, int port ) { // <-- extended handler
for(int i=0; i < data.length; i++)
print(char(data[i]));
println();
}
*/

View File

@ -0,0 +1,101 @@
#pragma once
#include <LwipEthernet.h>
#include <WiFiUdp.h>
#include <WiFiClient.h>
#include <ArduinoWiFiServer.h>
using EthernetUDP = WiFiUDP;
using EthernetClient = WiFiClient;
using EthernetServer = ArduinoWiFiServer;
enum EthernetLinkStatus
{
Unknown,
LinkON,
LinkOFF
};
enum
{
DHCP_CHECK_NONE = 0,
DHCP_CHECK_RENEW_FAIL = 1,
DHCP_CHECK_RENEW_OK = 2,
DHCP_CHECK_REBIND_FAIL = 3,
DHCP_CHECK_REBIND_OK = 4,
};
enum HardwareStatus
{
EthernetNoHardware,
EthernetHardwareFound,
};
template<class RawDev>
class ArduinoEthernet: public LwipIntfDev<RawDev>
{
public:
ArduinoEthernet(int8_t cs = SS, SPIClass& spi = SPI, int8_t intr = -1) :
LwipIntfDev<RawDev>(cs, spi, intr)
{
_hardwareStatus = EthernetNoHardware;
_linkStatus = Unknown;
}
// Arduino-Ethernet API compatibility, order can be either:
// mac, ip, gateway, netmask, dns (esp8266 or natural order)
// mac, ip, dns, gateway, netmask (Arduino legacy)
boolean begin(const uint8_t* macAddress, const IPAddress& local_ip = IPADDR_NONE,
const IPAddress& arg1 = IPADDR_NONE, const IPAddress& arg2 = IPADDR_NONE,
const IPAddress& arg3 = IPADDR_NONE)
{
SPI4EthInit(); // Arduino Ethernet self-initializes SPI
bool ret = true;
if (local_ip.isSet())
ret = LwipIntfDev<RawDev>::config(local_ip, arg1, arg2, arg3);
if (ret)
{
ret = LwipIntfDev<RawDev>::begin(macAddress);
if (!local_ip.isSet())
{
// Arduino API waits for DHCP answer
while (!LwipIntfDev<RawDev>::connected())
{
delay(100);
}
}
}
if (ret)
{
_hardwareStatus = EthernetHardwareFound;
_linkStatus = LinkON;
}
return ret;
}
HardwareStatus hardwareStatus() const
{
return _hardwareStatus;
}
EthernetLinkStatus linkStatus() const
{
return _linkStatus;
}
int maintain() const
{
return DHCP_CHECK_NONE;
}
protected:
HardwareStatus _hardwareStatus;
EthernetLinkStatus _linkStatus;
};
using ArduinoWiznet5500lwIP = ArduinoEthernet<Wiznet5500>;
using ArduinoWiznet5100lwIP = ArduinoEthernet<Wiznet5100>;
using ArduinoENC28J60lwIP = ArduinoEthernet<ENC28J60>;