Hi

Rather than calculating the ppm offset, calculate the number of ticks until you 
drop (or add) one tick. Your output pps can only be offset from the input pps 
by an integer number of ticks anyway. The next decision would be - how big a 
tick can you get away with? For a wall clock, 100 ms is in the ball park of 
begin to big. 10 ms is small enough that it’s below what a wall clock needs. 

Bob

On Jan 19, 2014, at 7:38 PM, Jim Lux <jim...@earthlink.net> wrote:

> On 1/19/14 4:10 PM, Tom Van Baak wrote:
>>> So, do you run the whole thing off 12V (which is what I'm going to do)
>>> and a float charged battery OR do you do something clever like detect
>>> when power is failing and save it in NV storage, then when you come back
>>> up, you send a bunch of clock ticks real fast to catch up.
>> 
>> Use a high-res Arduino web cam facing the wall of clocks and write OHR 
>> (Optical clock-Hand Recognition) code. That way its a single robust solution 
>> for setting it the first time, restarting it on power failure, resyncing 
>> after replacing a failed clock, or self-correcting after any mechanical 
>> glitch. You can also use the same video feed to show off the project live on 
>> the JPL web site.
>> 
> 
> 
> No, a low res cam with a robotic arm that moves it in front of each clock in 
> turn..
> 
> That is what is called "scope creep"..
> 
> I'll be happy if I get ONE clock running reasonably..
> 
> I've got the Arduino code running that does the EOT, once a second (but using 
> delay(1000) not the ISR), calculates the rate estimate, and accepts a sync 
> command over the (emulated) serial port to set the time and date.
> 
> Curse the folks who develop "processing" because the current version supports 
> Mac OSX 10.7 and later, but not 10.6, which I am using, so I don't have the 
> nifty "click here to sync the Arduino" routine that's provided as an example 
> with the Arduino Time library.
> 
> 
> Next I have to integrate the code I've got now with the other sketch that 
> does the ISR off the hardware timer.
> 
> 
> ---
> 
> #include <Time.h>
> 
> 
> // Solar clock to drive mechanical mechanism
> // Jim Lux, 19 Jan 2014
> 
> #include <math.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
> // T1262347200  - sample sync message
> 
> const double refclk=31376.6;  //16 MHz/510?
> const int clkpin1=6;          // pins going to external clock
> const int clkpin2= 7;
> 
> int dd, hh;      //current day and hour
> boolean UpdateClockFlag; // tells loop() that an interrupt has occurred
> 
> void setup(){
> 
>  pinMode(clkpin1,INPUT);      // set pins as inputs High Z for now.
>  pinMode(clkpin2,INPUT);
> 
>  Serial.begin(9600);
>  delay(1000);
>  UpdateClockFlag = false;
> }
> 
> 
> void loop(){
>  int DOY;
>  double e1,e2;
>  double secsperday,ratedelta;
>  time_t t;
> 
>   t = now();      // get the time
>  if(Serial.available() )
>  {
>    processSyncMessage();
>  }
>  delay(1000);                // hack, til we get ISR timer running
>  UpdateClockFlag = true;    // hack
> 
>  if (UpdateClockFlag) {
>    if(timeStatus() == timeNotSet)
>      Serial.println("waiting for sync message");
>    else  {
> 
>      DOY = DayWeekNumber(year(),month(),day(),weekday());
>      hh = hour();
>      e1 = eot(DOY,hh);        // EOT in minutes
>      e2 = eot(DOY,hh+1);
>      secsperday = (e2-e1)*1440;
>      ratedelta = secsperday*1.E6/86400;     //ppm for now,
>                                           // but we'll change to divisor later
>      Serial.print(ratedelta); Serial.print(" ");
>      digitalClockDisplay();
>      // code in here to update interrupt divisor, etc.
>    };
>    UpdateClockFlag = false;
>  }
> }
> 
> 
> // equation of time code from Tom Van Baak
> //http://www.leapsecond.com/tools/eot1.c
> double eot(int day,int hour){
>    double Pi = 4 * atan(1);
> 
>        double y = (2 * Pi / 365.0) * (day - 1 + (hour - 12) / 24.0);
>        double eqtime = 229.18 *
>                ( 0.000075
>                + 0.001868 * cos(y)
>                - 0.032077 * sin(y)
>                - 0.014615 * cos(2*y)
>                - 0.040849 * sin(2*y)
>                );
>        return(eqtime);
> }
> void processSyncMessage() {
>  // if time sync available from serial port, update time and return true
>  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of 
> header & 10 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
>    }
>  }
> }
> 
> 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);
> }
> 
> int  DayWeekNumber(unsigned int y, unsigned int m, unsigned int d, unsigned 
> int w){
>  int days[]={0,31,59,90,120,151,181,212,243,273,304,334};    // Number of 
> days at the beginning of the month in a not leap year.
> //Start to calculate the number of day
> int DOY;
>  if (m==1 || m==2){
>    DOY = days[(m-1)]+d;                     //for any type of year, it 
> calculate the number of days for January or february
>  }                        // Now, try to calculate for the other months
>  else if ((y % 4 == 0 && y % 100 != 0) ||  y % 400 == 0){  //those are the 
> conditions to have a leap year
>    DOY = days[(m-1)]+d+1;     // if leap year, calculate in the same way but 
> increasing one day
>  }
>  else {                                //if not a leap year, calculate in the 
> normal way, such as January or February
>    DOY = days[(m-1)]+d;
>  }
>  return DOY;
> // Now start to calculate Week number
> //  if (w==0){
> //   WN = (DOY-7+10)/7;             //if it is sunday (time library returns 0)
> // }
> //  else{
> //    WN = (DOY-w+10)/7;        // for the other days of week
> //  }
> }
> 
> 
> _______________________________________________
> time-nuts mailing list -- time-nuts@febo.com
> To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
> and follow the instructions there.

_______________________________________________
time-nuts mailing list -- time-nuts@febo.com
To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
and follow the instructions there.

Reply via email to