Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 9 of 9

Thread: T4.0 IntervalTimer question

  1. #1

    T4.0 IntervalTimer question

    I need to generate a precisely timed pulse train. For example, a 10uS pulse every 0.376467 +/- seconds.

    It looks like this could be done with the IntervalTimer functionality. I see that this takes a parameter which is the time interval in microseconds.

    My question is, is the resolution of this only 1.0 microsecond? Or can it go finer? The description says it can take a floating point number for the interval value.

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,882
    A while ago, we did update the IntervalTimer to allow you to get to maybe something like 0.73 microseconds.

    That was a quick and dirty fix to get us to about the same min interval as T3.2

    However I did/do have a version (Pull Request) that can run a lot faster than that

    By checking which clock the Interval timer is configured to use.

    Currently it is hard coded to use a fixed 24mhz clock. There is the ability to run those timers off of the system clock instead of that fixed clock.
    Which would allow much faster intervals, with the downside of lower maximum intervals.

    I believe that @luni's timer tool allows for faster intervals

  3. #3
    Thanks, Kurt. But I am not talking about the smallest interval, but the resolution.

    For example, if I want something like 376967.792 microseconds, will it get rounded to 376968 or 376967.8 or 376967.79?

    Another question. Can the timers be driven from an external clock source?

  4. #4
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,882
    Sorry the easiest way to answer this is to do the math...
    That is, if you look at the code.
    Code:
    	bool begin(void (*funct)(), float microseconds) {
    		if (microseconds <= 0 || microseconds > MAX_PERIOD) return false;
    		uint32_t cycles = (float)(24000000 / 1000000) * microseconds - 0.5f;
    		if (cycles < 17) return false;
    		return beginCycles(funct, cycles);
    	}
    So passing in your number I believe cycles is: 9,047,226.508 or as integer 9,047,226

    Again timer running at 24mhz so resolution is more or less 1/24000000 or about .0416666667uf...

    As for driving timer by external clock, sorry have not tried that so no ideas.

  5. #5
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,210
    I believe that @luni's timer tool allows for faster intervals
    Yes, you can select the PIT/GPT timer input clock (24/150MHz) and the TMR timer prescaler (1..128) in the config file. At minimum settings (GPT/PIT = 150MHz, TMR presaler = 1 and TCK @600MHz) you get the following resolutions:
    Code:
    TCK:          1.67 ns
    PIT/GPT/TMR:  6.67 ns
    However, in real life applications you will always face jitter due to other interrupts, so these values are just theoretical.
    See here for the full documentation of the library: https://github.com/luni64/TeensyTimerTool/wiki

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,001
    Quote Originally Posted by OhioJim View Post
    But I am not talking about the smallest interval, but the resolution.
    It will get rounded to the nearest 1/24th of a microsecond, if the PIT timer clocks at its default 24 MHz. Or rounded to 1/150th of a microsecond if you clock the PIT at 150 MHz.


    Quote Originally Posted by OhioJim View Post
    Another question. Can the timers be driven from an external clock source?
    The PIT timers do not support external clock. Only the 24 MHz crystal or the peripheral clock (normally 150 MHz) can be selected.

    However, the GPT timers can use external clocks. GPT1 can be clocked using pin 25 (AD_B0_13) and GPT2 can be clocked using pin 14 (AD_B1_02). The GPT timers are documented in chapter 52 of the reference manual, starting on page 2945.

    https://www.pjrc.com/teensy/datasheets.html

    In addition to configuring the GPT timer, you will also need to program the pin's I/O mux register (documented on page 490 and 494 for those pins) and also the timer's input select register (documented on page 936 and 939 for those timers).

    The GPT timers also have output compare circuitry which will allow you to create the pulses using only hardware, which solves the variable latency of using interrupt code to pulse the pin. But using GPT does require more learning to directly configure the hardware registers, since we don't have an easy-to-use software API like IntervalTimer to access the PIT timers.

  7. #7
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,210
    In case you want to give the TeensyTimerTool a try, here some working code using the GPT timers. It uses a second (one-shot-)timer to reset the pin which avoids waiting 10Ás in the ISR. GPT clock was set to 150MHz in the config file.

    Code:
    #include "TeensyTimerTool.h"
    using namespace TeensyTimerTool;
    
    PeriodicTimer mainTimer(GPT1);
    OneShotTimer pulseTimer(GPT2);
    
    void mainISR(){
        pulseTimer.trigger(10.0us); // start the pulse timer to reset the pin after 10Ás. If necessary, you can fine tune the 10Ás to compensate for time needed to call the trigger function. 
        digitalWriteFast(0, HIGH);
    }
    
    void pulseISR(){
        digitalWriteFast(0, LOW); // reset the pin
    }
    
    void setup(){
        pinMode(0, OUTPUT);
    
        mainTimer.begin(mainISR, 0.376467s); // invoke the callback every 0.376467s
        pulseTimer.begin(pulseISR);          // attach the pulseISR callback to the oneShotTimer
    }
    
    void loop(){
    }
    Unfortunately my cheap (24Mhz) logic analyzer is not precise enough to measure more than 4 digits but those at least correspond nicely to the requested 0.376467s.
    Click image for larger version. 

Name:	Screenshot 2020-10-18 134858.jpg 
Views:	12 
Size:	17.8 KB 
ID:	22122

    Please note: it looks like the newest version of the library (v0.3.1) is not yet detected by the Arduino library manager. But you can always download it from the gitHub repo.

  8. #8
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,593
    Quote Originally Posted by PaulStoffregen View Post

    However, the GPT timers can use external clocks. GPT1 can be clocked using pin 25 (AD_B0_13) and GPT2 can be clocked using pin 14 (AD_B1_02). The GPT timers are documented in chapter 52 of the reference manual, starting on page 2945.

    https://www.pjrc.com/teensy/datasheets.html

    In addition to configuring the GPT timer, you will also need to program the pin's I/O mux register (documented on page 490 and 494 for those pins) and also the timer's input select register (documented on page 936 and 939 for those timers).
    Here are two proof-of-concept sketches clocking GPT timers from external clock.
    https://github.com/manitou48/teensy4.../gpt_count.ino GPT1
    https://github.com/manitou48/teensy4...gpt2_count.ino GPT2

  9. #9
    Senior Member
    Join Date
    Feb 2018
    Location
    Corvallis, OR
    Posts
    243
    Once you figure out how to get part-per-million timing resolution, you can start to worry about stability. Since the crystals on the Teensy probably have temperature coefficients of up to 25PPM/deg C, just breathing on your Teensy is likely to change your 0.376467s time interval by 5 to 10 microseconds. Great timing resolution is nice, but doesn't help much if the frequency source to the timer doesn't have equivalent stability.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •