Time Program

use this one theres a problem for the hour part

int Seconds =0;
int Minutes =0;
int Hours   =0;
long previousMillis = 0; 
long interval = 1027;

void setup() 
{
  Serial.begin(9600);
}

void loop()
{
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) 
  {
    previousMillis = currentMillis;
    Seconds++;
    if (Seconds==60)
    {
      Seconds=0;
      Minutes++;
      if (Minutes ==60)
      {
        Minutes=0;
        Hours++;
        if (Hours==24)
        {
          Hours=0;
        }
      }  
    }
    Serial.print ("The time on Mars now is = ");
    Serial.print (Hours);
    Serial.print (":");
    Serial.print (Minutes);
    Serial.print (":");
    Serial.println (Seconds);
  }
}

I've been thinking about making a super simple Mars watch.

Accuracy?

Accuracy?

if(currentMillis - previousMillis > interval)
Unlikely.

ash901226:
use this one theres a problem for the hour part

int Seconds =0;

int Minutes =0;
int Hours   =0;
long previousMillis = 0;
long interval = 1027;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval)
  {
    previousMillis = currentMillis;
    Seconds++;
    if (Seconds==60)
    {
      Seconds=0;
      Minutes++;
      if (Minutes ==60)
      {
        Minutes=0;
        Hours++;
        if (Hours==24)
        {
          Hours=0;
        }
      } 
    }
    Serial.print ("The time on Mars now is = ");
    Serial.print (Hours);
    Serial.print (":");
    Serial.print (Minutes);
    Serial.print (":");
    Serial.println (Seconds);
  }
}

So far this is working perfectly :slight_smile: Thanks for the advice everyone I will be looking into all your suggestions.

Thanks @ash901226 for the code to get me started.

Thanks @LarryD for the links I WILL be reading up on everything :slight_smile:

You can do a lot better than that,

Earth 1.0274912510416665 second = Mars 1 second

with something like this:

#define EARTH_1s (F_CPU) //1 second on earth
#define MARS_1s   (EARTH_1s * 1.027491251041665) // marsian 1 second

//test for marsian time
//1: 1 second has elapsed since the last call
//0: otherwise
unsigned char mars_second(void) {
  static unsigned char start_time=millis();
  if (millis() - start_time >= MARS_1s) {
    start_time += MARS_1s; //increment start_time
    return 1; //indicating 1 marsian second has elapsed
  } else return 0; //not enough time has passed
}

In your user code, you can use time_tm (if your compiler supports it), or you can use your own:

typedef struct {
  unsigned char sec;
  unsigned char min;
  unsigned char hour;
  unsigned char day;
} time_tm;

time_tm marsian_time;

//update marsian time
unsigned char time_update(time_tm &time) {
  if (mars_second()==0) return 0; //no update
  //time to update
  time->sec+=1; //update second
  if (time->sec>=60) {  //second overflow
    time->sec-=60;
    time->min+=1;
    if (time->min>=60) { //min overflow
      time->min-=60;
      time->hour+=1;
    ...
  }
  return 1; //indicating that time has been updated
}

loop():
  if (time_update(&marsian_time)) {
    Serial.print("marsian time has been updated\r\n");
    //display time here from marsian_time.
  } else Serial.print("no update to marsian time\r\n");

Basic structure is there.

dhenry:
In your user code, you can use time_tm (if your compiler supports it), or you can use your own:

Awesome! Thanks for the additional code! I'm not sure what time_tm is in reference to but yeah the IDE doesn't like it (I'm using UnoR3) I get an error that just says 'time_tm' was not declared in this scope;

sketch_jan05a:-1: error: 'time_tm' was not declared in this scope
sketch_jan05a:-1: error: 'time' was not declared in this scope
sketch_jan05a:-1: error: redefinition of 'unsigned char time_update'
sketch_jan05a:-1: error: 'unsigned char time_update' previously defined here
sketch_jan05a:-1: error: 'time_tm' was not declared in this scope
sketch_jan05a:-1: error: 'time' was not declared in this scope
sketch_jan05a:5: error: ISO C++ forbids declaration of 'time_tm' with no type
sketch_jan05a:8: error: expected initializer before 'marsian_time'
sketch_jan05a:11: error: redefinition of 'unsigned char time_update'
sketch_jan05a:-1: error: 'unsigned char time_update' previously defined here
sketch_jan05a:11: error: 'time_tm' was not declared in this scope
sketch_jan05a:11: error: 'time' was not declared in this scope

No biggy though, I don't need anybody to dive into this error lol I can work on the two different codes these posters have been extremely awesome to provide for me. Thanks guys (and gals?) for pointing me in some good directions :slight_smile:

sketch_jan05a:-1: error: 'time_tm' was not declared in this scope

That's due to the stupid Arduino IDE.

I beefed up the code and moved from millis() to micros() to provide more precision and to reduce long-term errors.

#include "marsian.h"      //typedef for time_tm

#define TICK_PIN        8  //tick pin flips every 1 marsian second
#define EARTH_1s (1000000ul) //1 second on earth. We are using micros()
#define MARS_1s  (EARTH_1s * 1.027491251041665) // marsian 1 second

tm marsian_time;

//test for marsian time
//1: 1 second has elapsed since the last call
//0: otherwise
unsigned char mars_second(void) {
  static unsigned long start_time=micros();
  if (micros() - start_time >= MARS_1s) {
    start_time += MARS_1s; //increment start_time
    return 1; //indicating 1 marsian second has elapsed
  } else return 0; //not enough time has passed
}

//initialize the marsian time (to 0/0/0/0)
void time_init(tm * time, 
  unsigned char tm_yday,      //day of year
  unsigned char tm_hour,      //hour
  unsigned char tm_min,       //minute
  unsigned char tm_sec        //second
  ) {
  pinMode(TICK_PIN, OUTPUT);  //tick pin as output
  time->tm_yday=tm_yday;
  time->tm_hour=tm_hour;
  time->tm_min=tm_min;
  time->tm_sec=tm_sec;
}

//update marsian time
unsigned char time_update(tm * time) {
  if (mars_second()==0) return 0; //no update
  //time to update
  time->tm_sec+=1; //update second
  digitalWrite(TICK_PIN, !digitalRead(TICK_PIN));  //flip the tick pin
  if (time->tm_sec>=60) {  //second overflow
    time->tm_sec-=60;
    time->tm_min+=1;
    if (time->tm_min>=60) { //min overflow
      time->tm_min-=60;
      time->tm_hour+=1;
      if (time->tm_hour>=24) {  //hour overflow
        time->tm_hour-=24;
        time->tm_yday+=1;
      }
    }
  }
  return 1; //indicating that time has been updated
}

//print marsian time
void marsian_print(tm * time) {
  Serial.print("Marsian day is: ");  Serial.print(time->tm_yday); 
  Serial.print(", time is: "); Serial.print(time->tm_hour); Serial.print("'"); Serial.print(time->tm_min); Serial.print(":"); Serial.println(time->tm_sec);
}

void setup(void) {
  //pinMode(9, OUTPUT);
  Serial.begin(9600);
  time_init(&marsian_time, 10, 1, 59, 58);  //initialize to day 10, 1am, 59:58
}

void loop(void) {
  if (time_update(&marsian_time)) marsian_print(&marsian_time);
  //digitalWrite(9, !digitalRead(9));
}

marsian.h has the definitions of tm struct, which is now compatible to (a subset of) the unix version.

As is, the code prints out marsian time over the serial, and flips a pin every 1 marsian second (0.5hz).

dhenry:
marsian.h has the definitions of tm struct, which is now compatible to (a subset of) the unix version.

That makes sense, is there somewhere I can get the Marsian .h and .cpp files? is there a library that includes these? :slight_smile: again thanks for all the positive posts on this topic. I know there's a few condescending posts but I really appreciate those of you that are here for the community of Arduino users. I think supporting each other and keeping to the true spirit of DIY, and community is what will bring the technology of tomorrow to fruition and turn this capitalist world and individualist society into a world community in which we are more tolerant of one another and willing to lend a hand... Now that the hippy speech is over :stuck_out_tongue: Thanks for the help and suggestions all!

Sure.

marsian.h contains just the typedef statement for struct tm.

typedef struct {
  unsigned char tm_sec;
  unsigned char tm_min;
  unsigned char tm_hour;
  unsigned char tm_yday;
} tm;

You can further expand it with functional prototype so this module/library can be reused for other projects.

And the daily accuracy is?. I have the Time class running on a Mega (2 actually) and compared to GPS Time Both loose about 5 - 15 sec's/day depending on room temperature. I wouldn't count on an Arduino for accurate time over any non trivial period of time > 48 hrs.
As a point of interest it probably would be easier to slow down the main clock (the 16 MHz Clock) or just replace it with a slower but accurate clock source and just use the Time Library since the Mars/Earth seconds are so close. The Clock might well be close enough to allow (Nearly) accurate operation of the Arduino, I didn't bother to do the calculations... Good Luck with that Marsian Library...

Bob{Edit} RE: Time Accuracyhttp://arduino.cc/forum/index.php/topic,69316.0.html
I would read this first... Arduino's in general really do not have a clock (16 MHz Oscillator whether crystal or resonator) that has sufficient long term > 48 hours, for timekeeping accuracy. This is the reason why IC's like the Dallas DS1307 and Better DS3231 are manufactured. To offload timekeeping to a device meant for that purpose. I can make the same recommendation for a DS3231... Slow the 32KHz resonator by the Earth Mars time ratio and you will have a $6.00 (US) Mars Clock. It's really Very Simple.

Unless I misunderstood something, I would just take the elapsed time with millis(), multiply that by some factor, and convert that count into hh:mi:ss form. Take a modulo of the count with day length in milliseconds if not interested in passed days since last restart, or you could reset the local variable after each day. It would work for a month or so and then you would have to take the rollover into account to make it work longer. You could poll the current time as many times as you want or whenever needed and it would be accurate without a need for separate struct to hold counters separately for hh, mi and ss.

Whatever your calculations are is of no relevance, it is the accuracy of the Arduino clock (the resonator or crystal) that is the limiting factor and the reason I pointed you to the other discussion. Time is a frequent discussion here. I mentioned the other methods simply because the change in frequency of the primary clock (again resonator or..) is such a small amount that it might just be close enough to simply do a small 'correction' to either the code or to the time source which is still the crystal or resonator. In addition I mentioned that the methods have flaws that make them unusable for more than trivial observation, certainly not to do more than generate conversation or as a proof of concept.

Bob

Chaul:
Unless I misunderstood something, I would just take the elapsed time with millis(), multiply that by some factor, and convert that count into hh:mi:ss form. Take a modulo of the count with day length in milliseconds if not interested in passed days since last restart, or you could reset the local variable after each day. It would work for a month or so and then you would have to take the rollover into account to make it work longer. You could poll the current time as many times as you want or whenever needed and it would be accurate without a need for separate struct to hold counters separately for hh, mi and ss.

You got it Chaul :slight_smile: . This code, or at least the one I'm working on will reset every day and start fresh, no need to stay accurate for 68 years, It will be new every day.

for everyone
If anyone has looked into the two links I gave at the top you can clearly see that not even NASA and JPL have a "set" timezone. In fact the only time zones on Mars are relative to the rovers and their landers. Unless you count the Airy-0 crater (Airy Mean Time) and that hasn't been accepted as the official or accurate basis either ( research Mars Time ---- Timekeeping on Mars - Wikipedia ---)

The idea here, as is with the case even with NASA, JPL, etc, is to just get essentially a "counter" that starts at 00.00.00 and ends on 24.39.35. Resetting every day at 00.00.00. There is no Mean time to base the 24ish hour day anyway so you'd be just as accurate to start the clock as soon as the light of the sun hits your boots and as long as it hits 24.39.35 when the dark hits them, I've made my goal.

On a hugely positive note I am so glad to see a lot of response on this post I had tried repeatedly to get some energy going on this in the past and on other forums and, well, it was a flop. I do appreciate every ounce of information you guys ( and gals?) are leaving here and I am taking every point of view into consideration. I'm not one to just be whiny and argue that I don't like your ideas. You wouldn't take the time to post here if you didn't have a valid point and I respect that and give your word weight. So again Thanks to all who are participating here :slight_smile: I appreciate everyone's input.

I don't know how Mars time works, but I figured now that it would make sense that 1s is just as long on Mars as it is on Earth. It's just that Mars takes a little longer to revolve. So, if you start the clocks at the same time, lets say midnight on Earth. It would show the same time 23:59:59 at the end of the day. On earth, it would reset back 00:00:00 on the next second, but on Mars, it would continue to 24:00:00 and so on. When the Mars clock resets to zero, it would be 00:39:35 on Earth clock. On the next Mars midnight, it would be 01:30 or so on Earth. I'm confused again but never mind that..

Chaul:
I don't know how Mars time works, but I figured now that it would make sense that 1s is just as long on Mars as it is on Earth. It's just that Mars takes a little longer to revolve. So, if you start the clocks at the same time, lets say midnight on Earth. It would show the same time 23:59:59 at the end of the day. On earth, it would reset back 00:00:00 on the next second, but on Mars, it would continue to 24:00:00 and so on. When the Mars clock resets to zero, it would be 00:39:35 on Earth clock. On the next Mars midnight, it would be 01:30 or so on Earth. I'm confused again but never mind that..

The difference in time between seconds on Mars and Earth is (Earth 1.0274912510416665 second = Mars 1 second) :slight_smile:

The difference in time between seconds on Mars and Earth i

How can an SI constant not be constant (except in cases of extreme relativistic effects)?

daremick:
The difference in time between seconds on Mars and Earth is (Earth 1.0274912510416665 second = Mars 1 second) :slight_smile:

Are you talking about theory of relativity or something, since I'm still kinda lost on what that notion means. I guess I should walk away from this topic slowly before further embarassment...

AWOL:

The difference in time between seconds on Mars and Earth i

How can an SI constant not be constant (except in cases of extreme relativistic effects)?

???? What exactly are you asking? SI stands for the international system of units, and nowhere in this topic has it been implied that they aren't constant. In fact the only mention of SI at all is in your post, while simultaneously questioning, I guess, your own post? The reference to the difference in time on Mars and Earth has nothing to do with SI units. One Second will always be one second. The post you quoted (all though you did not quote it entirely) stated;

The difference in time between seconds on Mars and Earth is (Earth 1.0274912510416665 second = Mars 1 second)

Meaning that it takes 1.027 seconds (roughly) for a rotation on earth that would take "1 second" on mars. Mars has a different rotation and orbit than earth does, the same goes with every other planet in the solar system. In order to measure time in the first place early clocks (sundials) were derived that measured when the sun made a shadow on one mark on the dial and when it made a complete circle around to the mark again. This is called a "day", "solar day", or as we know it 24hours. However the earth does not make a complete revolution exactly every 24 hours it is closer to 23hours 56minutes and 4seconds give or take :stuck_out_tongue: so in order to measure a "day" on other planets we measure how long it takes that planet to complete one rotation. For example mercury's "day" lasts about 176 Earth days "solar day" and about 58-59 for a siderial day (one rotation). So as you can see our reference of time, the lovely 24hours is not applicable everywhere in the universe, it's just a unit of measure we derived and it splits the day up nicely. Mars happens to have an extremely similar rotational period however it is slightly over by 39minutes and 35seconds.

So to surmise, no one is contesting SI Units, merely explaining that when you take the 24:39:35 mars day and divvy it up into an earth day you go over a second by .027 seconds (roughly) more. over time this fraction of a number adds up and over the course of days, weeks, months, years, you are taking a shower and getting your pajamas on to go to bed on earth whereas on mars you are in rush hour traffic still trying to get home for the wife's meatloaf dinner. I hope that helped to clear some things up for anyone reading this topic. And I hope it helps to clarify why I hope to complete this small project. Thanks for all the feedback, and positive support I see on here. :slight_smile: