Pages: [1]   Go Down
Author Topic: Example NTP code not working whe integrated into my sketch  (Read 372 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 96
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've been trying to add the basic NTP example code into my current project to keep the time synced with a time server but am having a strange issue with it.

My project runs a web server which I have a feeling has something to do with it.

If I load the example NTP code onto my Mega it works fine and receives the NTP time.

When the code is integrated into my existing program it fails to receive the NTP packet (or fails to read it) returning a No Response, then retrys, failing over and over to receive a response from the time server

It's not an issue with the IP addresses I'm using as I've modified the example NTP sketch to have the same IP details as my project with success..

Is there something I need to do to allow my project to run as a web server AND receive UDP NTP packets for time syncing?

I'm so close to finishing my project but the NTP not working is killing me!

Any thoughts guys?.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 615
Posts: 49392
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I've been trying to add the basic NTP example code into my current project
Which is where? We can't see through you.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 96
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ill post it tomorrow!

Note compiled size is about 60kb...
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 96
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is the code. Sorry for the large size but its a rather large project. I have deleted most of the code as its way to big to post. I just included the header part, Setup() and the function for NTP

So the issue is when I try to use the NTP code (the built in arduino example sketch) within this project I get "No response from NTP".
I dont believe its network setting as if I use this the same networking settings with the example push NTP sketch it works 100% ok.

It has to be something to to do with the fact I am running a webserver as well, possibly socket binding. Note commenting out the server.begin() does not make the NTP work, I have tried this.
 
Also if anyone has suggestions on shaving some size of this project I would be quite happy. I know theres lots of room for improvements here.  



Code:
//Push Scheduler Control Centre.
//By Jasper Parker (2013)

//Included Libraries
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>
#include <TimeAlarms.h>
#include <EEPROM.h>
#include <Wire.h>
#include <DS1307RTC.h>

// NTP stuff
IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov
const int timeZone = 8;     // Perth
EthernetUDP Udp;
unsigned int localPort = 8888;  // local port to listen for UDP packets

//Set a Mac Address
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

//Set the IP address from EEPROM memory  
byte ip[4] = {
  EEPROM.read(4), EEPROM.read(5), EEPROM.read(6), EEPROM.read(7) };
//byte ip[4] = { 192, 168, 1, 125 };
IPAddress gateway( 192,168,1,1 );
IPAddress subnet( 255,255,255,0 );

//Create server and client instances
EthernetClient client;
EthernetServer server(80);

//Some required Boolean variables
boolean macro1HasRun = false;
boolean macro2HasRun = false;
boolean macro3HasRun = false;
boolean macro4HasRun = false;
boolean macro5HasRun = false;
boolean macro6HasRun = false;
boolean macro7HasRun = false;
boolean macro8HasRun = false;
boolean macro9HasRun = false;
boolean macro10HasRun = false;
boolean sleepTimerKill = false;

//boolean awaitingTime = true;
int prevDisplay;

//Old System Time method
//int sHours,sMinutes;

//Arrays to store current selected schedule days
char printDays[100];

//Sleep Timer variabkles
byte sleepTimer, sleepTimerMacro;

//Scheduling Variables
byte tHours1,tMinutes1,macro1,tHours2,tMinutes2,macro2,tHours3,tMinutes3,macro3,tHours4,tMinutes4,macro4,tHours5,
tMi

//Day collection
byte macro1DayM,macro1DayT,macro1DayW,macro1DayTh,macro1DayF,macro1DayS,macro1DaySu,macro2DayM,macro2DayT,macro2DayW,macro2DayTh,macro2DayF,macro2DayS,macro2DaySu,

byte pushIP1,pushIP2,pushIP3,pushIP4;
byte arduinoIP1,arduinoIP2,arduinoIP3,arduinoIP4;


//Set Push IP based on EEPROM memory
byte push[4] = {
  EEPROM.read(0), EEPROM.read(1), EEPROM.read(2), EEPROM.read(3) };
char buffer[16];

//Requiered HTTP request for sending commands to Push
String pushMacro = "GET /bwc.xml?bwc=bwc:macro:";



void setup()
{
  //If no IP address has been writtin to EEPROM on this device set to default address
  if((EEPROM.read(4))==255)  {  
    byte ip[4] = {
      192,168,1,125                };
  }

  //Sets time
  //setSyncProvider(RTC.get);
  //setSyncInterval(600);
  
  //Initilise  network things
  Wire.begin();
  Serial.begin(9600);
  Ethernet.begin(mac, ip, gateway, subnet);
  delay(1000);
  server.begin();
  delay(1000);
  Udp.begin(localPort);
  
   //System has booted
  Serial.println(F("System Booted"));
  delay(1000);
  Serial.println("waiting for sync");
  setSyncProvider(getNtpTime);

  
}

void loop()
{  
  }
  
  

/*-------- NTP code ----------*/

const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBufferT[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets

time_t getNtpTime()
{
  while (Udp.parsePacket() > 0) ; // discard any previously received packets
  Serial.println("Transmit NTP Request");
  sendNTPpacket(timeServer);
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500) {
    int size = Udp.parsePacket();
    if (size >= NTP_PACKET_SIZE) {
      Serial.println("Receive NTP Response");
      Udp.read(packetBufferT, NTP_PACKET_SIZE);  // read packet into the buffer
      unsigned long secsSince1900;
      // convert four bytes starting at location 40 to a long integer
      secsSince1900 =  (unsigned long)packetBufferT[40] << 24;
      secsSince1900 |= (unsigned long)packetBufferT[41] << 16;
      secsSince1900 |= (unsigned long)packetBufferT[42] << 8;
      secsSince1900 |= (unsigned long)packetBufferT[43];
      return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
    }
  }
  Serial.println("No NTP Response");

  return 0; // return 0 if unable to get the time
}

// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
  // set all bytes in the buffer to 0
  memset(packetBufferT, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBufferT[0] = 0b11100011;   // LI, Version, Mode
  packetBufferT[1] = 0;     // Stratum, or type of clock
  packetBufferT[2] = 6;     // Polling Interval
  packetBufferT[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBufferT[12]  = 49;
  packetBufferT[13]  = 0x4E;
  packetBufferT[14]  = 49;
  packetBufferT[15]  = 52;
  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:      
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBufferT, NTP_PACKET_SIZE);
  Udp.endPacket();
}

Logged

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 147
Posts: 6038
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You are not calling the Ethernet.begin() function correctly.
Code:
// this
  Ethernet.begin(mac, ip, gateway, subnet);
// should be like this
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
This presumes your router will provide dns for the Arduino. If not, you must replace the first "gateway" ip with a valid dns server ip.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 96
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good suggestion ill be able to try this when I get home from work. Ill just specify the DNS as the same as my gateway.

I could also try 8.8.8.8 (google DNS)

The only thing I can see wrong with this suggested fix is that if im specifying the time server as an IP address already and not a domain name then a domain name server address shouldn't be required as my understanding is a DNS will just be converting the domain address to an IP address if this is not already known... (although correct me if im wrong..)
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 96
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You are not calling the Ethernet.begin() function correctly.
Code:
// this
  Ethernet.begin(mac, ip, gateway, subnet);
// should be like this
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
This presumes your router will provide dns for the Arduino. If not, you must replace the first "gateway" ip with a valid dns server ip.


You were 100% right
This has resolved the issue, THANK YOU SO MUCH!
Logged

Pages: [1]   Go Up
Jump to: