Skip to content

Instantly share code, notes, and snippets.

@jmccrohan
Created November 5, 2011 17:58
Show Gist options
  • Save jmccrohan/1341824 to your computer and use it in GitHub Desktop.
Save jmccrohan/1341824 to your computer and use it in GitHub Desktop.
Nanode NTP Test/Demo
/*
* Arduino ENC28J60 Ethernet shield NTP client
* With extra bits for nanode
*/
#define NANODE
#define DEBUG
// uses RTClib from Jeelabs to provide DateTime functions
// http://cafe.jeelabs.net/software/#index3h1
#include <Wire.h>
#include <RTClib.h>
#include <EtherShield.h>
#ifdef NANODE
#include <NanodeMAC.h>
#endif
// Jan 1
#define SECS_YR_1900_2000 (3155673600UL)
#ifdef NANODE
static uint8_t mymac[6] = { 0,0,0,0,0,0 };
#else
static uint8_t mymac[6] = {
0x54,0x55,0x58,0x10,0x00,0x25};
#endif
// IP and netmask allocated by DHCP
static uint8_t myip[4] = { 0,0,0,0 };
static uint8_t mynetmask[4] = { 0,0,0,0 };
static uint8_t gwip[4] = { 0,0,0,0 };
static uint8_t dnsip[4] = { 0,0,0,0 };
static uint8_t dhcpsvrip[4] = { 0,0,0,0 };
// IP address of the host being queried to contact (IP of the first portion of the URL):
static uint8_t websrvip[4] = { 0, 0, 0, 0 };
#define NUM_TIMESERVERS 5
int currentTimeserver = 0;
// From http://support.ntp.org/bin/view/Servers/StratumTwoTimeServers
byte timeServer[][4] = {
{ 64, 90, 182, 55 } , // nist1-ny.ustiming.org
{ 66, 27, 60, 10 } , // ntp2d.mcc.ac.uk
{ 130, 88, 200, 4 } , // ntp2c.mcc.ac.uk
{ 31, 193, 9, 10 } , // clock02.mnuk01.burstnet.eu
{ 82, 68, 133, 225 } // ntp0.borg-collective.org.uk
};
// Packet buffer, must be big enough to packet and payload
#define BUFFER_SIZE 550
static uint8_t buf[BUFFER_SIZE+1];
EtherShield es=EtherShield();
#ifdef NANODE
NanodeMAC mac( mymac );
#endif
uint32_t lastUpdate = 0;
uint32_t time;
static const char day_abbrev[] PROGMEM = "SunMonTueWedThuFriSat";
void setup(){
Serial.begin(19200);
Serial.println("EtherShield/Nanode NTP Client");
// Initialise SPI interface
es.ES_enc28j60SpiInit();
// initialize enc28j60
#ifdef NANODE
es.ES_enc28j60Init(mymac,8);
#else
es.ES_enc28j60Init(mymac);
#endif
Serial.print( "ENC28J60 version " );
Serial.println( es.ES_enc28j60Revision(), HEX);
if( es.ES_enc28j60Revision() <= 0 ) {
Serial.println( "Failed to access ENC28J60");
while(1); // Just loop here
}
// init the ethernet/ip layer
// es.ES_init_ip_arp_udp_tcp(mymac,myip, 80);
// es.ES_client_set_gwip(gwip); // e.g internal IP of dsl router
lastUpdate = millis();
}
#ifdef DEBUG
// Output a ip address from buffer from startByte
void printIP( uint8_t *buf ) {
for( int i = 0; i < 4; i++ ) {
Serial.print( buf[i], DEC );
if( i<3 )
Serial.print( "." );
}
}
void printHex( uint8_t hexval ) {
if( hexval < 16 ) {
Serial.print("0");
}
Serial.print( hexval, HEX );
Serial.print( " " );
}
#endif
void loop(){
uint16_t dat_p;
uint16_t clientPort = 123;
char dstr[4];
int sec = 0;
int plen = 0;
boolean gotIp = false;
#ifdef DEBUG
Serial.println("Get IP");
#endif
// Get IP Address details
if( es.allocateIPAddress(buf, BUFFER_SIZE, mymac, 80, myip, mynetmask, gwip, dnsip, dhcpsvrip ) > 0 ) {
#ifdef DEBUG
// Display the results:
Serial.print( "My IP: " );
printIP( myip );
Serial.println();
Serial.print( "Netmask: " );
printIP( mynetmask );
Serial.println();
Serial.print( "DNS IP: " );
printIP( dnsip );
Serial.println();
Serial.print( "GW IP: " );
printIP( gwip );
Serial.println();
#endif
/* lastUpdate = millis();
Serial.print("Send NTP request ");
Serial.println( currentTimeserver, DEC );
es.ES_client_ntp_request(buf,timeServer[currentTimeserver++], ++clientPort);
if( currentTimeserver >= NUM_TIMESERVERS )
currentTimeserver = 0;
*/
}
else {
// Failed, do something else....
#ifdef DEBUG
Serial.println("Failed to get IP Address");
#endif
}
// Main processing loop now we have our addresses
while( es.ES_dhcp_state() == DHCP_STATE_OK ) {
// handle ping and wait for a tcp packet
dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));
// Has unprocessed packet response
if (dat_p > 0)
{
time = 0L;
if (es.ES_client_ntp_process_answer(buf,&time,clientPort)) {
Serial.print("Time:");
Serial.println(time); // secs since year 1900
if (time) {
time -= SECS_YR_1900_2000;
DateTime now(time);
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
int i=0;
while (i<3){
dstr[i]= pgm_read_byte(&(day_abbrev[(now.dayOfWeek()-1) * 3 + i]));
i++;
}
dstr[3]='\0';
Serial.print( dstr );
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
}
}
}
// Request an update every 20s
if( lastUpdate + 20000L < millis() ) {
// time to send request
lastUpdate = millis();
Serial.print("Send NTP request ");
Serial.println( currentTimeserver, DEC );
es.ES_client_ntp_request(buf,timeServer[currentTimeserver++], ++clientPort);
if( currentTimeserver >= NUM_TIMESERVERS )
currentTimeserver = 0;
}
}
}
// End
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment