Measure micro-second intervals with Teensy 3.2

Status
Not open for further replies.
Hi All,

Is there a library, function or code sample to measure intervals in the single micro-second range? It might be my search terms, but I end up with code for producing fixed intervals. I managed to detect the interval boundaries with attachInterrupt(pin, function, CHANGE), but apparently the typical Arduino Timer registers aren't available.

Greetings & thank you,

Fred Jan Kraan
 
The ideal way to do this is with timer input capture. Teensy 3.2 has "FTM" timers which are similar to AVR's 16 bit Timer1, but with many more features. Input capture works basically the same way. You configure the timer to keep counting up and rolling over to zero. A change on a pin causes the timer value to be captured to a register. Unlike AVR were compare and capture are different registers, all 8 of the "channel" registers can be configured to either compare (create output waveforms) or capture (input waveforms). Details can be found in the FTM chapter of the reference manual.

The FreqMeasure, FreqMeasureMulti and PulsePosition libraries use the FTM timer channels in this mode. Those libs would be the place to look for working example code.
 
Thanks for the responses. I already tried the solution with micros(). The elapsedMicros solution didn't work well as it can't be combined with volatile. Without volatile the variable is updated only one in ten iterations.

Timer Input Capture sounds good as most is done in hardware. I didn't look in the code of the libraries yet but will do now.

Here the code and some results from the micros() attempt:
Code:
#define AMOUNT 40

volatile unsigned int times[AMOUNT];
volatile int count = 0;
volatile byte timesExceeded = 0;
volatile unsigned long now = 0L;
volatile unsigned long prev = 0L;

void fArgInterpreter() {
    Serial.println("F");
    driveOn();
    count = 0;
    timesExceeded = 0;

    while (digitalRead(INDEX) != 0) {
        digitalWrite(LED, (digitalRead(INDEX)));
    }
    digitalWrite(LED, (digitalRead(INDEX)));
    now = prev = micros();
    attachInterrupt(digitalPinToInterrupt(READDATA), pinFlip, CHANGE);

    while (!timesExceeded) {
    } // wait here
    
    for (int i = 0; i < AMOUNT; i++) {
        Serial.print(i, DEC);
        Serial.print(" : ");
        Serial.println(times[i]);
    }
    detachInterrupt(digitalPinToInterrupt(READDATA));
    driveOff();
}

void pinFlip() {
    now = micros();
    times[count] = (int)(now - prev);
    prev = now;
    count++;
    if (count > AMOUNT) {
      noInterrupts();
      timesExceeded = 1;
      count = 0;
    }
}

With result:
F
0 : 4
1 : 1
2 : 1
3 : 2
4 : 4
5 : 2
6 : 4
7 : 2
...
 
Status
Not open for further replies.
Back
Top