Re: Trying to modify for sidereal rate

by Stephanie on Mon Jan 24, 2011 8:09 pm

Couldn't you use a 16 bit int instead of the 8 bit in the example? That would give +/- 32767 I think?

Disclaimer: I'm a noob to this stuff.
User avatar
Stephanie
 
Posts: 286
Joined: Sat Dec 11, 2010 12:17 am
Location: Canada

Re: Trying to modify for sidereal rate

by stinkbutt on Tue Jan 25, 2011 12:57 am

rschmit wrote:Yep, I looked at that post previous to writing, and I thought this would be a show stopper:
-128 <= cal_factor <= 127

If that's the limit to the range of values for cal_factor, then a full range value only buys me 0.366 seconds per day. At least that's how I was reading it.


Not a problem. You need to pick up, what, four minutes a day, maximum? OK, let's set our range for 4-8 minutes a day and see what we can do.

The current code adds 0.366 seconds per day max. We need 240-480 seconds per day max. Let's call it 366 seconds per day. That's 666 to 1,333 times more often. That's our target, 700-1300 to make the maths simpler.

Currently it shortens the interrupt in this block of code:

Code: Select all
  // an hour...
  if (time_m >= 60) {
   cal = eeprom_read_byte((int8_t *)EE_CAL);
   if (cal < 0)
        {
      // clock slow - shorten first second of hour
      TCNT2 += -cal + 1;
   }
        else if (cal > 0)
        {
      // clock fast - lengthen first second of hour
      uint8_t tmp = TCNT2;
      while ((TCNT2 - tmp) < cal);
      TCNT2 = tmp;
   }
    time_m = 0;
    time_h++;
    // lets write the time to the EEPROM
    eeprom_write_byte((uint8_t *)EE_HOUR, time_h);
    eeprom_write_byte((uint8_t *)EE_MIN, time_m);
  }


This if/then block triggers when time_m = 60, that is to say, once per hour. And it increments TCNT by cal when cal < 0, which is what we want, to shorten the hour.

If we fire it off every minute, we're going off 60x as often, still not enough. If we fire it off every second we're going off 3600x as often. Closer, but a bit too far. But that's getting us close. Let's remove the cal code from the hour and put it into the second:

Code: Select all
  CLKPR = _BV(CLKPCE);  //MEME
  CLKPR = 0;

  time_s++;             // one second has gone by

  // HERE WE ADD THE SHITCANNED CODE FROM BELOW
  cal = eeprom_read_byte((int8_t *)EE_CAL);
  if (cal < 0)
  {
    // clock slow - shorten first second of hour
    TCNT2 += -cal + 1;
  }
  else if (cal > 0)
  {
    // clock fast - lengthen first second of hour
    uint8_t tmp = TCNT2;
    while ((TCNT2 - tmp) < cal);
    TCNT2 = tmp;
  }
  // ADDED

  centiseconds = 0;
  // a minute!
  if (time_s >= 60) {
    time_s = 0;
    time_m++;
  }

  // an hour...
  if (time_m >= 60) {

/*  SHITCANNING THIS CODE BLOCK BY COMMENTING IT OUT
   cal = eeprom_read_byte((int8_t *)EE_CAL);
   if (cal < 0) {
      // clock slow - shorten first second of hour
      TCNT2 += -cal + 1;
   } else if (cal > 0) {
      // clock fast - lengthen first second of hour
      uint8_t tmp = TCNT2;
      while ((TCNT2 - tmp) < cal);
      TCNT2 = tmp;
   }
SHITCANNED! */

    time_m = 0;
    time_h++;
    // lets write the time to the EEPROM
    eeprom_write_byte((uint8_t *)EE_HOUR, time_h);
    eeprom_write_byte((uint8_t *)EE_MIN, time_m);
  }


Only problem is this is shortening the hour by too much. Sure, you could adjust cal down, but your increments would be a bit ham-handed. So instead let's only fire off every FOURTH second. So now instead of firing off 3600x more often, it's 900x more often. Right smack dab in the middle of our target. We do that by wrapping the cal code in a block that, instead of firing off once a second, only fires off every four seconds, by checking if seconds % 4 = 0, (if it's a multiple of 4,) like this:

Code: Select all
  CLKPR = _BV(CLKPCE);  //MEME
  CLKPR = 0;

  time_s++;             // one second has gone by

  // BEGIN 0.25 HZ BLOCK
  if( time_s % 4 == 0 )
    {
    // HERE WE ADD THE SHITCANNED CODE FROM BELOW
    cal = eeprom_read_byte((int8_t *)EE_CAL);
    if (cal < 0)
    {
      // clock slow - shorten first second of hour
      TCNT2 += -cal + 1;
    }
    else if (cal > 0)
    {
      // clock fast - lengthen first second of hour
      uint8_t tmp = TCNT2;
      while ((TCNT2 - tmp) < cal);
      TCNT2 = tmp;
    }
    // ADDED
  }
  // END 0.25 HZ BLOCK

  centiseconds = 0;
  // a minute!
  if (time_s >= 60) {
    time_s = 0;
    time_m++;
  }


Now you should be able to adjust the rate at which you gain time, (with a negative cal value,) to sidereal time. A cal value of -92 with that code ought to get you to run fast by 3 minutes and 56 seconds per day.
Red M&M, Blue M&M: They all wind up the same color
stinkbutt
 
Posts: 590
Joined: Wed Feb 17, 2010 1:40 am

Re: Trying to modify for sidereal rate

by stinkbutt on Tue Jan 25, 2011 1:19 am

Stephanie wrote:Couldn't you use a 16 bit int instead of the 8 bit in the example? That would give +/- 32767 I think?

Disclaimer: I'm a noob to this stuff.


The calibration factor gets set in a menu displayed on the clock. Could you, theoretically, adjust the code so that you instead increment between -16384 and +16383? Sure. Would it be a much much much bigger pain in the ass, reworking the VFD display to handle 5-digit numbers and flipping over at a different point instead of just doing what I just told him to do? You better believe it, Baby.
Red M&M, Blue M&M: They all wind up the same color
stinkbutt
 
Posts: 590
Joined: Wed Feb 17, 2010 1:40 am

Re: Trying to modify for sidereal rate

by rschmit on Tue Jan 25, 2011 8:42 am

I see what you did there... Brilliant! I'll get right to work on that. Thanks, SB!
rschmit
 
Posts: 8
Joined: Mon Jan 03, 2011 11:48 am