Hello,
I just started a project that should control my aquarium environment. (i know that there are many projects like that already but i want to learn during the process)
any way, the first thing that I'm trying to do is to get the current time.
I read about and downloaded the Time library (by mem) but i'm not sure how to use it.
my goal is to use this library with my Ethernet shield to get the current time with NTP and when there is no connection to the internet, i want it to use the system clock.
after reading some info about Time library i discovered that it is designed to try first with NTP and if something is wrong it's using the system time.
can anyone help me with simple example of using this library with NTP(and the fail safe with system time)? because the example supplied with the library is using UdpBytewise library that is quite old.
They usually come in waves. There was one a little while back, a bit different, but it goes like "I haven't done any programming before but I need to do and HAVE to have it done by tomorrow".
as i said before, i guess there are some aquarium projects out there.
i bought Arduino to learn some electronics and programming (i know Python but now this C like language).
if you ask, i don't need it by tomorrow... and I'm using NTP because i don't want to buy RTC right now and i think NTP is good enough right now.
any way, by saying system clock i meant the millis() method for counting when there is a problem with NTP.
Just teasing. But the DS1307 chip, plus a couple of components to make it work, costs around $5. That would keep track of time for 10 years. What happens to your aquarium if, when you turn it on, NTP isn't available? Then you can't count up from the current time, because you don't know it.
Anyway, if you are having trouble with the time library, how about posting your code, posting whatever errors you are getting, and we can help you out.
Hi Nick, thank you for your answer.
i started with the IDE example of: UdpNtpClient and i tried to isolate the function so i can call it whenever i want.
so i made a function called Test that returns the time since epoch.
the code:
*/
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
void setup()
{
Serial.begin(9600);
// start Ethernet and UDP
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
for(;;)
;
}
Udp.begin(localPort);
}
void loop()
{
Serial.println(Test());
}
unsigned long Test(){
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);
if ( Udp.parsePacket() ) {
// We've received a packet, read the data from it
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
//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;
// 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:
return epoch;
}
// wait ten seconds before asking for the time again
delay(10000);
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
{
// 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(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
}
but the problem is that from timw to time i get random numbers.
cam someone help with it?
example (look at: 27708, 18972):
Where did you find EthernetUdp.h? I don't seem to have that file.
// wait to see if a reply is available
delay(1000);
if ( Udp.parsePacket() ) {
// We've received a packet, read the data from it
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
I don't particularly like the delay here. This is pretty-well guaranteeing that your time is out by a second, right? May as well use a clock chip if you are going to throw accuracy away like that.
UDP is not guaranteed delivery. Does the Udp.read () function return the number of bytes read? I would check it is 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]);
And then I would be checking that the earlier bytes indicate a valid packet and not some sort of error response.
(edit) And before such a check I would make sure it is known, like memset the whole buffer to zeroes.
thank you, i will try what you suggest later this week.
i didn't wrote this code, it came with the new 1.0 IDE. (i only moved the code inside the loop to new func)
under: Open --> Ethernet --> UdpNtpClient
And if I may suggest, if you try getting the time every second by contacting an NTP server they will slap an IP ban on you faster than you can say "Jack Robinson". Then you still won't know the time.
So keep the NTP server for every few hours, and between that, count up the time interval.
I have a similar 1 seconds delay to wait for a reply from the server. At first I thought the same thing. This will throw off my second counter; however, I realized that because the delay is before my time variables are updated with the NTP (hours, minutes, and seconds) it doesn't matter. It will only make a difference if I wait the one second and I don't get a response. Doesn't that just mean that my timing will be off by one second until I get a new time update?
Ahhh,
after some experimentation I realized two things.
The 1 seconds delay does matter. What happens is it calls for the time, waits 1 second for a reply, and if there is a reply it reads the message. So all I do is derive the hours, minutes, seconds of the day from the message and then add 1 seconds to my seconds counter.
Don't always trust your computers clock. I went to The World Clock — Worldwide and found that my computers clock is off by 20 seconds!