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

Thread: Teensy 4.0 Timer Interrupt

  1. #1
    Junior Member
    Join Date
    Mar 2020
    Posts
    3

    Teensy 4.0 Timer Interrupt

    Hello. I have a project at Arduino DUE and want to use Teensy 4.0 in this project.

    I use timer interrupt in my project. Here is example:
    Code:
      Timer3.attachInterrupt(TimeKeeper);
      Timer3.start(500000);                                                
      Timer4.attachInterrupt(TimeAttention);
      Timer4.start(400000);                                                     
      Timer5.attachInterrupt(TimeButDelay);
      Timer5.start(300000);                                                      
      Timer6.attachInterrupt(TimeRotationDelay);
      Timer6.start(200000);
    How can i rewrite this code to use in Teensy 4.0 ? I want to use QuadTimer of NXP i.MX RT1060 processor, but don't find it's description in Arduino\hardware\teensy\avr\cores\teensy4 directory.

    Thanks,

    Ihar

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,564
    There may be other standard libraries usable - but starting with this thread :: pjrc.com/threads/59112-TeensyTimerTool

    And using the :: github.com/luni64/TeensyTimerTool

    This built in library may work as well: pjrc.com/teensy/td_timing_IntervalTimer.html - but may not offer the same flexibility or documentation level as TeensyTimerTool

  3. #3
    Junior Member
    Join Date
    Mar 2020
    Posts
    3
    Thank you for the answer. I followed your link, and used Tick Timer (TCK) from TeensyTimerTool library.

    Code below was rewrited to this one:

    Code:
      t1.begin(TimeKeeper, 500'000); 
      t2.begin(TimeAttention, 400'000);  
      t3.begin(TimeButDelay, 300'000); 
      t4.begin(TimeRotationDelay, 200'000);
    So, i solved this problem.

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,564
    Good choice as long as the loop() or calls to check for TCK's is called as often as you need accuracy in the timings as that is a polling check - not interrupt driven. So any delay() or tight loop or busy spot in the code will affect the triggering.

    The good thing is that functions won't be called under interrupt conditions so code there won't have race conditions that an interrupt might cause.

    Though that library could get _isr() calling on as many of those as needed using real timers - especially at those low rates

  5. #5
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    901
    So any delay() or tight loop or busy spot in the code will affect the triggering.
    Actually, calling delay() is fine, the TCK timers are ticked via yield() which is implicitly called in delay. If you have a long working loop you can always place a call to yield to keep the timers updating. See below for an example

    Code:
    void doSomething()
    {
         for(int i = 0; i < 10'000; i++=
        {
             // do some work
             // ....
             yield();       // give the TCK timers a chance to update...
        }
    }
    
    void loop()
    {
         doSomething(); 
         delay(1000);       // this is fine, since delay calls yield() in the background...
    }

    As defragster already mentioned, if this is not an option you can always use the hardware timers (e.g. TMR (QUAD), you have 16 of those on a T4).

  6. #6
    Quote Originally Posted by luni View Post
    Actually, calling delay() is fine, the TCK timers are ticked via yield() which is implicitly called in delay. If you have a long working loop you can always place a call to yield to keep the timers updating. See below for an example

    Code:
    void doSomething()
    {
         for(int i = 0; i < 10'000; i++=
        {
             // do some work
             // ....
             yield();       // give the TCK timers a chance to update...
        }
    }
    
    void loop()
    {
         doSomething(); 
         delay(1000);       // this is fine, since delay calls yield() in the background...
    }

    As defragster already mentioned, if this is not an option you can always use the hardware timers (e.g. TMR (QUAD), you have 16 of those on a T4).

    Code:
    Timer t1;
    So this takes Tick-Timer as a default
    Code:
    Timer t1(TMR1/GPT);
    and specifying TMR or GPT will take those one which is interrupt driven - correct?

  7. #7
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    901
    So this takes Tick-Timer as a default
    Code:
    Timer t1;
    No, it takes the next free timer from the pool (use this only for simple cases if you don't care which timer you get). The pool is defined in defaultconfig.h and its composition can be changed. See here for the config documentation: https://github.com/luni64/TeensyTime.../Configuration

    However, it clearer to explicitly define which timer you want. E.g. use
    Code:
    PeriodicTimer t1(TCK)
    to get a tick timer. (I used the new name 'PeriodicTimer' instead of the depreciated name 'Timer').

    Use
    Code:
    PeriodicTimer t1(TMR1)
    To get one of the four TMR1(QUAD1) timers and
    Code:
    PeriodicTimer t1(GPT2)
    to get the GPT2 timer etc.. All of this is documented here: https://github.com/luni64/TeensyTime...pported-Timers. Let me know if you miss something in the documentation or if something is not clear.
    Last edited by luni; 03-31-2020 at 02:57 PM.

Posting Permissions

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