Here's a little program to automatically adjust the IntervalTimer period.
Code:
IntervalTimer mytimer;
volatile uint32_t cyclesRisingEdge;
volatile uint32_t cyclesPulse;
volatile bool gotRisingEdge=false;
volatile bool gotPulse=false;
volatile bool firstAdjust=true;
float period = 1000000.0;
void setup() {
pinMode(2, INPUT);
pinMode(4, OUTPUT);
while (digitalReadFast(2) == HIGH);
while (digitalReadFast(2) == LOW);
mytimer.begin(pulse, period);
mytimer.priority(192);
attachInterrupt(2, gps, RISING);
ARM_DEMCR |= ARM_DEMCR_TRCENA;
ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
}
void gps() {
cyclesRisingEdge = ARM_DWT_CYCCNT;
gotRisingEdge = true;
}
void pulse() {
cyclesPulse = ARM_DWT_CYCCNT;
gotPulse = true;
digitalWriteFast(4, HIGH);
delayMicroseconds(1);
digitalWriteFast(4, LOW);
}
void loop() {
if (gotRisingEdge && gotPulse) {
float err = (int32_t)(cyclesPulse - cyclesRisingEdge) * (1000000.0f / (float)F_CPU);
if (firstAdjust) period = period - err * 0.75;
period = period - err * 0.02; // integral control
mytimer.update(period - err * 0.25); // proportional control
gotRisingEdge = false;
gotPulse = false;
firstAdjust = false;
Serial.print("error = ");
Serial.print(err);
Serial.println(" us");
}
}