Finding a way to verify precise timing?

I've made a stepper motor gear drive for my telescope designed to track the star's movement across the sky for astrophotography.

I nailed a 30 second exposure with no star trails, but other shots have various levels of trailing, so I know something isn't consistent. Certainly this might be a mechanical issue, my telescope mount is cheap and I'm pretty sure it needs various levels of torque to consistently drive it forward evenly, but I also want to rule out a programming issue.

My function raStandard() is the primary method the motor is stepped at a specific period:

#include <Encoder.h>

Encoder rapidAdv(11, 10);              //defines rot encoder input pins
int rotaryButt = 12;                        //encoders button pin
int advButt = 9;                             //pin for button to rapidly advance motor a bit
int stepSize = 4;                            //enable 1/2 step microstepping. typically set to HIGH
int dir = 3;                                    //sets direction of motor
int stp = 2;                                   //steps motor
unsigned long lastAdvance = 0;      //time-keeping variable. used to store the last time the motor stepped.
long orbitSpeed = 300;                 //Sets default standard rotational pace. rotary encoder changes this as needed     
long lastRotaryPos = -999;
long currentPos = -999;
int rotButtState = LOW;                 //hold encoder button's state
long adjRotaryDiff = 0;                  //holds the difference in rotary encoder value
int advButtState = LOW;                //hold state of quick advance button


void setup()         
{                
  pinMode(stp, OUTPUT);
  pinMode(advButt, INPUT);                      
  pinMode(dir, OUTPUT);
  pinMode(stepSize, OUTPUT);
  pinMode(rotaryButt, INPUT_PULLUP);      //inverts logic, pin goes LOW when button pressed
  lastRotaryPos = rapidAdv.read();
  digitalWrite(stepSize, HIGH);          //sets half-steps as deafualt
  Serial.begin(9600);                     
}


void loop()
{ 
  raStandard();               
  
  Serial.println(orbitSpeed);       //used this to monitor the actual period needed to accurately track stars.
    
  currentPos = rapidAdv.read();                //next 3 lines check status of inputs
  rotButtState = digitalRead(rotaryButt);
  advButtState = digitalRead(advButt);

  adjRotaryDiff = (lastRotaryPos - currentPos);      //determines how much encoder has moved

  if (advButtState == HIGH)            //advances motor quickly for a bit when pressed
    {
      digitalWrite(stepSize, LOW);      //sets stepstick board to full step
      for (int t=0; t <= 20; t++){
          Prograde();
          delay(35);
        }
      digitalWrite(stepSize, HIGH);     //once completed, resumes half steps for normal operation.
    }

  if ((rotButtState == LOW) and (adjRotaryDiff <= -1))
    {
      orbitSpeed++;
      lastRotaryPos = rapidAdv.read();
    }

  if ((rotButtState == LOW) and (adjRotaryDiff >= +1)) 
    {
      orbitSpeed--;
      lastRotaryPos = rapidAdv.read();
    }

  if ((adjRotaryDiff >= 4) and rotButtState == HIGH)
    {

      orbitSpeed--;
      lastRotaryPos = rapidAdv.read();  
    }
      
  if ((adjRotaryDiff <= -4) and rotButtState == HIGH) 
    {
      orbitSpeed--;
      lastRotaryPos = rapidAdv.read();
    }

}


void raStandard()                     //default mode, advances the motor at the period designated by 'orbitSpeed'
{
  unsigned long currentTime = millis();       
  if ((currentTime - lastAdvance) >= orbitSpeed)
    {
      Prograde();
      lastAdvance = millis();
    }
}


void Prograde()                        //rotates motor one step in direction of earth's orbit
{
  digitalWrite(dir, HIGH);
  digitalWrite(stp, HIGH);
  delay(10);
  digitalWrite(stp, LOW);
}

nothing seems like it would delay the normal operation, so it should advance the motor every 300 microsecond (or whatever orbitSpeed has been set to) if no other inputs are being pressed. I just want a way to check when exactly the motor does advance, and be sure it will not being changed by my viewing it.

If I have a serial output 'lastAdvance,' is there any reason it would be inaccurate? how much CPU time does a standard serial print consume?

ztoundas:
it should advance the motor every 300 microsecond

Did you mean millisecond?

Oops, yeah, millisecond. I don't need accuracy beyond that.

There's no such thing as a "standard serial print" - the question is mostly meaningless.

You seem to have a mix of delay and millis timing.

Try just using one (the latter) and just watch out for slippage.

To answer one of your questions, you can monitor the pulses by applying them to a LED.

If you think there is some time slippage you can modify the basic timer to a constant increment

void raStandard()                     //default mode, advances the motor at the period designated by 'orbitSpeed'
{
  unsigned long currentTime = millis(); 
  static unsigned long lastAdvance = currentTime;      
  if ((currentTime - lastAdvance) >= orbitSpeed)
    {
      Prograde();
      //lastAdvance = millis();
        lastAdvance += orbitSpeed;
    }
}

Well, I can hear the pulses each time the motor kicks on, so I know they are happening about when they should. I want to monitor them more precisely.

Also I'll remove the delay in the Prograde() function as it might be causing a timing problem, but the delay in fast advance feature doesn't matter as much because I only use that for rough positioning of the telescope, it won't be used during the fine tracking of the stars.

cattledog - Not familiar with that concept yet (constant increment), so I'll look into it. My rudimentary knowledge tells me by looking at it that it might be what I was trying to do in the first place. Thanks!

ztoundas:
Well, I can hear the pulses each time the motor kicks on, so I know they are happening about when they should. I want to monitor them more precisely.

It's just a little strange to have code to monitor what your code is doing... first of all the monitoring code might also have bugs (since at the outset you had doubts about the integrity of your code). Secondly, if there is a problem in your code the most logical approach is to find the problem and fix it because you have access to the entire source.

There is no reason to believe that something like the code in reply #5 would produce anything but an accurate pulse train. Thousands of sketches depend on it.

cattledog - Not familiar with that concept yet (constant increment), so I'll look into it. My rudimentary knowledge tells me by looking at it that it might be what I was trying to do in the first place. Thanks!

This issue is extensively discussed at the beginning of the thread "Demonstration code for several things at the same time"

http://forum.arduino.cc/index.php?topic=223286.0

ztoundas:
I nailed a 30 second exposure with no star trails, but other shots have various levels of trailing,

Arduinos do not run at precisely 16Mhz. Over a long period of time the Arduino "clock" will vary from a proper clock. If that seems to be the cause of the problem then you can use a Real Time Clock (RTC) module to provide a more precise reference.

And I think someone has already alluded to the need to the need (as illustrated in Several Things at a Time ) to count Arduino time from the initial value of millis() by updating periods with

latestTimeMillis += intervalMillis;

rather than

latesTimeMillis = millis();

The latter will almost certainly accumulate small errors (in addition to any error that may be due to any inaccuracy in the 16MHz clock)

...R