Try calling now() immediately after setTime(), and storing the value returned. Print that value, where you now print now().
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.
\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
/*
* 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
}
There may be a weakness in setTime(). Try to call now() right before you call setTime(). If that solves the problem, let us know it, then we can have it fixed.
Korman
Try to call now() right before you call setTime().
If the value returned by now() is supposed to be set by the call to setTime(), how in the heck is calling now() first going to accomplish anything?
No, I mean something like:
[glow]now();[/glow]
setTime(pctime);
timeStorage = now();
And no, that's not voodoo, it might prevent a potential problem from happening. If everything works fine with the additional now(), we have discovered a bug which will be easy to solve. If it doesn't the thing I imagined to be a problem isn't one and we're barking up the wrong tree.
Korman
That indeed solves the problem. So if I understand it right, to get a precise sync, for the moment, you need to call now() just before setTime() ?
\0x07Waiting for sync message
\0x07
now() time before syncing = 3
pctime, time that was synced with
= 1288477507
timeStatus() after syncing = 2
now() time after syncing = 1288477507now() time before syncing = 1288477549
pctime, time that was synce
d with = 1288477507
timeStatus() after syncing = 2
now() time after syncing = 1288477507now() time before syncing = 1288477534
pctime, time that was sy
nced with = 1288477507
timeStatus() after syncing = 2
now() time after syncing = 1288477507
/*
* 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() ;
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
}
}
timeStorage = now();
Serial.println();
Serial.print("now() time before syncing = ");
Serial.println(timeStorage);
setTime(pctime); // Sync Arduino clock to the time received on the serial port
timeStorage = now();
Serial.print("pctime, time that was synced with = ");
Serial.println(pctime);
Serial.print("timeStatus() after syncing = ");
Serial.println(timeStatus());
Serial.print("now() time after syncing = ");
Serial.println(timeStorage);
}
}
}
time_t requestSync()
{
Serial.print(TIME_REQUEST,BYTE);
return 0; // the time will be sent later in response to serial mesg
}
That indeed solves the problem.
Ok, the bug in the setTime function is that it doesn't reset prevMillis to the value of millis(). So the next time you call now(), the difference between the last call to now() and the current value of millis() will be added to the time you just adjusted with setTime(). If now is called often enough, that isn't a visible problem. However if you call now() only every 5 seconds and use setTime() directly, you get that weird offset you saw.
Next step: Finding out who maintains the Time library and where to post a patch...
Korman
Thanks Korman.
I have added the fix and uploaded it to the Playground.
Give it a go and let me know how you get on.
Wow, that is a quick bugfix!
It's working just fine now.
Mem,
it looks good now. Thank you for the quick response. For completeness here's my test program which fails with the old library and works with the new one:
#include <Time.h>
void setup () {
Serial.begin (9600);
delay (10000);
Serial.println (now());
delay (10000);
setTime (123456789);
Serial.println (now());
}
void loop(){
}
Results with old Time library - highlight is wrong:
10
123456799
Results with new Time library - highlight is ok now:
10
123456789
Korman
loomi, sorry I missed your post about parsing dates. Date strings are supported in the current library so your sketch could use something like this:
// function to return the numeric month from a given 3 character month string
// Jan is returned as 1, December as 12
int getMonth(char *mnthStr)
{
for( int mo = 1; mo <=12; mo++)
{
if(strcmp( mnthStr, monthShortStr(mo)) == 0)
return mo;
}
return 0;
}
Have a look at Datestrings.cpp in the Time library directory if you want to look at the monthShortStr function
Is there any particular interest in having the DS3231 specific features (such as forcing a temperature conversion, reading the temperature value, toggling the 32KHz pin, etc) added? I've already got the first two there finished, although I can't actually test them.
Hi ccfreak2k, I would be interested to hear the responses to your question. Why not start a new thread for discussion of your library when you have had a chance to get it tested and place a link here so people can find it..
I would be happy to include a DS3231 library with the Time library distribution if this is something people want.
I am trying to use this library, and can't see to get past what appears to be a simple error, using Ard0021 on OS X.
I have unpacked the zip, and so now have
Sketches
- Libraries
- Time (dl from playground)
- TinyGPS (was there already)
- NewSoftSerial (was there already)
Sketches in the Sketches folder seem to have no problem using header files from the TinyGPS or NewSoftSerial folders, but whenever I try to include Time.h, I get this:
TimeGPS.cpp:7:18: error: Time.h: No such file or directory
The include line looks like this:
#include <Time.h>
I've reviewed the Arduino instructions several times, and can't see what I'm doing wrong. Time.H is shown in the list of available libraries when I select Sketch - Import Library (along with NewSoftSerial and TinyGPS).
I copied the TimeGPS example to the Sketches folder, and it can find the TinyGPS and NewSoftSerial.h no problem (they turn orange in the editor), but can't find the Time.h, even though it's in the same place. Time.h doesn't turn black.
I must be doing something wrong - can anyone point me in the right direction, please?
SeanC, did you try to open the TimeGPS example sketch by navigating: File->Examples->Time->Examples->TimeGps
If you can open and correctly compile that sketch, click File->Save As to your sketchbook directory and after the IDE copies the sketch, see it that also compiles okay.
Thanks for your reply! I unpacked the archive again, opened the
TimeGPS example sketch with : File->Examples->Time->Examples->TimeGps
and it still fails the same way. Interestingly, I can see it's going to fail, because the Time.h in the sample code is all black in the editor, whereas the two found libraries, TinyGPS and NewSoftSerial are orange.
#include <Time.h>
#include <TinyGPS.h>
#include <NewSoftSerial.h>
I closed and re-opened the arduino ide, and still can see Time in the Sketch-Import Libraries menu.
Any help would be appreciated!
I think the coloring is a red herring. Arduino libraries use a syntax coloring file to enble the IDE to highlight keywords. Tinygps and NewSoftSerial are Class names that are used within the sketch so they are in the Syntax coloring file. The Time class name is not explicitly used in a sketch so its in the syntax coloring file and is not highlighted.
Something else is causing your problem. Are you quite sure that the Time library folder location is correct and that all the files are there?
I don't use OS X, perhap someone that does can check if they have any problems compiling the Time library example sketches.
Something else is causing your problem. Are you quite sure that the Time library folder location is correct and that all the files are there?
I don't use OS X, perhap someone that does can check if they have any problems compiling the Time library example sketches.
I also have the same problem as SeanC.
I'm running Mac OS X 10.6.5 and Arduino 0021 on my machine.
I downloaded Time library and unzipped it under my Arduino/libraries directory.
Time library becomes available as example and also importing but I cannot compile the examples.
I get the following errors from TimeSerial example.
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
Any suggestions on how to get Time library to work?
Actually, I just figured out what I was doing wrong.
When I installed Time library at my libraries directory, I did it like this:
I unzipped Time.zip file at my libraries directory, so it created a new directory, 'Time'.
So the result was like this:
~/Documents/Arduino/libraries/Time/DS1307RTC
~/Documents/Arduino/libraries/Time/Time
~/Documents/Arduino/libraries/Time/TimeAlarms
Instead, what I should have done was to move the contents of top-level 'Time' directory to my libraries directory, like this:
~/Documents/Arduino/libraries//DS1307RTC
~/Documents/Arduino/libraries/Time/
~/Documents/Arduino/libraries/TimeAlarms
After making this adjustment, I am able to compile the examples that came with Time library. Hope other people may find it useful (or has everyone already figured this out?).
Good to hear you have it working.
I hope that information helps others with a similar problem