「ESP32 に有線LANをつなげる」
https://qiita.com/nanbuwks/items/6e54b193dce1853ad708
では、Ethernet の PHY を接続、サンプルプログラムを動かしてテストしていました。
今回は使い慣れた WiFi 用のプログラムを書き直して有線LAN対応にする方法について。
以下のようにすればできるようになります。
スイッチ
今回は、 ETHER または WIFI を define していずれかを選択するようにしました。
いずれかの排他使用です。
#define ETHER // WIFI or ETHER
プリプロセッサの処理
#include <WiFi.h>
#ifdef WIFI
#include <WiFiClient.h>
#endif
#ifdef ETHER
#include <ETH.h>
#endif
有線LANのスケッチは無線LANから派生したのかな? WiFi.h は有線LANでも必要です。
setup() の処理
#ifdef WIFI
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
#endif
#ifdef ETHER
WiFi.onEvent(WiFiEvent);
ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);
// ETH.config(IPAddress(192, 168, 42, 90),IPAddress(192, 168, 42, 1),IPAddress(255, 255, 255, 0),IPAddress(192, 168, 42, 1));
#endif
無線の場合は WiFI.begin, 有線の場合は ETH.begin でネットワークが開始されます。
IPアドレスの表示
#ifdef WIFI
Serial.println(WiFi.localIP());
#endif
#ifdef ETHER
Serial.println(ETH.localIP());
#endif
AdvancedWebServerの移植
サンプルプログラムの AdvancedWebServer を上記の方法を使って有線LANに移植してみました。
以下はフルコードです。
/*
Copyright (c) 2015, Majenko Technologies
All rights reserved.
Modified by nanbuwks for LAN8720 (2020.06.10)
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
* * Neither the name of Majenko Technologies nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define ETHER // WIFI or ETHER
#include <WiFi.h>
#ifdef WIFI
#include <WiFiClient.h>
#endif
#ifdef ETHER
#include <ETH.h>
#endif
#include <WebServer.h>
#include <ESPmDNS.h>
#ifdef WIFI
const char *ssid = "myESSID";
const char *password = "myPassphase";
#endif
#ifdef ETHER
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN // external clock from crystal oscillator
#define ETH_POWER_PIN 17 // Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
#define ETH_TYPE ETH_PHY_LAN8720 // LAN8720 or TLK110
#define ETH_ADDR PHY1 // I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)
#define ETH_MDC_PIN 23 // Pin# of the I²C clock signal for the Ethernet PHY
#define ETH_MDIO_PIN 18 // Pin# of the I²C IO signal for the Ethernet PHY
#endif
WebServer server(80);
const int led = 13;
void handleRoot() {
digitalWrite(led, 1);
char temp[400];
int sec = millis() / 1000;
int min = sec / 60;
int hr = min / 60;
snprintf(temp, 400,
"<html>\
<head>\
<meta http-equiv='refresh' content='5'/>\
<title>ESP32 Demo</title>\
<style>\
body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
</style>\
</head>\
<body>\
<h1>Hello from ESP32!</h1>\
<p>Uptime: %02d:%02d:%02d</p>\
<img src=\"/test.svg\" />\
</body>\
</html>",
hr, min % 60, sec % 60
);
server.send(200, "text/html", temp);
digitalWrite(led, 0);
}
void handleNotFound() {
digitalWrite(led, 1);
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
digitalWrite(led, 0);
}
#ifdef ETHER
static bool eth_connected = false;
void WiFiEvent(WiFiEvent_t event) {
switch (event) {
case SYSTEM_EVENT_ETH_START:
Serial.println("ETH Started");
//set eth hostname here
ETH.setHostname("esp32-ethernet");
break;
case SYSTEM_EVENT_ETH_CONNECTED:
Serial.println("ETH Connected");
break;
case SYSTEM_EVENT_ETH_GOT_IP:
Serial.print("ETH MAC: ");
Serial.print(ETH.macAddress());
Serial.print(", IPv4: ");
Serial.print(ETH.localIP());
if (ETH.fullDuplex()) {
Serial.print(", FULL_DUPLEX");
}
Serial.print(", ");
Serial.print(ETH.linkSpeed());
Serial.println("Mbps");
eth_connected = true;
break;
case SYSTEM_EVENT_ETH_DISCONNECTED:
Serial.println("ETH Disconnected");
eth_connected = false;
break;
case SYSTEM_EVENT_ETH_STOP:
Serial.println("ETH Stopped");
eth_connected = false;
break;
default:
break;
}
}
#endif
void setup(void) {
pinMode(led, OUTPUT);
digitalWrite(led, 0);
Serial.begin(115200);
#ifdef WIFI
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
#endif
#ifdef ETHER
WiFi.onEvent(WiFiEvent);
ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);
// ETH.config(IPAddress(192, 168, 42, 90),IPAddress(192, 168, 42, 1),IPAddress(255, 255, 255, 0),IPAddress(192, 168, 42, 1));
Serial.print("AP IP address: ");
Serial.println(ETH.localIP());
#endif
if (MDNS.begin("esp32")) {
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);
server.on("/test.svg", drawGraph);
server.on("/inline", []() {
server.send(200, "text/plain", "this works as well");
});
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
}
void loop(void) {
server.handleClient();
}
void drawGraph() {
String out = "";
char temp[100];
out += "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"400\" height=\"150\">\n";
out += "<rect width=\"400\" height=\"150\" fill=\"rgb(250, 230, 210)\" stroke-width=\"1\" stroke=\"rgb(0, 0, 0)\" />\n";
out += "<g stroke=\"black\">\n";
int y = rand() % 130;
for (int x = 10; x < 390; x += 10) {
int y2 = rand() % 130;
sprintf(temp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" stroke-width=\"1\" />\n", x, 140 - y, x + 10, 140 - y2);
out += temp;
y = y2;
}
out += "</g>\n</svg>\n";
server.send(200, "image/svg+xml", out);
}