TeensyTimerTool

Hello Luni,

It's look like the callback for timers must be void functions without any parameter. Is that it ?



Code:
#define RefreshADCPeriod 40

PeriodicTimer ReadADC1(TCK);
PeriodicTimer ReadADC2(TCK);

void setup (){
  ReadADC1.begin(timerReadADC(1), RefreshADCPeriod * 1000);
  currentMillis = millis();
  while (millis() < (currentMillis + 25));  
  ReadADC2.begin(timerReadADC(2), RefreshADCPeriod * 1000);
}

void timerReadADC(uint_fast8_t ANA) {
	if (ANA == 1) adc->adc0->startSingleRead(ANA1);
	else adc->adc0->startSingleRead(ANA2);
	return;
}

Didn't compile =>

Code:
D:\Mes documents\Arduino\CAN_DISPLAY_v2.1\CAN_DISPLAY_v2.1.ino:845:58: error: invalid use of void expression
   ReadADC1.begin(timerReadADC(1), RefreshADCPeriod * 1000);
                                                          ^
D:\Mes documents\Arduino\CAN_DISPLAY_v2.1\CAN_DISPLAY_v2.1.ino:848:58: error: invalid use of void expression
   ReadADC2.begin(timerReadADC(2), RefreshADCPeriod * 1000);

But if I use two callback functions it's OK.

Thank you,
Manu
 
It's look like the callback for timers must be void functions without any parameter. Is that it ?
In principle yes. The library can't know which parameters users need... But you can easily work around that. Here some options:

1) Introducing relay functions and attach them to the timer:

Code:
//....
void relay1(void)  // same for timerReadADC(2)
{
  timerReadADC(1);
}

void setup (){  
  ReadADC1.begin(relay1, RefreshADCPeriod * 1000);
  //....
  ReadADC2.begin(relay2, RefreshADCPeriod * 1000);
  //...
}

2) To avoid the tedious definition of those relay functions you can use lambdas to define them "inline"

Code:
void setup (){  
  ReadADC1.begin([]{timerReadADC(1);}, RefreshADCPeriod * 1000);
  //...
  ReadADC2.begin([]{timerReadADC(2);}, RefreshADCPeriod * 1000);
  //...
}

3) Since timerReadADC() itself is just relaying the actual call to adc->startSingleRead you can also do this directly:
Code:
void setup (){
  ReadADC1.begin([]{adc->adc0->startSingleRead(ANA1);},RefreshADCPeriod*1000);
  //...
  ReadADC2.begin([]{adc->adc0->startSingleRead(ANA2);},RefreshADCPeriod*1000);
  //...
}

Here https://github.com/luni64/TeensyTimerTool/wiki/Callbacks you find more information about the callback system of the TeensyTimerTool.

Hope that helps
 
Thank you Luni.
Another one for you. Today I gave a try to VCS and VisualTeensy. I use NotePad++ with success but it miss Intellisense...

I create a new project that meet the requirements for an existing one that is know for operate well. I set-up all the libraries in VT, create the project and then run VCS.

First thing is that I had to declare all the functions used in the project at the beginning of main.cpp, like I use to do in C. Is this normal ? I know it is the way to go with C, but I don't really know C++ and arduino IDE don't need such things. Maybe the IDE do this in the background before compilation ?

Second : I selected 'TeensytimerTool' in VT, but it doesn't appear in VCS under LIB tab. And at compilation I got and error that say "can't find "teensyTimerTool.h". How can I solve this please ? The funny thing is that it compile, upload, and operate.

Also, where can I find TyCommanderC.exe and Teensyloader_cli.exe ?

Thank you,
Manu
 
Last edited:
TyCommander is part of: https://github.com/Koromix/tytools
Teensyloader stuff can usually be found at: https://www.pjrc.com/teensy/loader_cli.html


As you may notice there are lots of ways/IDEs you can go to, including the great work of @luni
Then there is VisualMicro stuff, which I use some of the time - https://www.visualmicro.com/
Then there is some integration stuff for SublimeTools that @FrankB and @defragster setup, which I also use some of the time.

For me, one of my main things as I do all of this as a hobby and try to help out a little, so one of my strong preferences is that the IDE/Build system I use, produces the same results as the IDE... So that others who use the Arduino IDE can use it as well... And with many of these systems you end up with some subtle differences, like VisualMicro will use a library that ships with the Teensyduino IDE over the ones you install in your <arduino folders>/libraries folder.... Took me awhile to figure out why something was not working.

So gain Luni's stuff is great!
 
@Manu, great you gave VisualTeensy a try.

Quick answer:
If you want to get the same behaviour as you get with the Arduino IDE you can set the underlying build system to "Arduino Builder" with a switch in the settings tab. It then uses the same build system as used by the Arduino IDE instead of the standard c++ system. See here for a documentation: https://github.com/luni64/VisualTeensy/wiki. There are small chapters about how to use the Arduino Builder, and how to open an Arduino "ino project".

Long answers:
I had to declare all the functions used in the project at the beginning of main.cpp, like I use to do in C. Is this normal ? I know it is the way to go with C, but I don't really know C++ and arduino IDE don't need such things.
Yes, this is normal. C and c++ need to know the declaration of everything before they can use it. Usually forward declaration is not a big deal if you organize your project in *.cpp and *.h files. The header files (*.h) simply contain the required forward declarations of the stuff in the *.cpp files and you would #include them whenever needed.

For some reason the Arduino design team decided to hide this from their users and did something like a "pre-preprocessor". AFAIK it collects files it finds in the sketch folder and combines them into one huge file. It then auto generates all required forward declarations at the top of this file and compiles it. This works nicely for the small sketches 99% of the users usually do. IMHO this is one of the reasons for the huge success of the Arduino ecosystem. However, to me this always felt like those support wheels you give children to learn to ride a bicycle. Great for learning but once you know how to ride you want to get rid of them. But, all of this is my personal opinion only and instead of complaining I tend to fix stuff for me and so I did VisualTeensy...

I selected 'TeensytimerTool' in VT, but it doesn't appear in VCS under LIB tab. And at compilation I got and error that say "can't find "teensyTimerTool.h". How can I solve this please ? The funny thing is that it compile, upload, and operate.
Looks like the VT Wiki needs some explanation of the library system :)
Basically you can choose libraries from the following 3 repositories:

  • 'Teensyduino Libraries' which contains all Teensyduino libraries you installed when you installed Teensyduino.
  • 'Arduino Repository' which contains all libraries the Arduino library manager knows of. This is a huge repository and usually contains everything you need. Use the search field below the list of libraries to wade through it.
  • 'Installed shared libraries' which contains all libraries you installed manually or via the Arduino library manager. Usually they live in the library subfolder of the arduino sketchbook.

Libraries from the first two repositories are copied to your project folder. This means you can have different versions for different projects which is usually good since it prevents new library versions breaking existing code. Libraries from the shared folder are not copied to the project. The project will use them directly from the shared folder. (Something like "copy it to the project folder anyway" for shared libraries might be a good enhancement though.)

Back to your question: I assume that you installed the TeensyTimerTool via the Arduino library manager so it ends up in the shared library folder and won't be copied to the project but used from the shared folder. So, all good.

I got and error that say "can't find "teensyTimerTool.h"... The funny thing is that it compile, upload, and operate
This obviously is an intellisense error only (otherwise it wouldn't compile). Intellisense gets information about where to look for headers from the file .vscode/c_cpp_properties.json. Sometimes (seldom) vsCode doesn't get noticed about changes in this file (maybe some cache thing). Usually, closing vsCode and reopening it fixes this.

From KurtE: TyCommander is part of: https://github.com/Koromix/tytools
Teensyloader stuff can usually be found at: https://www.pjrc.com/teensy/loader_cli.html

I recommend to use the TyCommander for its nice GUI and most important: it includes a serial monitor. It also perfectly supports projects with more than one Teensy which makes server/client developments MUCH easier. The Teensyloader CLI is used by some for advanced scenarios. You probably don't need it.

From KurtE: As you may notice there are lots of ways/IDEs you can go to, including the great work of @luni
Then there is VisualMicro stuff, which I use some of the time - https://www.visualmicro.com/
I also started with VisualMicro which is great stuff indeed. But, IMHO, using the VisualStudio IDE for Arduino builds has one big disadvantage: the underlying intellisense engine uses the microsoft compiler which of course is not compatible to the GCC used for Teensy. I.e., the compiler used for building the project is not the same as that used for intellisense. VisualMicro is working around that by generating a header which hides most of the differences by undefining gcc stuff, but of course this can never be perfect and I got strange intellisense errors from time to time. (Admittedly, last time I tested it is some years ago, probably improved by now). The other thing I didn't like was that the actual build is hidden from the user which always confused me (but again, my personal opinion only).

In vsCode the intellisense engine can use different underlying compilers. VisualTeensy configures it to use the same compiler as it uses for compilation. This makes intellisense much more reliable and usable. E.g. you can usually "F12" even into system libraries, the #defines are correctly interpreted and so on.

From KurtE: Then there is some integration stuff for SublimeTools that @FrankB and @defragster setup, which I also use some of the time.
Never really used it. One question: does this solution provide some intellisense features (error wiggles, code completion, jumping into definition of functions etc) or does it use Sublime as better editor only?

From KurtE: For me, one of my main things as I do all of this as a hobby and try to help out a little, so one of my strong preferences is that the IDE/Build system I use, produces the same results as the IDE... So that others who use the Arduino IDE can use it as well... And with many of these systems you end up with some subtle differences, like VisualMicro will use a library that ships with the Teensyduino IDE over the ones you install in your <arduino folders>/libraries folder.... Took me awhile to figure out why something was not working.

That's true indeed, before publishing something I usually try to compile with the A-IDE to verify. But since standard c++ is more stringent than the Arduino builder it usually just compiles. The other way round is more difficult. Especially if users make heavy use of the Arduino helpers.

Sorry for the long post in the wrong thread :)
 
Last edited:
@Manu, great you gave VisualTeensy a try.
...
From KurtE: Then there is some integration stuff for SublimeTools that @FrankB and @defragster setup, which I also use some of the time.
Never really used it. One question: does this solution provide some intellisense features (error wiggles, code completion, jumping into definition of functions etc) or does it use Sublime as better editor only?

...

SublimeText is a decent environment with an advanced editor - GlobalFolder grep ( like anything in ...\hardware\teensy\avr ) - and that includes Search of Definition or usage of desired text.
> It does build with TSET in a console window - and pastes error text inline in source file ( though often linked to the file "as compiled from the TEMP" folder :( - KurtE found a link to a possible reprogram - Sublime is just a Python script runner )
-- > not always a problem for local source files it seems - but then they are not open files or something - you edit the TEMP copy and that doesn't fix anything.
> It does a bit of auto suggest - mostly annoying - but personal finding is they all are ...

I just changed to sublime at KurtE's suggestion and liking the few things I use and TSET with TyComm is natural build like the IDE does it to be forum portable - and even updated to fire off the GDB debugger work just added when desired.
But not done a real project yet - just tons of hacking on Betas and posted forum examples
 
Thank you to everyone.
@Luni : TeensyTimerTool problem was due to a space in the path to reach it ;-)
 
Hello Luni,

Is there a way to get a timer each minute simply ?
I understand that TCK timer use (int) for the period which is too small for a minute. I have others timers that use (millis).
I can do a loop counter to count x timers callback and when a minute is elapsed do the real job, but if there is a possibility to simply have a timer for minutes ;-)

Thank you,
Manu
 
Using one of the GPTs at 24MHz should work 2^32 * 1/24E6 = 179s which is about 3min max period

I'm also working on an optional extension of the counter variable to 64bit which will allow more flexibility for longer timeouts with the TCK timers.
 
I'm use Teensy 3.2 so there is no GPTs available.

But it was simple with TCK. I just used a "callback execution counter" and a loop to execute the relevant code each time the counter is at the right amount, while just doing "callback execution counter"++ each time the timer enter the callback if it's not the right moment to execute the right code ;-)
 
The 32bit cycle counter (ARM_DWT_CYCCNT) which is used for the TCK timers overflows quite fast (e.g. every 7s on a T4@600MHz). I therefore added a variant of the TCK timers which extends ARM_DWT_CYCCNT to 64bit (v0.2.0). This allows for periods up to to full 2^32 microseconds (4295 seconds, 71.6 minutes). The new timer works on all T3.x and T4.x boards. I'll add the documentation to the TeensyTimerTool WIKI in the next days.

Here a small T4 sketch which prints out the overflow duration of the timers currently available with the TeensyTimerTool. The sketch was run in standard configuration, i.e., F_CPU=600MHz, GPT & PIT @24MHz, QUAD @150MHz with prescaler: PSC_AUTO.

Code:
#include "TeensyTimerTool.h"
using namespace TeensyTimerTool;

PeriodicTimer t1(TCK);
PeriodicTimer t2(TCK64);  // <-- new
PeriodicTimer t3(GPT1);
PeriodicTimer t4(TMR3);
PeriodicTimer t5(PIT);

PeriodicTimer blink(TCK);

void empty(){}

void setup()
{
    while (!Serial) {}

    t1.begin(empty, 1'000);
    t2.begin(empty, 1'000);
    t3.begin(empty, 1'000);
    t4.begin(empty, 1'000);
    t5.begin(empty, 1'000);

    Serial.printf("TCK:           %8.3f seconds\n", t1.getMaxPeriod());
    Serial.printf("TCK64:         %8.3f seconds\n", t2.getMaxPeriod());    // <-- new
    Serial.printf("GPT(@24MHz)    %8.3f seconds\n", t3.getMaxPeriod());
    Serial.printf("QUAD(PSC_AUTO) %8.3f seconds\n", t4.getMaxPeriod());
    Serial.printf("PIT(@24MHz)    %8.3f seconds\n", t5.getMaxPeriod());

    pinMode(LED_BUILTIN, OUTPUT);
    blink.begin([] { digitalToggle(LED_BUILTIN); }, 300'000); // heart beat
}

void loop()
{
}

And here the output
Code:
TCK:              6.711 seconds
TCK64:         4294.967 seconds
GPT(@24MHz)     178.957 seconds
QUAD(PSC_AUTO)    0.056 seconds
PIT(@24MHz)     178.957 seconds
 
Hello Luni,

This is a great library, thank you. I used it in the audio processing unit of my Gameboy emulator. It allowed me to easily use a general purpose timer alongside the free quad timer. I had to fall back to IntervalTimer for the quads because they allow for easy update of the interval. When I tried the quad timers of your library I had audible glitches when restarting the timers with new frequencies. This will likely be improved in future updates of TeensyTimerTool, I suppose. In the meantime it's no big deal to use both TeensyTimerTool and IntervalTimer. So, great work! :)
 
Hello Luni,

today I updated TeensyTimerTool library on my computer and since, my project don't operate as it use to. Periodic timers don't start.
I tried to change some command according to your samples but there is nothing that allow timers to start.

Did you change something that I should be aware of ?
Thank you,
Manu
 
Sorry Luni, this was a cache problem
Cleaning the project and rebuild it solve all strange behaviour
thank you
 
Compatibility to std::chrono::duration

I recently stumbled over c++14 std::chrono::duration and its corresponding user defined literals (e.g. ms, h, ns...). For the fun of it and since I think it makes a nice interface I updated the TeensyTimerTool to additionally accept std::chrono::durations as timing parameters. You can use ns, us, ms, s, min, h.

Some examples:
Code:
 timer[0].trigger(10ms);                                  // 10 ms
 timer[1].trigger(0.5s + 10ms);                           // 510 ms
 timer[2].trigger(2.5 * 0.3s + 20000us / 2);              // 760 ms
 timer[3].trigger(milliseconds(50) + microseconds(5000)); // 55ms
 timer[4].trigger(2h + 15min);
BTW: the calculations above are all done at compile time, no runtime penalty :). Anyway, in case you don't like the feature, you can always opt out in the config file.

Here the release: https://github.com/luni64/TeensyTimerTool/releases
and here the documentation: https://github.com/luni64/TeensyTimerTool/wiki

Unrelated to the TimerTool you can also use chrono::duration to do things like

Code:
for (auto time = 0.0s; time < 3s; time += 250ms)
{
    float sec = time.count();
    Serial.printf("%.2f s\n", sec);
}
which prints:
Code:
0.00 s
0.25 s
0.50 s
0.75 s
1.00 s
1.25 s
1.50 s
1.75 s
2.00 s
2.25 s
2.50 s
2.75 s
 
Just a quick update to the TeensyTimerTool: I managed to define my own frequency types and added the corresponding literals to the periodic timer begin functions. In addition to plain microseconds and the duration literals from the last post, you can now write stuff like this:
Code:
timer.begin(isr, 100_kHz);       // instead of      10 (µs)
timer.begin(isr, 0.25_MHz);      // instead of       4 (µs)
timer.begin(isr, 5_kHz + 10_Hz); // instead of 100'200 (µs)

Works with all periodic timers (TCK, GPTx, TMRx, FTMx, TCK64). All calculations and the conversion to the required timer ticks are done at compile time.

(https://github.com/luni64/TeensyTimerTool/releases)
 
I had to fall back to IntervalTimer for the quads because they allow for easy update of the interval. When I tried the quad timers of your library I had audible glitches when restarting the timers with new frequencies.

Hello blazarious,

have you tried to retrigger your timer in the callback function? I do this with GPT2 on a Teensy 4 without any problems like:

Code:
void callback() {

      if (intervalTime != prevIntervalTime) {
        t1.trigger(intervalTime);
        prevIntervalTime = intervalTime;
      }

      /* do something here */

}
Every time an interval is completed and your timing has changed the timer gets an update.

:cool:WK
 
Hi Luni,

I installed the last version of TeensyTimerTool and use it with a project that already have the previous version working. In this project I use TeensytimerTool to drive a chronometre with a periodic timer. As usual in such case, I have variables that are called "minutes", "seconds", etc...
With the last version of TeensyTimertool, VSCode trigger problems with this variables names. I think that this is because you also use them in your templates, since addition of chrono ?

Thank you,
Manu
 
Yes, that's true. You can opt out of the use of the chrono extensions if you don't like it. (But since you are doing a chronometer the new chrono stuff might come in handy? See also: https://github.com/TeensyUser/doc/wiki/durations-timepoints-and-clocks)

Here the section of the config where you can disable the use of std::chrono

Code:
//--------------------------------------------------------------------------------------------
// Use additionally c++14 user literals (e.g. 3.4s, 50ms ...) for time inputs
// Comment the following line if you don't want this.

    #define USE_TIME_LITERALS
 
I choose to rename my variables ;-)

But I have another problem... TeensyTimerTool throw errors :

multiple definition of 'enum class TeensyTimerTool::errorCode'

Have to figure why..
 
As discussed per PM the reason for this is a glitch in vsTeensy. The generated makefile double compiles libraries when you install them in the shared folder and additionally locally in your project folder. I'm working on a fix asap.
 
Back
Top