Time Program

I'm glad I found this site. I've been thinking about making a super simple Mars watch. I looked around to see if anybody else had made one and it turns out a jeweler made a mechanical one for JPL ( http://www.jckonline.com/article/287435-U_S_Jeweler_Creates_Mars_Time_Watch_for_JPL.php )........................ and an engineering student made a digital one ( http://www.popsci.com/diy/article/2012-09/make-your-own-mars-watch-keep-time-mars-rovers )..............................

I had hoped to stay under the pricing and complicated programming/workmanship they had to input ($50-$400 price points). The difference in time between seconds on Mars and Earth is (Earth 1.0274912510416665 second = Mars 1 second) so my idea was to simplify the code and make the watches extremely low cost and easy to reproduce. I thought since you can write a delay based on milliseconds you might be able to write a digit 000,000(plus one) at a delay rate of 1027-1028 until you reach 243,935 at which point the program would return to start at 000,000. and start again adding 1 digit every 1027 milliseconds.

This is the first piece of code I'm messing with (terribly inefficient)

void setup()                    
{
  Serial.begin(9600);           
  
  Serial.println(.01);   
  
  delay(1027);
  
  Serial.println(.02);
  
  delay(1027);
  
  Serial.println(.03);
  
  delay(1027);
  
  Serial.println(.04);
}

void loop()                       
{
                                 
}

If anyone has any suggestions or nows how I can make the "serial.println" just add one digit every 1.027 that'd be awesome. I basically just want to make the timer go from 00.00.00 to 24.39.35 without having 50,000 KB of code. I know there's got to be a way to have it "plus one" every 1027 milliseconds.

I'm no programmer so there may be a lot I'm missing but this seemed to me to be the simplest cheapest way to make a reasonably accurate watch for everyday use. I would compare these to a cheap watch you might get at Walmart for under $10, obviously it's not going to be a Roh Lex (banned word apparently) and at times you'll have to reset it if it gets off a few minutes, but I think it's a promising start. I welcome (and ask for) ANY response positive or negative on this. I'm open to suggestions and criticism. Thanks!

urm i think mostly you need a blink without delay. thats simple and then you need something to count urm lets say its Seconds, minutes and hours. you say that each time the blink w/o delay true then you increment second. if the second reach 60 increment minutes and reset second if the minutes reach 60 increment hours and reset minutes if the hour reach 24 reset hour. simple as that i think

I think you should start at the beginning for background. Read these 40 pages http://playground.arduino.cc/uploads/Main/arduino_notebook_v1-1.pdf

Also look at the following: http://playground.arduino.cc//Main/ManualsAndCurriculum http://arduino.cc/en/Reference/HomePage

Note: in loop(), when execution comes to the last instruction it goes back to the first instruction in loop() and on and on. Set up counters increment them, use your delay. Check the counters for a value and reset them when they reach the count you want.

Heres The code i made for you. it been tested and it works not the less. However it just to guide you in the rite direction.

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);
  }
}

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 :) 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 :)

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 :)

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? :) 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 :P 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 :) . 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 ---- http://en.wikipedia.org/wiki/Timekeeping_on_Mars ---)

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 :) 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) :)