/**************************************************************************************************************************** UDPSendReceive.ino - Simple Arduino web server sample for ESP8266/ESP32 AT-command shield 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 *****************************************************************************************************************************/ #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 // 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); char timeServer[] = "time.nist.gov"; // NTP server unsigned int localPort = 2390; // local port to listen for UDP packets const int NTP_PACKET_SIZE = 48; // NTP timestamp is in the first 48 bytes of the message const int UDP_TIMEOUT = 2000; // timeout in milliseconds to wait for an UDP packet to arrive byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming packet byte ReplyBuffer[] = "ACK"; // a string to send back // A UDP instance to let us send and receive packets over UDP WiFiUDP Udp; // send an NTP request to the time server at the given address void sendNTPpacket(char *ntpSrv) { // set all bytes in the buffer to 0 memset(packetBuffer, 0, NTP_PACKET_SIZE); // Initialize values needed to form NTP request // (see URL above for details on the packets) packetBuffer[0] = 0b11100011; // LI, Version, Mode packetBuffer[1] = 0; // Stratum, or type of clock packetBuffer[2] = 6; // Polling Interval packetBuffer[3] = 0xEC; // Peer Clock Precision // 8 bytes of zero for Root Delay & Root Dispersion packetBuffer[12] = 49; packetBuffer[13] = 0x4E; packetBuffer[14] = 49; packetBuffer[15] = 52; // all NTP fields have been given values, now // you can send a packet requesting a timestamp: Udp.beginPacket(ntpSrv, 123); //NTP requests are to port 123 Udp.write(packetBuffer, NTP_PACKET_SIZE); Udp.endPacket(); } void setup() { Serial.begin(115200); while (!Serial && (millis() < 5000)); Serial.print(F("\nStart UDPSendReceive 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(); /////////////////////////////////// Serial.println(F("\nStarting connection to server...")); // if you get a connection, report back via serial: Udp.begin(localPort); Serial.print(F("Listening on port ")); Serial.println(localPort); } void loop() { sendNTPpacket(timeServer); // send an NTP packet to a time server // wait for a reply for UDP_TIMEOUT milliseconds unsigned long startMs = millis(); while (!Udp.available() && (millis() - startMs) < UDP_TIMEOUT) {} // if there's data available, read a packet int packetSize = Udp.parsePacket(); if (packetSize) { Serial.print(F("UDP Packet received, size ")); Serial.println(packetSize); Serial.print(F("From ")); IPAddress remoteIp = Udp.remoteIP(); Serial.print(remoteIp); Serial.print(F(", port ")); Serial.println(Udp.remotePort()); // We've received a packet, read the data from it into the buffer Udp.read(packetBuffer, NTP_PACKET_SIZE); // the timestamp starts at byte 40 of the received packet and is four bytes, // or two words, long. First, esxtract the two words: unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); // combine the four bytes (two words) into a long integer // this is NTP time (seconds since Jan 1 1900): unsigned long secsSince1900 = highWord << 16 | lowWord; Serial.print(F("Seconds since Jan 1 1900 = ")); Serial.println(secsSince1900); // now convert NTP time into )everyday time: Serial.print(F("Unix time = ")); // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: const unsigned long seventyYears = 2208988800UL; // subtract seventy years: unsigned long epoch = secsSince1900 - seventyYears; // print Unix time: Serial.println(epoch); // print the hour, minute and second: Serial.print(F("The UTC time is ")); // UTC is the time at Greenwich Meridian (GMT) Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day) Serial.print(F(":")); if (((epoch % 3600) / 60) < 10) { // In the first 10 minutes of each hour, we'll want a leading '0' Serial.print(F("0")); } Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute) Serial.print(F(":")); if ((epoch % 60) < 10) { // In the first 10 seconds of each minute, we'll want a leading '0' Serial.print(F("0")); } Serial.println(epoch % 60); // print the second } // wait ten seconds before asking for the time again delay(10000); }