TeensyTimerTool

Thank you Luni for your Pulsegenerator post. Coincidentally I am implementing a pulsegenerator for 13 channels on the FlexPWM2/3/4 pins.

The pulses are typically 2-50us long. At the moment I'm using 13 OneShotTimers using TCK64 for scheduling, and testing whether to use the DoubleExposure example adapted to generate the pulse itself. I think a downside is that any delay on calling the tick timer would increase the pulselength when using TCK*. Another option I used before was to use noInterrupts() and just count the number of ARM_DWT_CYCCNT counter ticks.

Do you think the DMA based pulsegenerator would be a better fit, even if using FlexPWM channels?
 
Do you think the DMA based pulsegenerator would be a better fit, even if using FlexPWM channels?
Depends on your requirements of course. I currently implemented the DMA pulse generator only for the TMR/QUAD timers. It was more or less an exercise in DMA programming (which I didn't do so far). To extend the TMR code to the FlexPWM timers I need to read into the documentation first (which will not happen soon). If you want to implement the pulse generator code for the FlexPWM channels I'd be more than willing to integrate it to the library.
 
I tried to get into it but I'm afraid I'm not well versed enough yet to implement it.

For now the TCK based approach works very well, once again thanks for the library. In the callback, I use

Code:
void PulseGenerator::callback()
{
  noInterrupts();
  digitalWriteFast(pin, HIGH);
  delayNanoseconds( width );
  digitalWriteFast(pin, LOW);
  interrupts();
}

This gives a pulse of the correct length +26ns.
 
This new(?) TeensyTimerTool message thread has been very helpful...

I (C++ noob) and helping my friend (C noob) with writing control software on a Teensy3.5 to implement a custom hardware solution.

We have been trying to use TeensyTimerTool.

Due to needing delays of upto a few minutes we have used the TCK64 timer type.

I have looked at the source code in the library, but admit to being confused. I have also looked at the wiki web pages.

Apologies, but I didn't see any clear reference to these "special" time units that can be used (100us etc.).
In this thread I came across "You can use ns, us, ms, s, min, h" which answers my question, however I would suggest that someone who is able updates the wiki to add this very useful information.



The timer functions have been put in a cpp called "timer.cpp". I mention this as some code which compiles in the ".ino" does not compile in a ".cpp" because I think of missing #includes.

We want to use a set of One Shot timers.

I apologise because I am confused. The examples are trivial cases which don't quite match our need to call a one shot timer many times during execution of the code.

So do I declare all our one shot timers in the setup() *once* using begin?
The examples appear to show "begin()" repeated several times on the same timer. If a timer expires do you have to do a new "begin()".

To trigger one I use mytimer.trigger(time)?
To re-trigger a timer, do I call "trigger()" again or do I need to call another "begin()"?

To stop an oneshot timer I can use mytimer.stop()?
We need to do this if a higher priority event occurs. I think I read that stop() is a fairly new function. I did search for this function, but my C++ is too poor to help my understand where to look. Again in the wiki I think that stop() and any other functions (wrong term I know) for OneShotTimer's are not yet documented. Apologies if I am wrong.

OK, my bad, found it. <your documents folder>\Arduino\libraries\TeensyTimerTool\src\API> oneShotTimer.h , however I am getting confused as to where everything referenced is defined, so still confused

All the examples appear to pass fixed values to the timer functions. In our code there are variables which define the delay in seconds. These user defined delays can be adjusted in the GUI (not yet implemented but we have a dummy set of functions to return the user value as an unsigned int representing the seconds).

Code:
  int??? led_timeout = 1s * settings_timeout_timer();
  timeout.trigger(led_timeout);

We couldn't figure out what type led_timeout needs to be. None of the int types worked. But the following workaround worked...

Code:
  timeout.trigger(1s * settings_timeout_timer());

So just what type should led_timeout be declared as?
In order to get my int value (func call return value in this case) into the correct type, I think multiplying by "1s" is the most obvious way?

I also wondered what is the tick/delta time for each type of timer. Is this documented? It would be nice to see a table in the wiki. I note that there is a program to show the maximum time. We thought that we might need this information initially as we were going to pass an "int" type to the timer, so needed to know how big a tick was. Using the special(?) time types makes the code much more readable, so we will go this way.

Thank you in advance for any help which makes me less confused. Any pointer to web pages which I have not managed to find, also would be appreciated. I always seem to miss the obvious!!!
 
I lot of questions... I need to leave soon but I can try to answer a few. I can also provide some examples for your requirements but not before the weekend.

In this thread I came across "You can use ns, us, ms, s, min, h" which answers my question, however I would suggest that someone who is able updates the wiki to add this very useful information.

I'll add something in the WIKI but the usage is really straight forward, 42ms just means 42 milliseconds. Translation into the internally used microseconds is done by the compiler. If the time literals confuse you you can just omit them, numbers without those literals are interpreted as microseconds.

The timer functions have been put in a cpp called "timer.cpp". I mention this as some code which compiles in the ".ino" does not compile in a ".cpp" because I think of missing #includes.

This is not a problem



We want to use a set of One Shot timers.
I apologise because I am confused. The examples are trivial cases which don't quite match our need to call a one shot timer many times during execution of the code.
So do I declare all our one shot timers in the setup() *once* using begin?

If you declare the timers in setup they will only work in setup. Usually you would declare the timers as global objects (i.e., "above" setup as shown in the examples) In setup you would call begin(...) for all the timers you want to use. The timers also support more complex usage but you will probably not need that.

The examples appear to show "begin()" repeated several times on the same timer. If a timer expires do you have to do a new "begin()".

You can trigger a oneShotTimer as often as you like. You need to call begin() only once.

To trigger one I use mytimer.trigger(time)?
To re-trigger a timer, do I call "trigger()" again or do I need to call another "begin()"?

Yes, you trigger it with the trigger function. You can retrigger it as often as you like, no need to call begin() more than once.

To stop an oneshot timer I can use mytimer.stop()?
Yes

We need to do this if a higher priority event occurs. I think I read that stop() is a fairly new function. I did search for this function, but my C++ is too poor to help my understand where to look. Again in the wiki I think that stop() and any other functions (wrong term I know) for OneShotTimer's are not yet documented. Apologies if I am wrong.
Should work for a oneShotTimer but I need to double check

OK, my bad, found it. <your documents folder>\Arduino\libraries\TeensyTimerTool\src\API> oneShotTimer.h , however I am getting confused as to where everything referenced is defined, so still confused
If you are not fluent in c++ you'll probably be lost browsing the code. Especially if you are not using one of the more modern IDEs which help you following symbols without searching through files.

All the examples appear to pass fixed values to the timer functions. In our code there are variables which define the delay in seconds. These user defined delays can be adjusted in the GUI (not yet implemented but we have a dummy set of functions to return the user value as an unsigned int representing the seconds).

Of course you can also pass a variable to the functions (any numeric type will be accepted). The value will be interpreted as microseconds, so you need to multiply your seconds by 1E6.

Code:
  int??? led_timeout = 1s * settings_timeout_timer();
  timeout.trigger(led_timeout);

You can time literals but I recommend to simply pass microseconds in your case

We couldn't figure out what type led_timeout needs to be. None of the int types worked. But the following workaround worked...

Code:
  timeout.trigger(1s * settings_timeout_timer());

I'll show an example tomorrow

So just what type should led_timeout be declared as?
In order to get my int value (func call return value in this case) into the correct type, I think multiplying by "1s" is the most obvious way?

As mentioned, you can use an int, the value will be interpreted as microseconds

I
also wondered what is the tick/delta time for each type of timer. Is this documented? It would be nice to see a table in the wiki. I note that there is a program to show the maximum time. We thought that we might need this information initially as we were going to pass an "int" type to the timer, so needed to know how big a tick was. Using the special(?) time types makes the code much more readable, so we will go this way.

That depends on the kind of timer, the CPU frequency and prescaler settings, I'll add some information to the wiki
 
Dear @luni, many thanks for taking the time to reply.

It is getting clearer, and will make sense once we have had a play. My friend and I had another session tonight and managed to get our first 5 second delay to work as wanted!

Re my comment about "You can use ns, us, ms, s, min, h". I simply wasn't sure whether seconds were coded as "s" or "sec" or "seconds", until I read that statement in an earlier posting. TBH I'm blown away that C++ allows such coding of values. I used to work on equipment where voltages, currents and times were programmed, and came across code like "vout = 10*mV;" , so you always had to remember to use the multiply. I assume that the "mV" was a #define somewhere.

Thank you for the clarification of base units being in microseconds, because I had (wrongly) assumed that the base unit would be a minimum value determined by hardware and would differ from Teensy type to Teensy.

From an earlier thread I found a page mentioning the namespace for std::chrono and discovered the "seconds" type. I declared my variable as this type "seconds led_timeout = 1s * ..." and it worked. From the same page I saw use of what I assume is a function "seconds()" which appears to type convert from int/uint to time type. I think that both approaches will work.

I have viewed a few files in the TeensyTimerTool source area, but my C++ noobness has prevented me from really understanding what is going on, so I rely on the clarity of the wiki and the examples given.
 
I simply wasn't sure whether seconds were coded as "s" or "sec" or "seconds", until I read that statement in an earlier posting. TBH I'm blown away that C++ allows such coding of values.

Yes, that is nicely implemented indeed. Since the required information is coded into the types it doesn't need additional memory and, for constants, the compiler is able to do the conversion at compile time. Also, c++20 will add a lot of useful stuff to the chrono namespace. You can also extend the types very easily. The following shows how to define a days and a weeks type and use it to set the period of a periodic timer:

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

PeriodicTimer t1(TCK64);

void onT1(void)
{
    digitalToggleFast(LED_BUILTIN);
}

constexpr unsigned secPerDay = 60 * 60 * 24;
using days  = duration<double, std::ratio<secPerDay, 1>>;      // define a days type
using weeks = duration<double, std::ratio<7 * secPerDay, 1>>;  // weeks type

void setup()
{
    pinMode(LED_BUILTIN, OUTPUT);

    weeks someLongDuration = weeks(2.5);
    someLongDuration += 2*35ms;

    t1.begin(onT1, someLongDuration);  // will toggle the LED every 2.5weeks + 2*35ms, i.e. every 1'512'000'070 ms

void loop(){
}

You find some more information in the UserWiki: https://github.com/TeensyUser/doc/wiki/Durations-Timepoints-and-Clocks

Regarding your questions on the resolution of the various timers here some quick information (T4.x, FCPU = 600Mhz, default prescaler)
Code:
TMR (32bit):         1/150MHz = 6.66ns
PIT and GPT (32bit): 1/24MHz  = 41.6ns (standard) 6.66ns (optional) 
TCK (32bit):         1/600MHz = 1.666ns
TCK64 (64bit):       1/600MHz = 1.666ns
TCK_RTC (64bit):    1/32768Hz = 30.5µs

Hope that helps
 
Thank you @luni once again! I have had some bad experiences recently in a varied range of forums where I have asked questions, so nice to get a friendly reply :)

I saw the page you reference, and I am now thinking that...

seconds led_timeout = 1s * settings_timeout_timer(); // func returns an unsigned int type

and

seconds led_timeout = seconds(settings_timeout_timer());

are two different ways to achieve the same thing, i.e. to convert an unsigned into to a chrono/time type. I am happy that the use of a "seconds" type variable makes our code quite readable.

I tried to find the constructors (remember I am a C++ noob) for OneShotTimer.trigger() to try to understand which "types" are allowed/have been coded but was unsure about what I was finding. In TckChannel.h it appears to take a float, but then I couldn't find the actual code. I can see that the code is advanced even for C++ ! I was just curious to try to understand how it works. Anyway I'll stick to machine code.

Thanks again.
 
Hi @Luni,

Is there a way to readback the time remaining on a single shot timer?

Its an FTM64 timer.
Mat
 
Hi @Luni,
Is there a way to readback the time remaining on a single shot timer?
Its an FTM64 timer.
Mat

Currently not but I can have a look later this weekend. There is no FTM64 did you mean TCK64?
 
Pushed a test version to the RemainingTime branch. Here a usage example:

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

OneShotTimer t1(TCK64);

volatile bool start = true;

void onTimer()  // timer callback function
{
    Serial.println("triggered <--------------");
    start = true;
}

void setup()
{
    t1.begin(onTimer);  // attach callback
}

void loop()
{
    if (start)
    {
        t1.trigger(1.5s);  
        start = false;
    }
    else
    {
        Serial.printf("remainig: %0.3fs\n", t1.getRemainingTime());
        delay(25);
    }
}

Prints:

Code:
remainig: 0.200s
remainig: 0.175s
remainig: 0.150s
remainig: 0.125s
remainig: 0.100s
remainig: 0.075s
remainig: 0.050s
remainig: 0.025s
triggered <--------------
remainig: 1.500s
remainig: 1.475s
remainig: 1.450s
remainig: 1.425s
remainig: 1.400s
remainig: 1.375s
 
@luni:

Nice !!

Would it be better to move the calling of "Serial.println("triggered <--------------");" down into loop(), where the "start" condition is detected, rather than having it called in the onTimer() handler ??

Thanks for your excellent work on providing this capability !!

Mark J Culross
KD5RXT
 
@Luni,

Thaks for the speedy reply and the fine example I was going to say, yes its TCK64 I was using..

Mat




Pushed a test version to the RemainingTime branch. Here a usage example:


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

OneShotTimer t1(TCK64);

volatile bool start = true;

void onTimer()  // timer callback function
{
    Serial.println("triggered <--------------");
    start = true;
}

void setup()
{
    t1.begin(onTimer);  // attach callback
}

void loop()
{
    if (start)
    {
        t1.trigger(1.5s);  
        start = false;
    }
    else
    {
        Serial.printf("remainig: %0.3fs\n", t1.getRemainingTime());
        delay(25);
    }
}

Prints:

Code:
remainig: 0.200s
remainig: 0.175s
remainig: 0.150s
remainig: 0.125s
remainig: 0.100s
remainig: 0.075s
remainig: 0.050s
remainig: 0.025s
triggered <--------------
remainig: 1.500s
remainig: 1.475s
remainig: 1.450s
remainig: 1.425s
remainig: 1.400s
remainig: 1.375s
 
@luni:

Nice !!

Would it be better to move the calling of "Serial.println("triggered <--------------");" down into loop(), where the "start" condition is detected, rather than having it called in the onTimer() handler ??

Thanks for your excellent work on providing this capability !!

Mark J Culross
KD5RXT

TCK timers, IIRC run from [timertool] yield(), so on exit of loop {or delay}. Not on interrupt so basically inline code with loop(), as least in that example.
 
@Luni,
Thaks for the speedy reply and the fine example I was going to say, yes its TCK64 I was using..
Mat

Please test and let me know if it works for you before I push it to the master branch.

Would it be better to move the calling of "Serial.println("triggered <--------------");" down into loop(), where the "start" condition is detected, rather than having it called in the onTimer() handler ??
As defragster mentioned, all TCK timers (TCK, TCK64, TCK_RTC) run from yield. Anyway, I never had issues printing small amounts to Serial from a real timer interrupt as well. After all it just copies the bytes to some buffer which is quickly done. Also, the ARM processors implement interrupt priorities and interrupts with default priorities can be interrupted by system interrupts with higher priority. So, using interrupts is not as time critical as it used to be with ancient 8bit processors.
 
Hi Luni,
Me again with another newbie question.

I am trying to produce an accurate (No drift) 1 second 'Tick' to use in a clock project (wall clock thing). I want to use a periodic timer and planned to use FTM3 as its source, Will this timer be large enough to handle a 1 second count? or is there a better option. I could not find what a PIT timer was, so no clue if thats better.

Thanks in advance for any help /advice.
Mat
 
I am trying to produce an accurate (No drift) 1 second 'Tick' to use in a clock project (wall clock thing).
Whatever timer you use, the drift will always be the drift of the corresponding crystal (IIRC: ~20ppm). If you need less you might be better off with a clock module like this one (https://learn.adafruit.com/adafruit-ds3231-precision-rtc-breakout) which is speced at 2ppm.

The FTM timers are 16bit only. You will get am max period of some 50ms. Why not simply use an intervalTimer for this?

I want to use a periodic timer and planned to use FTM3 as its source, Will this timer be large enough to handle a 1 second count?
No, the FTMs are 16bit, you'll get about 50ms max period (depending on your FCPU setting of course). I'd simply use an IntervalTimer for this.
 
Hi Luni,
Me again with another newbie question.

I am trying to produce an accurate (No drift) 1 second 'Tick' to use in a clock project (wall clock thing). I want to use a periodic timer and planned to use FTM3 as its source, Will this timer be large enough to handle a 1 second count? or is there a better option. I could not find what a PIT timer was, so no clue if thats better.

Thanks in advance for any help /advice.
Mat

Can you tell us your required accuracy.
 
Just getting started with both Teensy and this TeensyTimerTool.

I am trying to create some code to make a quadrature encoder simulator. This would run on Teensy T4.1#1. Teensy T4.1#2 would decode the signals generated from #1.

So on Teensy T4.1#1, I was able to create a periodic timer that passes a parameter to the callback function. It seems the last argument is in the units of microseconds. Is there a way to do this in ns? Ideally the variable would just be a number in ns. I would like the duty factor to be 50%, but the period to be controlled by the passed parameter. This code is only me learning how to use this library.
Code:
#include "TeensyTimerTool.h"

using namespace TeensyTimerTool;

Timer t1(TCK);  // Tick-Timer does not use any hardware timer (20 32bit channels)
Timer t2(TMR1); // First channel on TMR1 aka QUAD timer module. (TMR1 - TMR4, four 16bit channels each)
Timer t3(GPT1); // GPT1 module (one 32bit channel per module)
Timer t4(TMR1); // Second channel on TMR1

// Callbacks ===================================================================================

void a_ns(uint32_t myns)
{
  digitalWriteFast(1, HIGH);
  delayNanoseconds(myns);
  digitalWriteFast(1, LOW);
  t4.trigger( myns/2 );
}

void b_ns(uint32_t myns)
{
  digitalWriteFast(2, HIGH);
  delayNanoseconds(myns);
  digitalWriteFast(2, LOW);
}


void setup() {
  // put your setup code here, to run once:
  for(unsigned pin=1; pin<=2; pin++) pinMode(pin, OUTPUT);

  t1.beginPeriodic( [] { a_ns(500);}, 1);    // this works somewhat!
  t4.beginOneShot( []  { b_ns(500);});       // this is broken

}

void loop() {
  // put your main code here, to run repeatedly:

}
 
Last edited:
Your code is a bit convoluted. The problems you get are probably due to the short period and the relatively (to the calling period) long blocking in the callbacks.

I'd do something like this:

Code:
#include "TeensyTimerTool.h"

using namespace TeensyTimerTool;

PeriodicTimer t1(TMR1);  // the TMRs run at 150MHz

constexpr int A = 1, B = 2;
uint8_t maskA = 0b11001100;
uint8_t maskB = 0b10011001;

void onTimer()
{
    static unsigned pos = 0;
    digitalWriteFast(A, maskA & (1 << pos));
    digitalWriteFast(B, maskB & (1 << pos));
    pos = (pos + 1) % 8;
}

void setup()
{
    for (uint8_t pin : {A, B, LED_BUILTIN})
        pinMode(pin, OUTPUT);

    t1.begin(onTimer, 0.5us);
}

void loop()
{
    digitalToggleFast(LED_BUILTIN);
    delay(250);
}

Which gives a 2 Mcnt/sec quad signal:

Screenshot 2022-05-06 183719.png

(for those short periods it is best to set the TMR prescaler to 1 in defaultConfig.h)

You might also be interested in this library: https://github.com/luni64/EncSim which generates Quad signals with settable frequencies, settable phases, and additional bounce pulses.
 
I don't understand how your code example works just yet. I'm neither a C or C++ wizard, so it makes it hard for me.

For what it was worth, I managed to run the interrupt at 4x and decode the states of A & B in forward and reverse. My code is longer and much uglier than yours, (and could be written more clearly) but at least I fully understand mine. By choosing a 4x rate, it guarantees the phases are correct independent of period. Looking at your code you do something similar, a lot more elegantly.

I used GPT1 and want to use GPT2. Should I change USE_GPT_PIT_150MHz to true in defaultConfig.h? If this change is made, can I enter 0.25us as an argument to beginPeriodic?

Thank your for the reference to EncSim, but if I could smoothly sweep the period by 250ns steps or so, I'd be perfectly happy to use what I have. When I need more sophistication, may migrate to EncSim.
Code:
#include "TeensyTimerTool.h"

using namespace TeensyTimerTool;

// for Teensy 4.1 only

Timer t1(GPT1);

int period;
int count;
volatile bool forward;

#define A 1
#define B 2

// Callbacks

void a_ns( )
{
  //Serial.print("count = ");  Serial.println(count);
  if (count==0) 
  { 
    if (forward) { digitalWriteFast(A, HIGH); digitalWriteFast(B, LOW); }
    else { digitalWriteFast(A, LOW); digitalWriteFast(B, HIGH); }
  }
  if (count==1) 
  { 
    if (forward) { digitalWriteFast(A, HIGH); digitalWriteFast(B, HIGH); }
    else { digitalWriteFast(A, HIGH); digitalWriteFast(B, HIGH); }
  }
  if (count==2)
  {
    if(forward) { digitalWriteFast(A, LOW); digitalWriteFast(B, HIGH); }
    else { digitalWriteFast(A, HIGH); digitalWriteFast(B, LOW); }
  }
  if (count==3)
  {
    digitalWriteFast(A, LOW); digitalWriteFast(B, LOW); 
    // same for both fwd and reverse
  }
  if ((count>3)|(count<0))
  {
    digitalWriteFast(A, LOW);  digitalWriteFast(B, LOW);
    Serial.println("Fatal Error");
  }
  count += 1;
  if (count>3) count = 0;
}


void setup() {
  // put your setup code here, to run once:
  for(unsigned pin=1; pin<=2; pin++) pinMode(pin, OUTPUT);
  
  Serial.begin(9600);
  //while(!Serial) delay(100);
  
  count = 0;
  forward = true;
  t1.beginPeriodic( a_ns, 1);

}

void loop() {
  // put your main code here, to run repeatedly:
  

}
PXL_20220506_164337058_500.jpg
 
I don't understand how your code example works just yet. I'm neither a C or C++ wizard, so it makes it hard for me.
If you tell me where you have problems to understand it I can try to explain. Your code basically does the same but a bit more verbose.

I used GPT1 and want to use GPT2. Should I change USE_GPT_PIT_150MHz to true in defaultConfig.h? If this change is made, can I enter 0.25us as an argument to beginPeriodic?
You can use both GPT1 or GPT2. Setting it to 150MHz will certainly improve the accuracy for high frequencies. Just curious, do you have any special reason why you prefer the GPTs over the (cheaper) TMRs?


..can I enter 0.25us as an argument to beginPeriodic?
Yes, you can use any unit you like (ns, us, ms, _kHz, _MHz...). Without explicitly stating the unit, it defaults to microseconds. Values are taken as floats in any case, so 0.25us is the same as 250ns and so on...

Please note that interrupts are quite expensive. You won't get much faster than about 4 MHz call rate. And this will already use up quite some processor cycles. Just try...
 
I just saw that you are using the depricated Timer API. You should have got a corresponding warning from the compiler!

Instead of
Code:
Timer t1(GPT1);

say
Code:
PeriodicTimer t1(GPT1);

and instead of
Code:
t1.beginPeriodic(...)

say
Code:
t1.begin(...)

The old API uses integers for the periods, this will limit the max frequency to 1MHz!!! The new API supports floats and the time literals (ns, us, ms, s, _Hz, kHz, _MHz)
 
Well thank you for pointing out the old API. That helps a bit. I used only the old API, because that was in your examples. I didn't know any better. MoreTimers.ino is what I started with.

Just made a change and now running at 500 KHz period. And it runs at 1 MHz. Each quadrant is 250ns long. That seems to be the limit. Entering in 0.125us gives the same result as entering 0.25us. However, having a period of 1us for A & B is great. It is good enough for what I need to do.

To answer your question on why use GPT1, because it is 32 bit. As the period gets very long, I may need it. Besides, this Teensy will only run this program, so I can use both GPT timers and it will be fine. Yes, I wouldn't do this on a Teensy that was doing all kinds of other stuff. This Teensy will be the stimulus for a second Teensy. Ultimately, I will create an electronic lead screw for my lathe. I don't think anyone has a project to do this, at least I couldn't find one with a Teensy. Clough42 has one using a TI processor that is currently unavailable, due to chip shortages, so I'm attempting this using a Teensy 4.1.

To change the period what is the correct way to do this? Is there a set function, or just begin again? Does your wiki explain this?
 
Last edited:
I used only the old API, because that was in your examples
Ups, thought I had changed them all. Thanks for spotting this.

You change the period by t1.setPeriod(...)

Ultimately, I will create an electronic lead screw for my lathe.
Great, hope you show the progress here. At least I'd be very interested.

Long time ago I was working on something similar. https://www.youtube.com/watch?v=ZLVXQfjfS6Q The board in the video shows a T3.2 which read out the x/y linear encoders from my lathe. The board had an ATMega 328 as 'coprocessor' which was running GRBL to control the lathe. The T3.2 had a WebServer running which generated the GUI so, one could use anything which runs a Browser as display. Unfortunately I got lost in details and never finished the project... But the stepper is still mounted to my leadscrew :)
 
Back
Top