Hey guys,
I've just forget to post my code:
to get a time reference, I first use the bridge to get the time from Linux side as a string and get the different part isolated in a tm structure:
Serial.print(F("Setting up Time references : "));
Process Starttime;
Starttime.begin("/bin/date");
Starttime.run();
String string = Starttime.readString();
tm startTime = {string.substring(17, 19).toInt(), // Seconds asfter th minute
string.substring(14, 16).toInt(), // Minutes after the hour
string.substring(11, 13).toInt(), // Hours since Midnight
string.substring(8, 10).toInt(), // Day of the month
0, // Months since January
0, // Years since 1900
0, // Days since Sunday
0, // days since January 1
-1}; // Daylight Saving Tim flag ( (> 0 : true) (0 : false) ( < 0 : undefined)
startTime.tm_year = (string.substring(24, 28).toInt() - 1900);// I don't know why it doesn't work inside the array declaration
As you can see, I can't put all the raw values in the structure because I need to treat the string:
get an int from the day of the week :
String FL = string.substring(0, 1);
if(FL == "M")
startTime.tm_wday = 1;
else if(FL == "T")
startTime.tm_wday = (string.substring(1, 2) == "u") ? 2 : 4;
else if(FL == "M")
startTime.tm_wday = 3;
else if(FL == "F")
startTime.tm_wday = 5;
else if(string.substring(0, 2) == "u")
startTime.tm_wday = 0;
else
startTime.tm_wday = 6;
get an int from the month:
FL = string.substring(4, 5);
if (FL == "J")
startTime.tm_mon = ((string.substring(4, 7) == "Jan") ? 0 : ((string.substring(4, 7) == "Jun") ? 5 : 6));
else if (FL == "F")
startTime.tm_mon = 1;
else if (FL == "M")
startTime.tm_mon = ((string.substring(4, 7) == "Mar") ? 2 : 4);
else if (FL == "A")
startTime.tm_mon = ((string.substring(4, 7) == "Apr") ? 3 : 7);
else if (FL == "S")
startTime.tm_mon = 8;
else if (FL == "O")
startTime.tm_mon = 9;
else if (FL == "N")
startTime.tm_mon = 10;
else
startTime.tm_mon = 11;
to determine the day of the year, I use the month to figure out how many day has passed before the month has started. I've used a complex loop instead of a switch because I'm a bit lazy and because I think it uses less constants this way.
maybe you'll be afraid by the encapsulated ternary operators… just sorry about that.
it just means "if it's february put 28, else put one time in two 30 or 31 and add one if it's a leap year".
then I just need to add the day of the month to the amount:
bool bisxl = ((startTime.tm_year + 1900) % 4) ? false : true, b = true;
uint8_t J = 31, F = 28 + bisxl, A = 30;
int nbDay = 0;
// count the number of days that passed before the current month.
for(int i = 0; i < startTime.tm_mon ; i++, nbDay += (((i == 1) ? 28 : 30 + ((b) ? 1 : 0)) + ((bisxl) ? 1 : 0)), b = !b){
// i : month tested
// nbDay : total of days that passed before the month i
// b : is the month a 31 or 30 month
if(i == 7)
b = !b;
}
startTime.tm_yday = nbDay + startTime.tm_mday;
Last thing I need to do it converting this structure into a time_t type variable to use it in a easy and fast way.:
yunTime = mktime(&startTime);
if((yunTime == -1)){
Serial.println(F("Error while converting time into UNIX Timestamp"));
while(1);
}
else
PrintDateTime(yunTime);
}
then, to update Time each loop, I've just declared a variable to get the number of millisecond elapsed since the begining to the last update of the program with millis() and compare it to the current amout of millisecond elapsed. When more than 999 millisecond has passed, I convert it into second and add it to the TimeStamp. It sound complex but here is my (almost) complete code :
main.ino:
time_t yunTime, timeTrigger = 0;
unsigned long lastmillis = millis(), milliscount = 0;
setup(){
lastmillis = millis();
PdateSetup();
}
void loop(){
PdateUpdate();
}
time.ino:
void PdateSetup() {
Process Starttime;
Starttime.begin("/bin/date");
Starttime.run();
String string = Starttime.readString();
tm startTime = {string.substring(17, 19).toInt(), // Seconds asfter th minute
string.substring(14, 16).toInt(), // Minutes after the hour
string.substring(11, 13).toInt(), // Hours since Midnight
string.substring(8, 10).toInt(), // Day of the month
0, // Months since January
0, // Years since 1900
0, // Days since Sunday
0, // days since January 1
-1}; // Daylight Saving Tim flag ( (> 0 : true) (0 : false) ( < 0 : undefined)
startTime.tm_year = (string.substring(24, 28).toInt() - 1900);
//turn day of week into an int
String FL = string.substring(0, 1);
if(FL == F("M"))
startTime.tm_wday = 1;
else if(FL == F("T"))
startTime.tm_wday = (string.substring(1, 2) == "u") ? 2 : 4;
else if(FL == F("M"))
startTime.tm_wday = 3;
else if(FL == F("F"))
startTime.tm_wday = 5;
else if(string.substring(0, 2) == F("u"))
startTime.tm_wday = 0;
else
startTime.tm_wday = 6;
// turn month into an int
FL = string.substring(4, 5);
if (FL == F("J"))
startTime.tm_mon = ((string.substring(4, 7) == F("Jan")) ? 0 : ((string.substring(4, 7) == "Jun") ? 5 : 6));
else if (FL == F("F"))
startTime.tm_mon = 1;
else if (FL == F("M"))
startTime.tm_mon = ((string.substring(4, 7) == F("Mar")) ? 2 : 4);
else if (FL == F("A"))
startTime.tm_mon = ((string.substring(4, 7) == F("Apr")) ? 3 : 7);
else if (FL == F("S"))
startTime.tm_mon = 8;
else if (FL == F("O"))
startTime.tm_mon = 9;
else if (FL == F("N"))
startTime.tm_mon = 10;
else
startTime.tm_mon = 11;
bool bisxl = ((startTime.tm_year + 1900) % 4) ? false : true, b = true;
uint8_t J = 31, F = 28 + bisxl, A = 30;
int nbDay = 0;
// count the number of days that passed before the current month.
for(int i = 0; i < startTime.tm_mon ; i++, nbDay += (((i == 1) ? 28 : 30 + ((b) ? 1 : 0)) + ((bisxl) ? 1 : 0)), b = !b){
// i : month tested
// nbDay : total of days that passed before the month i
// b : is the month a 31 or 30 month
if(i == 7)
b = !b;
}
startTime.tm_yday = nbDay + startTime.tm_mday;
yunTime = mktime(&startTime);
if((yunTime == -1)){
while(1)
errorBlink();
}
}
void PdateUpdate(){
milliscount += (millis() - lastmillis);
lastmillis = millis();
if(milliscount / 1000){
yunTime += milliscount / 1000;
milliscount -= (milliscount / 1000) * 1000;
}
}
To set an Alarm, I recommend to use the timer interruptions of your chip but if (like me) you don't know how to do it, here is my function:
bool delayYunTime(time_t delay_, time_t now_, time_t *dst) {
if (now_ >= *dst) {
*dst = delay_ + now_;
return true;
}
else {
return false;
}
}