Here is the latest copy - https://dl.dropboxusercontent.com/u/63497702/read_encoder_v32.7z

It is spread over multiple tabs, so I couldn't figure out how to paste them all into one code block.

The key variables are _tstart (time when we finished calibrating the encoder and are now measuring angles for real) and tcnv (the time the current angle was measured).

So, if we know when we started measuring the angle (_tstart) and we know the time the current angle was taken (tcnv), we just multiply by the sidereal tracking rate (_trackingRate), which is 15.04 arc-seconds per second and we know what the encoder angle ought to be.

And any deviations from that, is a mechanical error that we can correct.

Note that tcnv is set in read_encoder (when we get the current encoder reading) and _tstart is set by the set_origin() function. Both are set from millis().

The problem is because millis() can't be trusted, the theoretical encoder angle drifts monotonically in one direction (but not at a constant rate, because that I could fix).

void read_encoder(long &A, long &B, long &tcnv) {

int reading;

int i;

long t0, t1;

t0 = exttimer_millis();

// this should finish in 5ms or less @ 32ksps

for (i = 0; i < OVERSAMPLING; i++) {

reading = read_adc(1);

A += reading;

reading = read_adc(2);

B += reading;

}

A = A / OVERSAMPLING;

B = B / OVERSAMPLING;

t1 = exttimer_millis();

// tcnv should be in milliseconds

tcnv = (t0 + t1) / 2;

}

long calc_full_angle (long theta, long tcnv) {

// calculate the full encoder angle (in DECI-arcseconds!)

_current_encoder_angle = (long) (get_quadrature_count() * 648) + (theta % 648);

if (_cal) {

_current_encoder_angle -= _origin_encoder_angle;

// don't use seconds directly as angles here are in DECI-arcseconds

double tElapsed = ((double) (tcnv - _tstart)) / 100;

_theoretical_encoder_angle = (long) (_trackingRate * tElapsed) + 0.5;

}

else {

_theoretical_encoder_angle = _current_encoder_angle;

}

return ( _current_encoder_angle );

}