276 lines
8.4 KiB
C++
276 lines
8.4 KiB
C++
/****************************************************************************************************************************
|
|
AdvancedWebServer.h
|
|
|
|
For Ethernet shields using ESP32_W5500 (ESP32 + W5500)
|
|
|
|
WebServer_ESP32_W5500 is a library for the ESP32 with Ethernet W5500 to run WebServer
|
|
|
|
Based on and modified from ESP32-IDF https://github.com/espressif/esp-idf
|
|
Built by Khoi Hoang https://github.com/khoih-prog/WebServer_ESP32_W5500
|
|
Licensed under GPLv3 license
|
|
|
|
Copyright (c) 2015, Majenko Technologies
|
|
All rights reserved.
|
|
|
|
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.
|
|
*****************************************************************************************************************************/
|
|
|
|
#if !( defined(ESP32) )
|
|
#error This code is designed for (ESP32 + W5500) to run on ESP32 platform! Please check your Tools->Board setting.
|
|
#endif
|
|
|
|
#define DEBUG_ETHERNET_WEBSERVER_PORT Serial
|
|
|
|
// Debug Level from 0 to 4
|
|
#define _ETHERNET_WEBSERVER_LOGLEVEL_ 3
|
|
|
|
//////////////////////////////////////////////////////////
|
|
|
|
// Optional values to override default settings
|
|
// Don't change unless you know what you're doing
|
|
//#define ETH_SPI_HOST SPI3_HOST
|
|
//#define SPI_CLOCK_MHZ 25
|
|
|
|
// Must connect INT to GPIOxx or not working
|
|
//#define INT_GPIO 4
|
|
|
|
//#define MISO_GPIO 19
|
|
//#define MOSI_GPIO 23
|
|
//#define SCK_GPIO 18
|
|
//#define CS_GPIO 5
|
|
|
|
//////////////////////////////////////////////////////////
|
|
|
|
#include <WebServer_ESP32_W5500.h>
|
|
|
|
WebServer server(80);
|
|
|
|
// Enter a MAC address and IP address for your controller below.
|
|
#define NUMBER_OF_MAC 20
|
|
|
|
byte mac[][NUMBER_OF_MAC] =
|
|
{
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01 },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x02 },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x03 },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x04 },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x05 },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x06 },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x07 },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x08 },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x09 },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0A },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0B },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0C },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0D },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0E },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0F },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x10 },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x11 },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x12 },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x13 },
|
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x14 },
|
|
};
|
|
|
|
// Select the IP address according to your local network
|
|
IPAddress myIP(192, 168, 2, 232);
|
|
IPAddress myGW(192, 168, 2, 1);
|
|
IPAddress mySN(255, 255, 255, 0);
|
|
|
|
// Google DNS Server IP
|
|
IPAddress myDNS(8, 8, 8, 8);
|
|
|
|
int reqCount = 0; // number of requests received
|
|
|
|
void handleRoot()
|
|
{
|
|
#define BUFFER_SIZE 400
|
|
|
|
char temp[BUFFER_SIZE];
|
|
int sec = millis() / 1000;
|
|
int min = sec / 60;
|
|
int hr = min / 60;
|
|
int day = hr / 24;
|
|
|
|
hr = hr % 24;
|
|
|
|
snprintf(temp, BUFFER_SIZE - 1,
|
|
"<html>\
|
|
<head>\
|
|
<meta http-equiv='refresh' content='5'/>\
|
|
<title>AdvancedWebServer %s</title>\
|
|
<style>\
|
|
body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
|
|
</style>\
|
|
</head>\
|
|
<body>\
|
|
<h2>Hi from WebServer_ESP32_W5500!</h2>\
|
|
<h3>on %s</h3>\
|
|
<p>Uptime: %d d %02d:%02d:%02d</p>\
|
|
<img src=\"/test.svg\" />\
|
|
</body>\
|
|
</html>", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60);
|
|
|
|
server.send(200, F("text/html"), temp);
|
|
}
|
|
|
|
void handleNotFound()
|
|
{
|
|
String message = F("File Not Found\n\n");
|
|
|
|
message += F("URI: ");
|
|
message += server.uri();
|
|
message += F("\nMethod: ");
|
|
message += (server.method() == HTTP_GET) ? F("GET") : F("POST");
|
|
message += F("\nArguments: ");
|
|
message += server.args();
|
|
message += F("\n");
|
|
|
|
for (uint8_t i = 0; i < server.args(); i++)
|
|
{
|
|
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
|
|
}
|
|
|
|
server.send(404, F("text/plain"), message);
|
|
}
|
|
|
|
void drawGraph()
|
|
{
|
|
String out;
|
|
out.reserve(3000);
|
|
char temp[70];
|
|
|
|
out += F("<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"310\" height=\"150\">\n");
|
|
out += F("<rect width=\"310\" height=\"150\" fill=\"rgb(250, 230, 210)\" stroke-width=\"2\" stroke=\"rgb(0, 0, 0)\" />\n");
|
|
out += F("<g stroke=\"blue\">\n");
|
|
int y = rand() % 130;
|
|
|
|
for (int x = 10; x < 300; x += 10)
|
|
{
|
|
int y2 = rand() % 130;
|
|
sprintf(temp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" stroke-width=\"2\" />\n", x, 140 - y, x + 10, 140 - y2);
|
|
out += temp;
|
|
y = y2;
|
|
}
|
|
|
|
out += F("</g>\n</svg>\n");
|
|
|
|
server.send(200, F("image/svg+xml"), out);
|
|
}
|
|
|
|
void setup()
|
|
{
|
|
Serial.begin(115200);
|
|
|
|
while (!Serial && (millis() < 5000));
|
|
|
|
Serial.print(F("\nStart AdvancedWebServer on "));
|
|
Serial.print(ARDUINO_BOARD);
|
|
Serial.print(F(" with "));
|
|
Serial.println(SHIELD_TYPE);
|
|
Serial.println(WEBSERVER_ESP32_W5500_VERSION);
|
|
|
|
ET_LOGWARN(F("Default SPI pinout:"));
|
|
ET_LOGWARN1(F("SPI_HOST:"), ETH_SPI_HOST);
|
|
ET_LOGWARN1(F("MOSI:"), MOSI_GPIO);
|
|
ET_LOGWARN1(F("MISO:"), MISO_GPIO);
|
|
ET_LOGWARN1(F("SCK:"), SCK_GPIO);
|
|
ET_LOGWARN1(F("CS:"), CS_GPIO);
|
|
ET_LOGWARN1(F("INT:"), INT_GPIO);
|
|
ET_LOGWARN1(F("SPI Clock (MHz):"), SPI_CLOCK_MHZ);
|
|
ET_LOGWARN(F("========================="));
|
|
|
|
///////////////////////////////////
|
|
|
|
// To be called before ETH.begin()
|
|
ESP32_W5500_onEvent();
|
|
|
|
// start the ethernet connection and the server:
|
|
// Use DHCP dynamic IP and random mac
|
|
//bool begin(int MISO_GPIO, int MOSI_GPIO, int SCLK_GPIO, int CS_GPIO, int INT_GPIO, int SPI_CLOCK_MHZ,
|
|
// int SPI_HOST, uint8_t *W6100_Mac = W6100_Default_Mac);
|
|
ETH.begin( MISO_GPIO, MOSI_GPIO, SCK_GPIO, CS_GPIO, INT_GPIO, SPI_CLOCK_MHZ, ETH_SPI_HOST );
|
|
//ETH.begin( MISO_GPIO, MOSI_GPIO, SCK_GPIO, CS_GPIO, INT_GPIO, SPI_CLOCK_MHZ, ETH_SPI_HOST, mac[millis() % NUMBER_OF_MAC] );
|
|
|
|
// Static IP, leave without this line to get IP via DHCP
|
|
//bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = 0, IPAddress dns2 = 0);
|
|
//ETH.config(myIP, myGW, mySN, myDNS);
|
|
|
|
ESP32_W5500_waitForConnect();
|
|
|
|
///////////////////////////////////
|
|
|
|
server.on(F("/"), handleRoot);
|
|
server.on(F("/test.svg"), drawGraph);
|
|
server.on(F("/inline"), []()
|
|
{
|
|
server.send(200, F("text/plain"), F("This works as well"));
|
|
});
|
|
|
|
server.onNotFound(handleNotFound);
|
|
server.begin();
|
|
|
|
Serial.print(F("HTTP EthernetWebServer is @ IP : "));
|
|
Serial.println(ETH.localIP());
|
|
}
|
|
|
|
void heartBeatPrint()
|
|
{
|
|
static int num = 1;
|
|
|
|
Serial.print(F("."));
|
|
|
|
if (num == 80)
|
|
{
|
|
Serial.println();
|
|
num = 1;
|
|
}
|
|
else if (num++ % 10 == 0)
|
|
{
|
|
Serial.print(F(" "));
|
|
}
|
|
}
|
|
|
|
void check_status()
|
|
{
|
|
static unsigned long checkstatus_timeout = 0;
|
|
|
|
#define STATUS_CHECK_INTERVAL 10000L
|
|
|
|
// Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change.
|
|
if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0))
|
|
{
|
|
heartBeatPrint();
|
|
checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL;
|
|
}
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
server.handleClient();
|
|
check_status();
|
|
}
|