Forum Rule: Always post complete source code & details to reproduce any issue!
Page 12 of 13 FirstFirst ... 2 10 11 12 13 LastLast
Results 276 to 300 of 303

Thread: TeensyTimerTool

  1. #276
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,704
    Quote Originally Posted by Alex4455 View Post
    ... then everything works correctly, but I don't want to use Delay()
    You can use elapsedMillis instead:
    Code:
    elapsedMillis stopwatch;  
    
    void setup()
    {
        //....
    }
    
    void loop()
    {
       if(stopwatch > 500) 
       {     
          Serial7.print("IF;");
          Serial7.flush();
          stopwatch-=500;
       }
    }
    BTW: why don't you want to use delay?

  2. #277
    Quote Originally Posted by luni View Post
    You can use elapsedMillis instead:
    Code:
    elapsedMillis stopwatch;  
    
    void setup()
    {
        //....
    }
    
    void loop()
    {
       if(stopwatch > 500) 
       {     
          Serial7.print("IF;");
          Serial7.flush();
          stopwatch-=500;
       }
    }
    BTW: why don't you want to use delay?
    thank you! I will try to do so,
    I have many other tasks in the code, I would not like to delay them ..

  3. #278
    Hello dear.
    please tell the beginner again,
    how to implement such an algorithm ?
    Thanks in advance for your help !

    Timer1 = 15 ms
    Timer2 = 25 ms

    if (Condition 1)
    {
    Timer1 ON
    Executable code 1
    Timer1 OFF
    }

    if (Condition 2)
    {
    Timer2 ON
    Executable code 2
    Timer2 OFF
    }

  4. #279
    Member ProfHuster's Avatar
    Join Date
    Aug 2018
    Location
    Pittsburgh PA
    Posts
    23
    I need a 40 kHz pulse train so I used a timer at 12.5 us and toggled the output on and off, but the PeriodicTimer only uses integer microseconds. I searched this forum for "submicrosecond" and "nanosecond" and did not find hits.
    I was using a Teensy 3.2, but switched to a 4.0. Using the TeensyTimerTool I am able to get a stable eight pulse train - but at 12 us half period instead of 12.5 us.

  5. #280
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,607
    There is delaynanoseconds() and nanos()

  6. #281
    Member ProfHuster's Avatar
    Join Date
    Aug 2018
    Location
    Pittsburgh PA
    Posts
    23
    Ahhh. So inside my isr I could delay 500 ns? A hack.
    So I could calculate the extra nanoseconds I need and store it in a global volatile int, and the isr could delay that many ns. (I hate coding for a fixed frequency and having a "magic" number buried in an isr.)

    Thanks for the idea!

  7. #282
    Member ProfHuster's Avatar
    Join Date
    Aug 2018
    Location
    Pittsburgh PA
    Posts
    23
    Is it safe to use a delay function in an ISR?

  8. #283
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,607
    Yes it is .

  9. #284
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,704
    The following should generate 8 pulses at 40kHz on a T3.2 using the the first of the 8 FTM0 hardware timers.

    Code:
    #include "Arduino.h"
    #include "TeensyTimerTool.h"
    using namespace TeensyTimerTool;
    
    PeriodicTimer timer(FTM0);
    
    void pulse()
    {
        static unsigned cnt = 0;
    
        if (cnt++ < 16)
            digitalToggleFast(0);
        else
            timer.stop();
    }
    
    void setup()
    {
        pinMode(0, OUTPUT);
        timer.begin(pulse, 2 * 40_kHz);
    }
    
    void loop()
    {
    }
    How precise do you need your 40kHz? At the standard CPU clock of 96MHz the FTMs are clocked with 48MHz. If you set the CPU clock to 120MHz you get a bus clock of 60MHz which fits better to your 40Khz requirement (-> reload value = 750). I also suggest to set the counter prescaler to the smallest value to get a better resolution (see here https://github.com/luni64/TeensyTime.../Configuration how to do this)

  10. #285
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,704
    Just saw that you switched to a T4. The only thing you need to change in the code above is to use TMR4 instead of FTM0. Reducing the prescaler is also suggested. I.e., change it from PSC_128 to PSC_1 in line 46 of the config file.

    Here a LA trace for the T4.0 using the code from above (with TMR4 instead of FTM0)

    Click image for larger version. 

Name:	Screenshot 2021-08-25 213822.jpg 
Views:	41 
Size:	25.2 KB 
ID:	25661

  11. #286
    Member ProfHuster's Avatar
    Join Date
    Aug 2018
    Location
    Pittsburgh PA
    Posts
    23
    Quote Originally Posted by Frank B View Post
    There is delaynanoseconds() and nanos()
    Apparently only for Teensy 4.X.
    For Teensy 3.2 I might have to live with 41.7 kHz.

  12. #287
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    25,491
    Quote Originally Posted by ProfHuster View Post
    Is it safe to use a delay function in an ISR?
    Normally, yes.

    But if you've increased your interrupt's priority level to beyond 32 (lower numbers mean higher priority), then no.

    Most interrupts default to priority 128, in the middle of the 0-255 range. The timing stuff defaults to 32 (nearly the highest priority), so it's usable from most other interrupts. But we never configure any of the core library or main Teensyduino libraries to use higher priority than 32 (numbers 31 or less) for people who need their interrupt to work in at the highest priority.

  13. #288
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    25,491
    Quote Originally Posted by ProfHuster View Post
    Apparently only for Teensy 4.X.
    Maybe you have an old version. In Arduino, click Help > About to check.

    Teensyduino 1.54 brought delayNanoseconds() to all Teensy models, even Teensy 2.0. Obviously at only 16 MHz, the nanosecond resolution isn't as good, but it is implemented as well as AVR can do.

  14. #289
    Member ProfHuster's Avatar
    Join Date
    Aug 2018
    Location
    Pittsburgh PA
    Posts
    23

    Jumped Threads

    Quote Originally Posted by luni View Post
    The following should generate 8 pulses at 40kHz on a T3.2 using the the first of the 8 FTM0 hardware timers.

    Code:
    #include "Arduino.h"
    #include "TeensyTimerTool.h"
    using namespace TeensyTimerTool;
    
    PeriodicTimer timer(FTM0);
    
    void pulse()
    {
        static unsigned cnt = 0;
    
        if (cnt++ < 16)
            digitalToggleFast(0);
        else
            timer.stop();
    }
    
    void setup()
    {
        pinMode(0, OUTPUT);
        timer.begin(pulse, 2 * 40_kHz);
    }
    
    void loop()
    {
    }
    How precise do you need your 40kHz? At the standard CPU clock of 96MHz the FTMs are clocked with 48MHz. If you set the CPU clock to 120MHz you get a bus clock of 60MHz which fits better to your 40Khz requirement (-> reload value = 750). I also suggest to set the counter prescaler to the smallest value to get a better resolution (see here https://github.com/luni64/TeensyTime.../Configuration how to do this)
    I changed loop to repeat the pulse train with a delay of 100 ms.
    Code:
    void loop()
    {
      delay(100);
      cnt = 0;
      timer.begin(pulse, 2 * 40_kHz);
    }
    where cnt is a global volatile.

    With a Teensy 3.2 I get about 2.5 us jitter in the length of the whole pulse train, 1.25 %. (NOT the rep rate. I trigger my scope on the leading edge of the pulse train.)
    With a Teensy 4.0, changing the timer to GPT1 I can't see any jitter on a 250 ns/cm scale.
    I am making an ultrasonic anemometer so that jitter limits my windspeed resolution to about 1.2% of the sound speed, or about 4 m/s. I need about 0.5 m/s to 0.1 m/s accuracy.
    I would like to stay with the Teensy 3.2 because I have a bunch of them, and for the power consumption.

    BTW, I posted here with a question about TeensyTimerTool that was spawned from a different thread, so see https://forum.pjrc.com/threads/68040...actly-N-pulses for the bigger discussion.
    Last edited by ProfHuster; 08-26-2021 at 03:28 PM. Reason: Additional Information

  15. #290
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,607
    Try delayMicroseconds(100 * 1000);
    if that does not help, you may have to use an additional timer(which is preferable anyway)
    I.e. an intervalTimer

  16. #291
    Member ProfHuster's Avatar
    Join Date
    Aug 2018
    Location
    Pittsburgh PA
    Posts
    23
    The problem is NOT in the repetition rate. The total length of a single train of 8 pulses jitters by 2.5 us. In the other thread I took a suggestion and tried the IntervalTimer. Much better results. 50 ns jitter in the length of the pulse train and a frequency of 39.8 kHz which is closer to 40 kHz than I could get with the TeensyTimerTool.

  17. #292
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,607
    ah, ok, I misunderstood.

  18. #293
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,704
    With a Teensy 3.2 I get about 2.5 us jitter in the length of the whole pulse train, 1.25 %. (
    The FTMs are a bit tricky since the 8 channels share one timer. In the ISR the TimerTool adds the channel reload value to the current counter which of course takes some time so that the actual period is not super accurate.
    The GPTs have one timer per channel (as do the TMRs and PITs) -> periods are as precise as the timer is.

    Generally, if you have such high performance requirements a canned, general purpuse library may not be the best choice. If you need to stick with the T3.2 I'd use the PITs and optimize the reload value.

    Anyway, the jitter can be reduced by increasing the priority of the FTMs. Here some code to show this and to measure the jitter.
    Code:
    #include "Arduino.h"
    #include "TeensyTimerTool.h"
    using namespace TeensyTimerTool;
    
    PeriodicTimer timer(FTM0);
    
    volatile uint32_t cnt = 0;
    volatile bool run     = false;
    volatile uint32_t dt  = 0;
    
    void pulse()
    {
        static uint32_t t0 = 0;
        if (cnt == 0)
        {
            t0  = ARM_DWT_CYCCNT;
        }
    
        if (cnt++ < 16)
            digitalToggleFast(0);
        else
        {
            dt = ARM_DWT_CYCCNT - t0;
            timer.stop();
            run = false;
            cnt = 0;
        }
    }
    
    void setup()
    {
        pinMode(0, OUTPUT);
    
        ARM_DEMCR |= ARM_DEMCR_TRCENA;          // enable debug/trace
        ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; // enable cycle counter
    
        timer.begin(pulse, 12.0f, false);  // experimentally optimize frequency since FTMs share one timer for the channels
    
        NVIC_SET_PRIORITY(IRQ_FTM0, 1);   // higher priority to reduce jitter
    }
    
    void loop()
    {
        run = true;
        timer.start();             // start the timer
        while (run == true) {}     // wait until done
    
        Serial.println(dt/96.0f);  // print time for complete sequence in Ás
        delay(100);
    }
    This prints (microseconds)
    Code:
    200.59
    200.59
    200.89
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.60
    200.84
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.72
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.60
    200.59
    200.64
    200.59
    200.59
    201.01
    200.64
    200.59
    200.59
    201.01
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.60
    200.59
    200.59
    200.64
    200.59
    201.01
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.60
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.61
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    201.01
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.89
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.72
    200.59
    200.59
    200.59
    200.68
    200.59
    200.59
    200.59
    200.68
    200.59
    200.59
    200.59
    200.68
    201.01
    200.59
    200.59
    200.68
    200.76
    200.59
    200.59
    200.68
    200.76
    200.59
    200.59
    200.68
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.60
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    201.01
    200.59
    200.59
    200.59
    201.01
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.61
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    201.01
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.60
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.80
    200.64
    200.59
    200.59
    200.76
    200.64
    200.60
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.76
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    201.01
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.76
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    201.01
    200.59
    200.59
    200.64
    200.76
    200.60
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.80
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.89
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.76
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    201.01
    200.59
    200.59
    200.59
    201.01
    200.59
    200.59
    200.59
    200.76
    200.60
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.93
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.59
    200.59
    200.59
    200.64
    200.60
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    201.01
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.93
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.76
    200.59
    200.59
    200.59
    200.59
    200.59
    200.59
    Here the jitter analysis:

    Click image for larger version. 

Name:	Screenshot 2021-08-26 165012.gif 
Views:	29 
Size:	7.0 KB 
ID:	25668

    And here the pulse train
    Click image for larger version. 

Name:	Screenshot 2021-08-26 164924.gif 
Views:	31 
Size:	43.0 KB 
ID:	25669

    Edit: BTW you should use the newest version of the library (0.3.5). While doing your examples I found some glitches wich are fixed...

  19. #294
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,704
    Just for fun, a very quickly hacked version using a PIT directly. This gives rock solid 40kHz pulses and no jitter. Let me know if you need explanations...

    Code:
    #include "Arduino.h"
    
    IntervalTimer timer;
    KINETISK_PIT_CHANNEL_t* channel;
    
    volatile uint32_t cnt = 0;
    volatile bool run     = false;
    volatile uint32_t dt  = 0;
    
    void pulse();
    
    void init()
    {
        timer.begin(pulse, 100);                            // get an interval timer
        int n          = (IRQ_NUMBER_t)timer - IRQ_PIT_CH0; // old trick to get hold of the used channel
        channel        = KINETISK_PIT_CHANNELS + n;
        channel->TCTRL = 0;       // stop the timer
        channel->LDVAL = 600 - 1; // set to 40 kHz
    }
    
    void start()
    {
        channel->TCTRL = PIT_TCTRL_TEN | PIT_TCTRL_TIE;
    }
    
    void stop()
    {
        channel->TCTRL = 0;
    }
    
    void pulse()
    {
        if (cnt++ < 16)
            digitalToggleFast(0);
        else
        {
            stop();
            run = false;
            cnt = 0;
        }
    }
    
    void setup()
    {
        pinMode(0, OUTPUT);
        init();
    }
    
    void loop()
    {
        run = true;
        start();                  // start the timer
        while (run == true) {}    // wait until done        
        delay(100);
    }

  20. #295
    Junior Member
    Join Date
    Jan 2017
    Posts
    4
    ...first, awesome work/library! But in addition to trigger some actions based on some accurate timing I need some time measurement based on pin level changes. Do I missed something or is a simple running timer which I can ask for the time while pin level changed missing ? Besides the general elapsedMicros or elapsedMillis ...

  21. #296
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,704

    TeensyTimerTool v0.4.1

    There is a new release (v0.4.1) of the TimerTool: https://github.com/luni64/TeensyTimerTool/releases

    Main new features:
    • Destructors should work now -> you can define your timer locally. Leaving the scope will gracefully shut down the timer and release allocated hardware resoruces (...hopefully)
    • setPeriod and setNextPeriod should work for most timers now (PIT, TMR, GPT, TCKxx) . Both functions will change the period of a running timer. setPeriod tries to do this immediately (which only works if the new period is longer than the old one or the request comes early enough), setNextPeriod will do the change after the current period is done. Both functions also accept std::chrono time literals e.g. setPeriod(2.2s) or setNextPeriod(14534ns) etc.
    • I added a new 64 bit software timer (TCK_RTC) which is based on the built in RTC instead of the cycle counter. This might be useful if the callbacks need to be synced to the RTC.
      Here an example printing the drift between the 32.768kHz RTC crystal and the 24MHz main crystal:
      Code:
      #include "TeensyTimerTool.h"
      using namespace TeensyTimerTool;
      
      PeriodicTimer t1(TCK_RTC);
      
      constexpr uint32_t period = 500'000; //Ás
      
      void callback()
      {
          static uint32_t start = micros();
          static uint32_t idx   = 0;
      
          uint32_t now          = micros() - start;
          uint32_t expected     = idx++ * period;
          int32_t delta         = now - expected;
          float drift           = 1E6 * delta / expected;  // ppm
      
          Serial.printf("t: %d Ás,  rel. drift: %.2f ppm\n", now, drift);
      }
      
      void setup(){
          t1.begin(callback, period);
      }
      
      void loop(){
      }
      output:
      Code:
      ....
      t: 17500023 Ás,  rel. drift: 1.31 ppm
      t: 18000024 Ás,  rel. drift: 1.33 ppm
      t: 18500025 Ás,  rel. drift: 1.35 ppm
      t: 19000025 Ás,  rel. drift: 1.32 ppm
      t: 19500026 Ás,  rel. drift: 1.33 ppm
      t: 20000027 Ás,  rel. drift: 1.35 ppm
      t: 20500027 Ás,  rel. drift: 1.32 ppm
      t: 21000028 Ás,  rel. drift: 1.33 ppm
      t: 21500029 Ás,  rel. drift: 1.35 ppm
      t: 22000030 Ás,  rel. drift: 1.36 ppm
      t: 22500030 Ás,  rel. drift: 1.33 ppm
      ...
    Last edited by luni; 11-07-2021 at 12:09 PM.

  22. #297
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,704

    DMA based Pulse Generator for T4.x boards

    I added an alpha version of a DMA based pulse generator to the TimerTool (it lives in the PulseGenerator branch). Currently, it only works on the pins which can be driven by the TMR / QUAD timers. I.e., pins 10,11,12,13,14,15,18,19. I'll try to add the other pins (FlexPWM based) later, in case the whole thing turns out to be useful at all. (My final goal is to use DMA based pulse generation in TeensyStep, to avoid using resource- hungry timer interrupts for step pulse generation).

    Here examples how to use it and what can be done. The first example shows how to use compile time defined pulse sequences. You can enter the times using the std::chrono literals (ns, us, ms, s,..) or plain numbers (float), which are interpreted as microseconds. (BTW: conversion from chrono literals to (float)microseconds is always done at compile time. I.e., without runtime penalty)

    Code:
    #include "TeensyTimerTool.h"
    using namespace TeensyTimerTool;
    
    PulseGenerator pulseGenerator;
    
    // define a pulse train {{high,low},{high,low},....}
    PulseTrain train_1{{2ms, 3ms}, {1ms, 3ms}, {50us, 3ms}, {1000, 3000}, {2000, 3000}}; // numbers without units are interpreted as us (microseconds)
    
    // another pulse train
    PulseTrain train_2{{300ns, 2us}, {300ns, 3us}, {50ns, 3us}, {300ns, 2us}, {300ns, 2us}};
    
    void setup(){
        pulseGenerator.begin(10); // attach the pulse generator to pin 10
    }
    
    void loop(){
        pulseGenerator.trigger(train_1);    // select one or both pulse trains
        delay(100);
        //pulseGenerator.trigger(train_2);
        //delay(100);
    }
    train_1:
    Click image for larger version. 

Name:	pulsetrain1.jpg 
Views:	21 
Size:	60.4 KB 
ID:	26569

    train_2:
    Click image for larger version. 

Name:	pulsetrain2.jpg 
Views:	16 
Size:	22.0 KB 
ID:	26570


    The following example shows how to construct a pulse train at run time which probably is a more interesting use case:
    Code:
    #include "TeensyTimerTool.h"
    using namespace TeensyTimerTool;
    
    PulseGenerator pulseGenerator;
    
    void setup()
    {
        pulseGenerator.begin(10); // attach the pulse generator to pin 10
    
        // generate a simple acceleration/decleration pattern at runtime
        // e.g. a stepper motor ramp
        Pulse pulses[200];
        for (int i = 0; i < 100; i++)
        {
            pulses[i].hi = 500ns;
            pulses[i].lo = 2us + 500ns * i;
        }
        for (int i = 0; i < 100; i++)
        {
            pulses[i + 100].hi = pulses[99 - i].hi;
            pulses[i + 100].lo = pulses[99 - i].lo;
        }
        PulseTrain stepperTrain(pulses, sizeof(pulses)/sizeof(pulses[0])); // use the array to construct a PulseTrain
    
        pulseGenerator.trigger(stepperTrain); // trigger the pulse train.
    }
    
    void loop(){
    }
    Click image for larger version. 

Name:	Screenshot 2021-11-17 184611.jpg 
Views:	16 
Size:	32.2 KB 
ID:	26571

    As mentioned the pulse generation is done loading reload values from a buffer to the timer using DMA. I didn't do any measurements so far but it should not generate significant load on the processor. As far as my cheap LA can measure, pulses below 50ns seem to be possible. Ultimately the minimal pulse width is limited by the time the DMA channel needs to copy new compare values to the timer hardware.

    Let me know if this is of any use, if any additional features are needed to be useful etc. Extending to circular buffers, or other DMA schemes should be not too difficult. Using the other pins might be more demanding (I don't have any experience with the FlexPWM timers).

  23. #298
    Senior Member
    Join Date
    Jan 2015
    Location
    France
    Posts
    164
    Hello Lutz,

    today I had some time to share and I decided to update TeensyTimerTool library is some of my projects. For most of them I upgraded from 0.2.1 to 0.4.1.

    In one of them I had a problem with "isnan()" which don't operate now. If I switch back to 0.2.1 there is no problem. I use visualTeensy and VScode for most of my projects.

    Here is the VScode error :

    Code:
    'isnan' was not declared in this scope
    and here is the compilation error message :

    Code:
    src/main.cpp:2239:37: error: 'isnan' was not declared in this scope
       if (isnan((*item).RA->getAverage()))
                                         ^
    src/main.cpp:2239:37: note: suggested alternative:
    In file included from lib/TeensyTimerTool/src/API/baseTimer.h:12:0,
                     from lib/TeensyTimerTool/src/API/oneShotTimer.h:4,
                     from lib/TeensyTimerTool/src/TeensyTimerTool.h:3,
                     from src/main.h:19,
                     from src/main.cpp:9:
    c:\progra~2\arduino\hardware\tools\arm\arm-none-eabi\include\c++\5.4.1\cmath:641:5: note:   'std::isnan'
         isnan(_Tp __x)
         ^
    make: *** [makefile:232: .vsteensy/build/src/main.cpp.o] Error 1
    Hope (sure) you can solve the problem.

    Thank you,
    Manu

  24. #299
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,704
    Difficult to debug without code. Can you post an example showing the issue?

  25. #300
    Senior Member
    Join Date
    Jan 2015
    Location
    France
    Posts
    164
    thank you Luni for your fast response and yes, it's operate well when using std::isnan

Posting Permissions

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