/*
This is a simple program that demonstrates how to use an ENC28J60 Ethernet controller module to syncronize
the Arduino's clock and the clock in an RTC module to time retreived from an NTP time server.
*/
#include <EtherCard.h> //GitHub - njh/EtherCard: EtherCard is an IPv4 driver for the ENC28J60 chip, compatible with Arduino IDE
#include <Time.h> //Time Library, Timekeeping and Time/Date Manipulation on Teensy
#include <TimeLib.h>
byte Ethernet::buffer[350]; // Ethernet storage buffer size
static byte mymac[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; // MAC address of ENC28J60
uint8_t ipDestinationAddress[4]; // Array to hold NTP time server IP
boolean request_sent = false; // Program control boolean
boolean got_response = false; // Program control boolean
uint32_t NTP_time; // Variable to store NTP time returned
time_t networkTime; // Variable to hold NTP time to be set in Arduino/RTC
// string conversion variables
char time_string[20];
char m[3], d[3], y[5], h[3], mn[3], s[3];
// Error control variable and screen title variables
byte moduleStatus;
void setup () {
//this doesn't work:
//char ws[] = "ptbtime1.ptb.de";
//PROGMEM const static char website[] = char ws[];
//this works:
PROGMEM const static char website[] = "ptbtime1.ptb.de"; // String to hold NTP time server address
Serial.begin(115200);
if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) moduleStatus = 0; // Create an instance of the ethernet class and start it up, else error out
else if (!ether.dhcpSetup()) moduleStatus = 1; // Obtain an IP from DHCP, else error out
else if (!ether.dnsLookup(website)) moduleStatus = 2; // Verify ability to use DNS, else error out
else moduleStatus = 3; // If all the above processes complete successfully, everything is a "Go"
}
// function to convert and display various IPs
char * formatIP(char *IP, uint8_t *f_ip) {
String outputString = IP;
for (byte q = 0; q < 4; q++) {
outputString.concat(f_ip[q]);
if (q < 3) {
outputString.concat(".");
}
//Serial.println(outputString);
}
static char IPout[25];
outputString.toCharArray(IPout, 25);
return IPout;
}
void draw(void) {
switch (moduleStatus) {
case 0:
Serial.println("Failed to access ethernet controller");
break;
case 1:
Serial.println("DHCP failed");
break;
case 2:
Serial.println("DNS failed");
break;
case 3:
Serial.println("ENC28J60 Ethernet Module");
break;
case 4:
Serial.println("Gets network time from an NTP server");
break;
case 5:
Serial.print("NTP Server Time: "); Serial.println(now());
break;
}
}
// function that makes the NTP time request, waits for a response, then returns the time as a <Time.h> library time_t variable
time_t getNTPTime(char NTPServer[15]) {
uint16_t dat_p;
int plen = 0;
while (!got_response) { // Wait until a time is successfully received from the NTP time server
plen = ether.packetReceive(); // Clear the buffer
dat_p = ether.packetLoop(plen); // wait for some data to fill the buffer
if (plen > 0) {
NTP_time = 0L; // Clear the variable the time will be stored in
if (ether.ntpProcessAnswer(&NTP_time, 123)) { // If a time was successfully received,
got_response = true; // set the "got response" flag, and
return time_t(NTP_time); // return the time as a <Time.h> library time_t variable
}
}
if (!request_sent) { // If the request hasn't been sent yet, send it
request_sent = true; // Set the "request sent" flag,
ether.parseIp(ipDestinationAddress, NTPServer); // convert the NTP server IP for use by the Ethernet library, and
ether.ntpRequest(ipDestinationAddress, 123); // send the NTP time request
}
}
}
void loop () {
if (moduleStatus == 3) {
delay(5000);
moduleStatus++;
}
else if (moduleStatus == 4) {
delay(7000);
moduleStatus++;
}
if (moduleStatus > 4) {
if (!got_response) { // If the time hasn't already been set, make an NTP request for the time
networkTime = getNTPTime("199.102.46.75"); // Make the request
setTime(networkTime-2208988800ul); // Set the Arduino's clock to UTC Unix time
Serial.println("Network Time: "); Serial.println(now());
//setSyncProvider(RTC.get); // Define the function to be used by <Time.h> to preiodically sync the Arduino's clock from the RTC
//adjustTime(-2208988800ul); // Correction for UTC Time in seconds
Serial.print("IP-Address: "); for (int ii=0; ii<=3; ii++) {Serial.print(ether.myip[ii]); if (ii<=2) {Serial.print(".");};} Serial.println();
Serial.print("Gateway-Address: "); for (int ii=0; ii<=3; ii++) {Serial.print(ether.gwip[ii]); if (ii<=2) {Serial.print(".");};} Serial.println();
Serial.print("Mask: "); for (int ii=0; ii<=3; ii++) {Serial.print(ether.netmask[ii]); if (ii<=2) {Serial.print(".");};} Serial.println();
Serial.print("DNS: "); for (int ii=0; ii<=3; ii++) {Serial.print(ether.dnsip[ii]); if (ii<=2) {Serial.print(".");};} Serial.println();
}
}
}