Pages: 1 2 3 [4] 5 6 ... 10   Go Down
Author Topic: Time Library added to Playground  (Read 29322 times)
0 Members and 1 Guest are viewing this topic.
0
Online Online
Full Member
***
Karma: 0
Posts: 144
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: February 11, 2010, 12:54:04 pm by newhobby » Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Online Online
Full Member
***
Karma: 0
Posts: 144
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@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!
Logged

0
Offline Offline
Full Member
***
Karma: 4
Posts: 201
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Online Online
Full Member
***
Karma: 0
Posts: 144
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pretty sure you can do delay(0)
Logged

0
Offline Offline
Full Member
***
Karma: 4
Posts: 201
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks. that did it. It didn't work without a Alarm.delay() or some sort.
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: March 03, 2010, 04:17:27 pm by mem » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

1) Added some comments how to change UdpEthernet.h buffer size
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:
   
       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  smiley

Hi mem,
please review my changes and introduce them to your library.

Here is my code :
Code:
/*
 * 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.de
byte SNTP_server_IP[] = {
  192,53,103,108}; // ptbtime1.ptb.de

time_t prevDisplay = 0; // when the digital clock was displayed

// time zone correction [sec]. e.g. CET = -3600 sec
const 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
« Last Edit: March 06, 2010, 09:50:47 am by DRose28357 » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
/*
 * 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.de
byte SNTP_server_IP[] = {
  192,53,103,108}; // ptbtime1.ptb.de

time_t prevDisplay = 0; // when the digital clock was displayed

// time zone correction [sec]. e.g. CET = -3600 sec
const 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
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ditmar, thanks for your comments.

I had made the change to UdpBytewise.h buffer but forgot to add the comment to the sketch.
I have fixed this and included your other suggestions in the latest version that I will upload soon.

A useful enhancement that I have also added is to include the following after the UdpBytewise.h include:
Code:
#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
« Last Edit: March 06, 2010, 02:19:49 pm by mem » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
I need to add IR detection in one of my projects that is using TimeAlarms. The IR detection example is using
Code:
attachInterrupt(0, interrupt_func, FALLING);

Here is the IR detection example:
Code:
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
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Offline Offline
Full Member
***
Karma: 4
Posts: 201
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Is there a limit to how many Alarm.alarmRepeat I can use?
The answer is in the FAQ included in readme.txt file in the download:

Q: How many alarms can be created?
A: Up to six alarms can be scheduled.  
The number of alarms can be changed in the TimeAlarms header file (set by the constant dtNBR_ALARMS,
note that the RAM used equals dtNBR_ALARMS  * 12)


for nine alarms, use:
#define dtNBR_ALARMS 9
Logged

Pages: 1 2 3 [4] 5 6 ... 10   Go Up
Jump to: