Pages: 1 ... 6 7 [8] 9 10   Go Down
Author Topic: Time Library added to Playground  (Read 36841 times)
0 Members and 1 Guest are viewing this topic.
Seattle, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

mem there is no sync program in the zip file that users can use to send through their serial port to the arduino. I'm new to hardware programming and I assumed that the Arduino program would request it from the port itself instead of the computer being required to send it.

Peeter123's program was extremely helpful with getting it to work for me. File link on page 2 and his source is on page 3.

It would also be good to note about which pins the RTC goes in (of course they can find that out from the wire library description) and about the autoreset in the Time documentation as well.
« Last Edit: September 20, 2010, 02:11:14 am by ZNahum » Logged

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

Hi,

I tried this library and can't get the seconds to match up.  I set the time, then instantly display it, and it's never quite right.

I notice that if you subtract the ms/1000 from the last printed line from the ms/1000  of the new first printed line you can predict the seconds. (for example:

Code:
10 13:22:10
--------
19 13:22:9

19-10 = 9

Am I doing something wrong?
Thanks,
-Mike

Here's my sample code (running on an arduino mega)

Code:
#include <string.h>
#include <Time.h>

char datestr[15];
char timestr[15];

int availableMemory()
{
 int size = 8192;
 byte *buf;
 while ((buf = (byte *) malloc(--size)) == NULL);
 free(buf);
 return size;
}

//====================================================================================
void setup()
{

  
  Serial.begin(9600);

  Serial.print("free memory = "); // good to check this.  Copied it from a forum somewhere.
  Serial.println(availableMemory());
  



}

//===================================================================================================
void loop()
{
  char incoming_data,ii;
  if(Serial.available()) // keypresses to run the show.  Good for testing stuff.
  {
    incoming_data = Serial.read();
    if (incoming_data=='~')
     {
            setTime(13, 22, 0, 3, 10, 2010);
            for (ii=0;ii<5;ii++)
            {
            time_t tnow = now();
            //sprintf(datestr,"%02d-%02d-%04d ",month(tnow), day(tnow), year(tnow));
            //sprintf(timestr,"%02d:%02d:%02d",hour(tnow),minute(tnow),second(tnow));
            Serial.print((millis()/1000));
            Serial.print(" ");
            Serial.print(hour(tnow));
            Serial.print(":");
            Serial.print(minute(tnow));
            Serial.print(":");
            Serial.println(second(tnow));
            //Serial.println(timestr);
            delay(1000);
            }
            Serial.println("--------");

     }
  }
}

Here's my output:
Code:
free memory = 7439
6 13:22:6
7 13:22:7
8 13:22:8
9 13:22:9
10 13:22:10
--------
19 13:22:9
20 13:22:10
21 13:22:11
22 13:22:12
23 13:22:13
--------
28 13:22:5
29 13:22:6
30 13:22:7
31 13:22:8
32 13:22:9
--------
75 13:22:43
76 13:22:44
77 13:22:45
78 13:22:46
80 13:22:48
--------
108 13:22:28
109 13:22:29
110 13:22:30
111 13:22:31
112 13:22:32
--------
153 13:22:41
154 13:22:42
155 13:22:43
156 13:22:44
157 13:22:45
--------
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 50039
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm not sure that I understand what your problem is, but, the first value that you print is done this way:
Code:
           Serial.print((millis()/1000));
There will be truncation as a result of the division, and there will be rounding as a result of the conversion to string for printing. There might also be problems due to the fact that you are dividing an unsigned long by an int.

Would you try again to explain what your problem is, if this is not the culprit?
Logged

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

Quote
I'm not sure that I understand what your problem is, but, the first value that you print is done this way:
There will be truncation as a result of the division, ...
Would you try again to explain what your problem is, if this is not the culprit?

Thanks for looking at it.  That's not the problem, I understand the variable type and rounding but that part is working fine.

The code waits for you to type "~" then sets the clock to 13:22:00, then immediately prints out the time once a second for 5 seconds.  It also prints the millis counter (divided by 1000) as a reference.  I expect the time printout to look like 13:22:00, 13:22:01, 13:22:02...13:22:05.  I understand that with excecution times etc it might miss a second every now and then and am not worried about that either.

What I consistently get is the clock set to the 13:22:00 plus the time difference between the last clock print time from millis() and the current time from millis().  For example, the first set of data ends with a millis of 10e3, and the second set starts with millis of 19e3 (10 and 19 in the left column), and the second clock printouts are 9 seconds fast.  Further down the there is a printout at 32 seconds then a clock setting at 75 seconds, and the clock is set 43 seconds fast (to 13:22:43).  You can subtract the number on the left below the ----- from the number on the left above the ----- and predict how far off the clock setting will be.

I seem to be missing an activate/set/do it now!!! sort of command; my clock setting using setTime doesn't happen until sometime later.

I did switch to the old DateTime library and got this working just fine.  Are there any bugs with the DateTime library or was it abandoned because there are more features in Time?

Thanks,
-Mike
Logged

London, England
Offline Offline
Edison Member
*
Karma: 4
Posts: 1026
Go! Go! Arduinoooo !!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Is it just me or does this library not work under IDE 0021? The NTP example is throwing up all kinds of errors.
Logged

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

It's not just you, Mike. I've been trying to sort through this as well.

I haven't tested the sketch yet, but I finally got it to compile on 0021. I'm not terribly familiar with C/C++ :-[ so I wouldn't mind a few "don't do that; do this" comments from the more elite folks.

Here's what I did:
1) I previously had these files in an Ethernet directory under the <mysketches>/libraries directory. This works for other libraries but this TimeNTP code seemed to have issues finding the built-in Ethernet library files. I found the built-in Ethernet library directory and moved the library files for the Time stuff all into there.
2) In all the files (UdpBytewise,UdpString,UdpRaw), change the extern area to:
// extern "C" {
// #include "types.h"
#include "w5100.h"
#include "socket.h"
// }
3) #include <SPI.h> at the top of the sketch
4) Seems like some string methods got dropped from 0021 so these libraries have a hard time calling cstr or capacity on String. In hardware/arduino/cores/arduino/WString.h add the following to the public defs:
    const char * cstr() const {return _buffer;}
    int capacity() {return _capacity;}
5) This one I'm the least sure about what's the best thing to do about the W5100 class - where/how it ought to be instantiated. The below will at least fix the compilation issues... so it's a naive start.
UdpRaw.cpp:
W5100Class wizzy;
int UdpRawClass::available() {
      return wizzy.getRXReceivedSize(_sock);
}
and UdpString
W5100Class wizzyForUdpString;
int UdpStringClass::available() {
      return wizzyForUdpString.getRXReceivedSize(_sock);
}
« Last Edit: October 09, 2010, 09:10:19 pm by marcpeabody » Logged

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

I forgot to mention that references in the Udp code to SnMR need to be updated to SnMR::UDP

I just tried the TimeNTP sketch (with 0021) on my Arduino and I'm successfully getting timestamps outputted to Serial every second.
Logged

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

I don't know a whole lot about arduino programming ect. but i downloaded the libary(the latestest version, download a few minutes ago) extacted it, copied and pasted it into the libraries file, load a example into arduino and try to compile and get the following errors in red at the bottom:

 
Code:
TimeSerial.cpp:12:20: error: Time.h: No such file or directory
TimeSerial:16: error: 'time_t' does not name a type
TimeSerial.cpp: In function 'void setup()':
TimeSerial:19: error: 'requestSync' was not declared in this scope
TimeSerial:19: error: 'setSyncProvider' was not declared in this scope
TimeSerial.cpp: In function 'void loop()':
TimeSerial:28: error: 'timeStatus' was not declared in this scope
TimeSerial:28: error: 'timeNotSet' was not declared in this scope
TimeSerial:30: error: 'timeSet' was not declared in this scope
TimeSerial.cpp: In function 'void digitalClockDisplay()':
TimeSerial:38: error: 'hour' was not declared in this scope
TimeSerial:39: error: 'minute' was not declared in this scope
TimeSerial:40: error: 'second' was not declared in this scope
TimeSerial:42: error: 'day' was not declared in this scope
TimeSerial:44: error: 'month' was not declared in this scope
TimeSerial:46: error: 'year' was not declared in this scope
TimeSerial.cpp: In function 'void processSyncMessage()':
TimeSerial:64: error: 'time_t' was not declared in this scope
TimeSerial:64: error: expected `;' before 'pctime'
TimeSerial:68: error: 'pctime' was not declared in this scope
TimeSerial:71: error: 'pctime' was not declared in this scope
TimeSerial:71: error: 'setTime' was not declared in this scope
TimeSerial.cpp: At global scope:
TimeSerial:76: error: 'time_t' does not name a type


I may be doing something wrong, if i am let me know, its the TimeSerial example sketch all i did was load the example(from the file, examples list) and hit compile. If it matters I am running the IDE 0021 on Windows 7 64 bit. Due to these errors i haven't even got to try loading it to an arduino (i have an uno and duemilanove)
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 50039
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Open the IDE, with a blank sketch. Use the Sketch + Import Library... menu item to try to import the Time library. You will probably find that you can't.

This indicates that you did not put the library in the correct place, or correctly in the place that you put it.

Make note of the name of one of the libraries that you CAN import. Use your computer's search capability to find that name. Look at where that name occurs, as opposed to where you put the time library. Look at the structure of that library, as opposed to the time library structure that you created.

The difference should be obvious. If not, post what you find, and we'll help you get it straightened out.
Logged

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

Hi, I propose a different way to set the date / time for the library. I implemented this because I get the time information out of a HTTP response. Here we find an UTC string where the month is encoded as 3 letter string.

Code:
Wed, 27 Oct 2010 18:18:04 GMT

I have an example code which works for me:

First define the months as PROGMEM variables.
Code:
prog_char m_jan[] PROGMEM = "Jan";   // The months for UTC Date conversion
prog_char m_feb[] PROGMEM = "Feb";
prog_char m_mar[] PROGMEM = "Mar";
prog_char m_apr[] PROGMEM = "Apr";
prog_char m_may[] PROGMEM = "May";
prog_char m_jun[] PROGMEM = "Jun";
prog_char m_jul[] PROGMEM = "Jul";
prog_char m_aug[] PROGMEM = "Aug";
prog_char m_sep[] PROGMEM = "Sep";
prog_char m_oct[] PROGMEM = "Oct";
prog_char m_nov[] PROGMEM = "Nov";
prog_char m_dec[] PROGMEM = "Dec";

PROGMEM const char *MONTHS[] =          // as an array
{  
  m_jan, m_feb, m_mar, m_apr, m_may, m_jun, m_jul, m_aug, m_sep, m_oct, m_nov, m_dec
};

Then just iterate over them until it could be matched. datebuf helds a string as shown above.

Code:
   int h,m,s,y,d,mo = 0;
    char mon[2];
    sscanf(datebuf,"%*s %d %s %d %d:%d:%d",&d,&mon,&y,&h,&m,&s); //split the UTC Date string
  
    while (strcmp_P(mon, (char*)pgm_read_word(&(MONTHS[mo]))) != 0) //decode the month
        mo++;

    // NOTICE: the actual month is mo+1 !!
    setTime(h,m,s,d,mo+1,y); // to set with the time library

I hope this helps.. Who do I best contact to integrate this in the Time Library?

Hope this helps someone
Michael
Logged

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

Syncing time is not precise. I am using the timeserial example with a little addition. Just after the  setTime(pctime); command I've added two commands to print both the pctime (that was just set) and the now() internal time. I suppose they should be the same, but they never are.

The output is like this:

1288477507
1288477511


1288477507
1288477510


1288477507
1288477610


1288477507
1288477516

I think this is the same problem Breezetrees is referring to. Any idea how to sync the time with more precision?
« Last Edit: October 30, 2010, 07:57:52 pm by Thomas_de_Graaff » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 50039
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Just after the  setTime(pctime); command I've added two commands to print both the pctime (that was just set) and the now() internal time. I suppose they should be the same, but they never are.
Let's see the code. There is, of course, some time taken to set the time and some time taken to get the time. There may also, depending on your code, be time taken to print the time to the serial port.
Logged

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

Just send T1262347200 a couple of times via serial, and see the result...

Code:
/*
 * TimeSerial.pde
 * example code illustrating Time library set through serial port messages.
 *
 * Messages consist of the letter T followed by ten digit time (as seconds since Jan 1 1970)
 * you can send the text on the next line using Serial Monitor to set the clock to noon Jan 1 2010
 T1262347200  
 *
 * A Processing example sketch to automatically send the messages is inclided in the download
 */
 
#include <Time.h>  

#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message

void setup()  {
  Serial.begin(9600);
  setSyncProvider( requestSync);  //set function to call when sync required
  Serial.println("Waiting for sync message");
}

void loop(){    
  if(Serial.available() )
  {
    processSyncMessage();
  }
  if(timeStatus()!= timeNotSet)  
  {
    digitalWrite(13,timeStatus() == timeSet); // on if synced, off if needs refresh  
    digitalClockDisplay();  
  }
  delay(1000);
}

void digitalClockDisplay(){
  /* // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  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);
}

void processSyncMessage() {
  // if time sync available from serial port, update time and return true
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of a header and ten ascii digits
    char c = Serial.read() ;
    Serial.print(c);  
    if( c == TIME_HEADER ) {      
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){  
        c = Serial.read();          
        if( c >= '0' && c <= '9'){  
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
        }
      }  
      setTime(pctime);   // Sync Arduino clock to the time received on the serial port
      Serial.print("timeStatus() = ");
      Serial.print(timeStatus());
      Serial.print(", pctime = ");
      Serial.print(pctime);
      Serial.print(" and now() = ");
      Serial.println(now());
    }  
  }
}

time_t requestSync()
{
  Serial.print(TIME_REQUEST,BYTE);  
  return 0; // the time will be sent later in response to serial mesg
}

Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 50039
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Try calling now() immediately after setTime(), and storing the value returned. Print that value, where you now print now().
Logged

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

I've tried that, no difference, still quite large discrepancies in the synced time (now()) with the original time send via serial (pctime). The older DateTime library doesn't have this behaviour in the same situation.

The example below is what happens when the time T1288477507 was send 4 times to sync via serial.
Quote
\0x07Waiting for sync message

TtimeStatus() = 2, pctime = 1288477507 and now() = 1288477512


TtimeStatus() = 2, pctime = 1288477507 and now() = 1288477513


TtimeStatus() = 2, pctime = 1288477507 and now() = 1288477516


TtimeStatus() = 2, pctime = 1288477507 and now() = 1288477515

Code:
/*
 * TimeSerial.pde
 * example code illustrating Time library set through serial port messages.
 *
 * Messages consist of the letter T followed by ten digit time (as seconds since Jan 1 1970)
 * you can send the text on the next line using Serial Monitor to set the clock to noon Jan 1 2010
 T1262347200  
 *
 * A Processing example sketch to automatically send the messages is inclided in the download
 */

#include <Time.h>  

#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message
unsigned long timeStorage = 0;

void setup()  {
  Serial.begin(9600);
  setSyncProvider( requestSync);  //set function to call when sync required
  Serial.println("Waiting for sync message");
}

void loop(){    
  if(Serial.available() )
  {
    processSyncMessage();
  }
  if(timeStatus()!= timeNotSet)  
  {
    digitalWrite(13,timeStatus() == timeSet); // on if synced, off if needs refresh  
    digitalClockDisplay();  
  }
  delay(1000);
}

void digitalClockDisplay(){
  /* // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  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);
}

void processSyncMessage() {
  // if time sync available from serial port, update time and return true
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of a header and ten ascii digits
    char c = Serial.read() ;
    Serial.print(c);  
    if( c == TIME_HEADER ) {      
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){  
        c = Serial.read();          
        if( c >= '0' && c <= '9'){  
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
        }
      }  
      setTime(pctime);   // Sync Arduino clock to the time received on the serial port
      timeStorage = now();
      Serial.print("timeStatus() = ");
      Serial.print(timeStatus());
      Serial.print(", pctime = ");
      Serial.print(pctime);
      Serial.print(" and now() = ");
      Serial.println(timeStorage);
    }  
  }
}

time_t requestSync()
{
  Serial.print(TIME_REQUEST,BYTE);  
  return 0; // the time will be sent later in response to serial mesg
}

« Last Edit: November 01, 2010, 04:07:45 am by Thomas_de_Graaff » Logged

Pages: 1 ... 6 7 [8] 9 10   Go Up
Jump to: