Go Down

### Topic: Time Library added to Playground (Read 77564 times)previous topic - next topic

#### newhobby

#45
##### Feb 11, 2010, 06:52 pmLast Edit: Feb 11, 2010, 06:54 pm by newhobby Reason: 1
Hi,
I'm having a problem with your leap year calculation.
For some reason, the function setTime() always adds one more day when you use the year 2000.
I did change this:
#define LEAP_YEAR(_year) ( ( (((1970+_year)%4)==0) && ((1970+year)%100!=0) ) || ((1970+_year)%400==0) )
to this:
#define LEAP_YEAR(_year) ( ( (((1970+_year)%4)==0) && ((1970+_year)%100!=0) ) || ((1970+_year)%400==0) )
but still have problems.
Would you be able to check on that?

Thanks

#### mem

#46
##### Feb 11, 2010, 08:11 pm
good catch on the missing underscore.

That calculation  is used internally using Unix time where 1970 is year 0
so  year 2000 would be given to that expression as year 30.

#### newhobby

#47
##### Feb 11, 2010, 10:23 pm
I'm sorry for not being so clear.
Here is an example of faulty unix time calculation:
setTime(8,29,40,1,1,0); // set time to 8:29:40am Jan 1 2000
Serial.print(month());
Serial.print("/");
Serial.print(day());
Serial.print("/");
Serial.println(year());
And this is what you get from serial output:
1/2/2000
Do you see where I'm trying to get?
It increments by 1 day because of leap year calculation. I just can't find out where and I just didn't have time to look further and test it if it is every 4 years or just on centuries or just on milleniums.
If you can look into it, I would appreciate your effort.
Great library btw. I'm using a modified version for my own purposes.

Thanks.

#### mem

#48
##### Feb 12, 2010, 12:58 pm
@newhobby, I have uploaded an update to the Time library that fixes an error in the leap calculation. This should resolve the problem you found.

have fun!

#### mistergreen

#49
##### Mar 03, 2010, 03:17 am
Hi,
I'm new using this library. The example works fine but the events like Alarm.alarmRepeat() won't trigger when I take delay(1000) out of the loop(). Is there a way around this?

I need event to occur without the delay.

thanks.

#### newhobby

#50
##### Mar 03, 2010, 06:05 am
Pretty sure you can do delay(0)

#### mistergreen

#51
##### Mar 03, 2010, 07:36 am
thanks. that did it. It didn't work without a Alarm.delay() or some sort.

#### mem

#52
##### Mar 03, 2010, 10:17 pmLast Edit: Mar 03, 2010, 10:17 pm by mem Reason: 1
Yes, you need to do alarm.delay when using the alarm library.

as it says in the documentation for the timeAlarm library:
Quote
Note that the loop code calls Alarm.delay(1000) -  Alarm.delay must be used
instead of the usual arduino delay function because the alarms are serviced in the Alarm.delay method.
Failing to regularly call Alarm.delay will result in the alarms not being triggered
so always use Alarm.delay instead of delay in sketches that use the Alarms library.

#### DRose28357

#53
##### Mar 06, 2010, 02:35 pmLast Edit: Mar 06, 2010, 03:50 pm by DRose28357 Reason: 1
I had some problems to get "Time_SNP.pde" up and running. Main reason was wrong buffer length in UdpEtherne.h. So i introduced some changes to "Time_NTP.pde" code to ease beginners to bring it to operation.

2) removed gateway adress, this would normaly not be neccesary.
3) renamed Server-IP Variable to "SNTP_server_IP[]" for better international reading.
4) introduced some more time servers as a comment to easy try some other servers.
5) added a const unsigned long for time zone correction, which ist used in unsigned long getNtpTime() function. This could also be done by definig 24 different like e.g.
Code: [Select]
`           const unsigned long seventy_years_CET = 22089XXXXUL;//     const unsigned long seventy_years_UTC = 2208988800UL;//     const unsigned long seventy_years_    ____ and so on ____`
Which version would you or a beginner prefer for time zone correction ? i can provide the changes if someone wants me to do

Hi mem,

Here is my code :
Code: [Select]
`/* * Time_NTP.pde * Example showing time sync to NTP time source * * This sketch uses the Ethenet library with the user contributed UdpBytewise extension */#include <Time.h> #include <Ethernet.h>// the follwing library should be copied to the Ethernet directory#include <UdpBytewise.h>  // UDP library from: bjoern@cs.stanford.edu 12/30/2008 //  You will also need to modify the UdpBytewise.h library to allow enough space in the buffers for the NTP packets. //  Open up UdpBytewse.h and change these lines:////  #define UDP_TX_PACKET_MAX_SIZE 32//  #define UDP_RX_PACKET_MAX_SIZE 32////  to this:////  #define UDP_TX_PACKET_MAX_SIZE 64//  #define UDP_RX_PACKET_MAX_SIZE 64//byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; byte ip[] = {  192, 168, 178, 100 };   // fill in your local Arduino ip adress  // byte SNTP_server_IP[] = { 192, 43, 244, 18}; // time.nist.gov// byte SNTP_server_IP[] = { 130,149,17,21}; // ntps1-0.cs.tu-berlin.debyte SNTP_server_IP[] = {  192,53,103,108}; // ptbtime1.ptb.detime_t prevDisplay = 0; // when the digital clock was displayed// time zone correction [sec]. e.g. CET = -3600 secconst unsigned long add_time_zone=-3600UL; void setup() {  Ethernet.begin(mac,ip);    Serial.begin(19200);  Serial.println ("waiting for NTP server ...");  setSyncProvider(getNtpTime);  while(timeStatus()== timeNotSet)      ; // wait until the time is set by the sync provider}void loop(){    if( now() != prevDisplay) //update the display only if the time has changed  {    prevDisplay = now();    digitalClockDisplay();    }}void digitalClockDisplay(){  // digital clock display of the time  Serial.print(hour());  printDigits(minute());  printDigits(second());  Serial.print(" sec ");  Serial.print(day());  Serial.print(".");  Serial.print(month());  Serial.print(".");  Serial.print(year());  Serial.println(); }void printDigits(int digits){  // utility function for digital clock display: prints preceding colon and leading 0  Serial.print(":");  if(digits < 10)    Serial.print('0');  Serial.print(digits);}/*-------- NTP code ----------*/unsigned long getNtpTime(){  sendNTPpacket(SNTP_server_IP);  delay(200); // for roundtriptiime in slow environtment  if ( UdpBytewise.available() ) {    for(int i=0; i < 40; i++){      UdpBytewise.read(); // ignore every field except the time    }        const unsigned long seventy_years = 2208988800UL+add_time_zone;            return getUlong() -  seventy_years;        }  return 0; // return 0 if unable to get the time}unsigned long sendNTPpacket(byte *address){  UdpBytewise.begin(123);  UdpBytewise.beginPacket(address, 123);  UdpBytewise.write(B11100011);   // LI, Version, Mode  UdpBytewise.write(0);    // Stratum  UdpBytewise.write(6);  // Polling Interval  UdpBytewise.write(0xEC); // Peer Clock Precision  write_n(0, 8);    // Root Delay & Root Dispersion  UdpBytewise.write(49);  UdpBytewise.write(0x4E);  UdpBytewise.write(49);  UdpBytewise.write(52);  write_n(0, 32); //Reference and time stamps    UdpBytewise.endPacket();   }unsigned long getUlong(){  unsigned long ulong = (unsigned long)UdpBytewise.read() << 24;  ulong |= (unsigned long)UdpBytewise.read() << 16;  ulong |= (unsigned long)UdpBytewise.read() << 8;  ulong |= (unsigned long)UdpBytewise.read();  return ulong;}void write_n(byte what, int how_many){  for( int i = 0; i < how_many; i++ )    UdpBytewise.write(what);}`

Happy playing with Arduino !
Ditmar

#### DRose28357

#54
##### Mar 06, 2010, 03:50 pm
Hi folks,
i did a mash up because i am so lazy ....

I dont want to enter 11 characters to the terminal. I have an DS1307 and an Ethernet shield, so why not synchronising or initialising the DS1307 RTC with a NTP server delivered time ....

Hi mem,
may be you like it. You can include the code in your time library examples.

... and her is the code.

Code: [Select]
`/* * TimeSetRTCByNTP.pde * Example showing time sync of RTC DS1307 with NTP time source * it is a mash up out of "TimeRTCSet.pde" and "TimeNTP.pde" * * This sketch uses the Ethenet library with the user contributed UdpBytewise extension */#include <Time.h> #include <Wire.h>  #include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t#include <Ethernet.h>// the follwing library "UdpBytewise.h" and "UdpBytewise.cpp" should be copied to the Ethernet directory#include <UdpBytewise.h>  // UDP library from: bjoern@cs.stanford.edu 12/30/2008 //  You will also need to modify the UdpBytewise.h library to allow enough space in the buffers for the NTP packets. //  Open up UdpBytewse.h and change these lines:////  #define UDP_TX_PACKET_MAX_SIZE 32//  #define UDP_RX_PACKET_MAX_SIZE 32////  to this:////  #define UDP_TX_PACKET_MAX_SIZE 64//  #define UDP_RX_PACKET_MAX_SIZE 64//byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; byte ip[] = {  192, 168, 178, 100};   // fill in your local Arduino ip adress// byte SNTP_server_IP[] = { 192, 43, 244, 18}; // time.nist.gov// byte SNTP_server_IP[] = { 130,149,17,21}; // ntps1-0.cs.tu-berlin.debyte SNTP_server_IP[] = {  192,53,103,108}; // ptbtime1.ptb.detime_t prevDisplay = 0; // when the digital clock was displayed// time zone correction [sec]. e.g. CET = -3600 secconst unsigned long add_time_zone=-3600UL; void setup() {  Ethernet.begin(mac,ip);    Serial.begin(9600);  Serial.println ("waiting for NTP server ...");  setSyncProvider(getNtpTime);  while(timeStatus()== timeNotSet)      ; // wait until the time is set by the sync provider  RTC.set(now());   // set the RTC time to the received value  Serial.print ("got NTP server time to RTC ...  ");  digitalClockDisplay();  setSyncProvider(RTC.get);   // set time source to get the time from the RTC for verification  if(timeStatus()!= timeSet)    Serial.println("Unable to sync with the RTC");  else    Serial.println("RTC has set the system time"); }void loop(){    if( now() != prevDisplay) //update the display only if the time has changed  {    prevDisplay = now();    digitalClockDisplay();    }}void digitalClockDisplay(){  // digital clock display of the time  Serial.print(hour());  printDigits(minute());  printDigits(second());  Serial.print(" sec ");  Serial.print(day());  Serial.print(".");  Serial.print(month());  Serial.print(".");  Serial.print(year());  Serial.println(); }void printDigits(int digits){  // utility function for digital clock display: prints preceding colon and leading 0  Serial.print(":");  if(digits < 10)    Serial.print('0');  Serial.print(digits);}/*-------- NTP code ----------*/unsigned long getNtpTime(){  sendNTPpacket(SNTP_server_IP);  delay(200); // for roundtriptiime in slow environtment  if ( UdpBytewise.available() ) {    for(int i=0; i < 40; i++){      UdpBytewise.read(); // ignore every field except the time    }        const unsigned long seventy_years = 2208988800UL+add_time_zone;            return getUlong() -  seventy_years;        }  return 0; // return 0 if unable to get the time}unsigned long sendNTPpacket(byte *address){  UdpBytewise.begin(123);  UdpBytewise.beginPacket(address, 123);  UdpBytewise.write(B11100011);   // LI, Version, Mode  UdpBytewise.write(0);    // Stratum  UdpBytewise.write(6);  // Polling Interval  UdpBytewise.write(0xEC); // Peer Clock Precision  write_n(0, 8);    // Root Delay & Root Dispersion  UdpBytewise.write(49);  UdpBytewise.write(0x4E);  UdpBytewise.write(49);  UdpBytewise.write(52);  write_n(0, 32); //Reference and time stamps    UdpBytewise.endPacket();   }unsigned long getUlong(){  unsigned long ulong = (unsigned long)UdpBytewise.read() << 24;  ulong |= (unsigned long)UdpBytewise.read() << 16;  ulong |= (unsigned long)UdpBytewise.read() << 8;  ulong |= (unsigned long)UdpBytewise.read();  return ulong;}void write_n(byte what, int how_many){  for( int i = 0; i < how_many; i++ )    UdpBytewise.write(what);}`

happy Ardunio computing ...
Ditmar

#### mem

#55
##### Mar 06, 2010, 08:11 pmLast Edit: Mar 06, 2010, 08:19 pm by mem Reason: 1

I had made the change to UdpBytewise.h buffer but forgot to add the comment to the sketch.

A useful enhancement that I have also added is to include the following after the UdpBytewise.h include:
Code: [Select]
`#if  UDP_TX_PACKET_MAX_SIZE <64 ||  UDP_RX_PACKET_MAX_SIZE < 64#error : UDP packet size to small - modify UdpBytewise.h to set buffers to 64 bytes#endif`
This checks the buffer sizes and reports an error if too small

edit: updated sketch uploaded to playground

#### ioan

#56
##### Mar 09, 2010, 07:11 am
Hi,
I need to add IR detection in one of my projects that is using TimeAlarms. The IR detection example is using
Code: [Select]
`attachInterrupt(0, interrupt_func, FALLING);`

Here is the IR detection example:
Code: [Select]
`void loop() {  // read the state of the IRDetector value:  objectPresent = digitalRead(IRDetectorPin2);  // check if the pushbutton is pressed.  // if it is, the buttonState is HIGH:  if (objectPresent == HIGH)  {          digitalWrite(LEDPin12, HIGH);  }  else  {    digitalWrite(LEDPin12, LOW);  }  attachInterrupt(0, interrupt_func, FALLING); }`

Does attachInterrupt mess up the timer alarms? What should I use to replace attachInterrupt?

TIA
-ioan

#### mem

#57
##### Mar 09, 2010, 10:25 am
attachInterrupt should be done once only in setup, not in loop.
See: http://www.arduino.cc/en/Reference/AttachInterrupt

You should be fine using alarms  and attachInterrupt together in a sketch.

#### mistergreen

#58
##### Mar 25, 2010, 04:02 am
Hi,
Is there a limit to how many Alarm.alarmRepeat I can use?
I have 9 alarmRepeat defined and only first 6 out of the 9 triggers. When I comment out a few at the beginning, they all work.

thanks.

#### mem

#59
##### Mar 25, 2010, 10:15 am
Quote
Is there a limit to how many Alarm.alarmRepeat I can use?