Forum Rule: Always post complete source code & details to reproduce any issue!
Page 10 of 10 FirstFirst ... 8 9 10
Results 226 to 244 of 244

Thread: TeensyTimerTool

  1. #226
    Senior Member
    Join Date
    Jan 2015
    Location
    France
    Posts
    135
    Thank you !

  2. #227
    Banned
    Join Date
    Oct 2020
    Posts
    6
    Great Tool, Luni!

  3. #228
    I'm curious. I've been trying to encapsulate some timers in a class, and I can't seem to get the tick timers to automatically generate from the next available channel. In other words, every instance of my class overwrites the first TCK timer channel.

    I'm wondering if this is a) my mistake, and there is a simple way around it, or b) a limitation of the TeensyTimerTool library?

    For the moment I'm instantiating 8 timers (or however many I might need) before I create any objects, and then pass the appropriate OneShotTimer to the class instances by reference.

    Wondering if one of you pros could give me a little guidance with this one. Just getting started, but I'll post the code:

    Code:
    #pragma once
    
    #include "TeensyTimerTool.h"
    using namespace TeensyTimerTool;
    
    class motor
    {
        public:
          int8_t step_pin;
          int8_t dir_pin;
          int32_t position_steps;
      
          double delay_usec;
          double pulsewidth_usec;
    
          bool stopped;
    
          TeensyTimerTool::OneShotTimer tmr;   
    
         motor(int8_t _step_pin, int8_t _dir_pin, TeensyTimerTool::OneShotTimer &_tmrx)
          : tmr(_tmrx)
         {
             this->step_pin = _step_pin;
             this->dir_pin = _dir_pin;
             pulsewidth_usec = 2;    //Teensystep default = 5us
             delay_usec = 1; 
             stopped = true;    
              
             pinMode(step_pin, OUTPUT); digitalWrite(step_pin, HIGH);
             pinMode(dir_pin, OUTPUT); digitalWrite(dir_pin, HIGH); 
    
             setSpeed(10);
    
             tmr.begin([this] { this->step_callback();} ); 
             tmr.trigger( 10000 ); 
      
         }
    
          void start() {stopped = false; setSpeed(1);}
          void setSpeed(double stps_per_sec) { delay_usec = (1000000 / stps_per_sec) - pulsewidth_usec; }
          void step_callback() 
          {
              if (!stopped)
              {
                  if (!digitalRead(step_pin)) {
                    position_steps++; 
                      tmr.trigger(pulsewidth_usec);
                  }
                  else {
                      tmr.trigger(delay_usec);
                  }
                  digitalWrite(step_pin, !digitalRead(step_pin));
              }
          }
          double steps_per_sec () { return 1000000 / (pulsewidth_usec + delay_usec); }
                
    };

    Before someone recommends the TeensyStep library (which is fantastic), I should say that I am trying to control 8 motors simultaneously by joint angle, updating position on the fly and RotateControl with some sort of PID loop seems to be the only way to accomplish this task, but you cannot use overrideSpeed for individual motors in a controller, and you can only have 4 RotateControllers at a time due to the number of timers on the Teensy 3.6. For this reason, I'm trying to hack something together with TCK timers on a Teensy 4.1.
    Last edited by drewhamiltonasdf; 11-14-2020 at 10:56 PM.

  4. #229
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,309
    I'm curious. I've been trying to encapsulate some timers in a class, and I can't seem to get the tick timers to automatically generate from the next available channel. In other words, every instance of my class overwrites the first TCK timer channel.
    I can have a look but I need your calling code and some information how to identify your issue.

    Here already a few remarks to your code:

    • Any reason why you define your timers in the sketch and then pass them to your motor objects? Might be cleaner to directly add them as member variables in your class.
    • You do a lot of hardware related stuff in the constructor. If you have your motors as global objects (which is pretty common in the Arduino world) the constructors may be called early in the startup process. It can be that Teensyduino didn't initialize everything yet when the constructor is called. If you need to talk to hardware It is always better to introduce a begin() function which you'd call from setup() or any other convenient place.

  5. #230
    Quote Originally Posted by luni View Post
    • Any reason why you define your timers in the sketch and then pass them to your motor objects? Might be cleaner to directly add them as member variables in your class.
    • You do a lot of hardware related stuff in the constructor. If you have your motors as global objects (which is pretty common in the Arduino world) the constructors may be called early in the startup process. It can be that Teensyduino didn't initialize everything yet when the constructor is called. If you need to talk to hardware It is always better to introduce a begin() function which you'd call from setup() or any other convenient place.
    • What I intended to say is that I couldn't get the timers to initialize on different channels if I added them as member variables. Each instance of the class would just use the first channel of the TCK timer, whereas if I define all the timers in the main INO file, the TeensyTimerTool library seems to keep track of available channels. Perhaps I'm missing something.
    • Agreed. I'll clean this up. A begin() function is a great idea and I'll give that a whirl, but I'm still not sure how I can get around defining my timers in the main sketch.

    Hope that makes sense.

    As a side note, and this is probably off-topic here, I've been trying to get similar timing using this tool as you've achieved with the TeensyStep library. Even with all but one "stepper" timer commented out, and all extraneous code/delays etc kept to a minimum, I can see just the slightest bit of jitter on my oscilloscope whereas your TeensyStep library produces absolutely still and perfectly timed steps. I've tried this with all the different varieties of timers available-- I've tried it on the Teensy 3.6, 4.0 and 4.1-- and I've spent countless idle hours looking at your library and trying to piece together this black magic, but your programming is way too sophisticated for me to make heads or tails. For example, you declare an object:

    Code:
    namespace TeensyStep
    {
        template <typename Accelerator, typename TimerField>
        class RotateControlBase : public TeensyStep::MotorControlBase<TimerField>
            void doRotate(int N, float speedFactor = 1.0);
            void accTimerISR();
    
            Accelerator accelerator;
    And I cannot for the life of me figure out where or how this is defined as a class and how that loops back in with the LinRotAccelerator and LinStepAccelerators.

    To be clear, this is a failing of mine, not yours. Both libraries accomplish their intended tasks extremely well, though I am curious to here your response to my initial comment.

    People like myself rely on combing the internet for crumbs left out by coders like you and Paul Stoffregen.

  6. #231
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,309
    What I intended to say is that I couldn't get the timers to initialize on different channels if I added them as member variables. Each instance of the class would just use the first channel of the TCK timer, whereas if I define all the timers in the main INO file, the TeensyTimerTool library seems to keep track of available channels. Perhaps I'm missing something.
    I'd love to help you but, as I wrote in my last post, I really need to see your sketch. Ideally some minimal version which I can compile and which shows the behaviour you describe. Without seeing your sketch this is all just guess work. Together with the sketch please also describe how you determine that only one TCK channel is used.

  7. #232
    Junior Member
    Join Date
    Mar 2020
    Location
    Bristrol - UK
    Posts
    7
    Hello all,
    Firstly I am still fairly green to C++ (and the Teensy family) but I will try and explain a problem I have encountered with the TeensyTimerTool. I have version 0.3.2 currently installed (I recently did an update of a number of libraries).

    Earlier this year I created a project called "The G.P.S.CLOCK" which I posted about in the blog project submission using an older version of this fab tool. The program behind this complied without error, however since updating the TimerTool revision the program no longer compiles with the following error.:

    ---------------------

    PROJECT: In function 'void filterfield()':

    PROJECT:263: error: reference to 'hours' is ambiguous

    hours = (((raw_nmea[counter+1] - '0') * 10) + (raw_nmea[counter+2] - '0')); // Extract the Hours

    ^

    D:\MY DOCUMENTS\ARDUINO\PROJECT\PROJECT.ino:70:15: note: candidates are: signed char hours

    signed char hours = 0; // HOUR STORAGE

    ^

    In file included from D:\MY DOCUMENTS\Arduino\libraries\TeensyTimerTool\src/frequency.h:27:0,

    from D:\MY DOCUMENTS\Arduino\libraries\TeensyTimerTool\src/baseTimer.h:9,

    from D:\MY DOCUMENTS\Arduino\libraries\TeensyTimerTool\src/timer.h:4,

    from D:\MY DOCUMENTS\Arduino\libraries\TeensyTimerTool\src/TeensyTimerTool.h:4,

    from D:\MY DOCUMENTS\ARDUINO\PROJECT\PROJECT.ino:14:

    d:\program files\arduino\hardware\tools\arm\arm-none-eabi\include\c++\5.4.1\chrono:542:45: note: typedef struct std::chrono::duration<long long int, std::ratio<3600ll> > std::chrono::hours

    typedef duration<int64_t, ratio<3600>> hours;

    ^

    ---------------
    I use the following global variables:

    signed char hours = 0; // HOUR STORAGE
    unsigned char minutes = 0; // MINUTES STORAGE
    unsigned char days = 0; // Day of Week storage
    unsigned char seconds = 0; // Seconds of the Minute


    All of which are now listing similar errors to the one listed about. Also I noticed that the words "hours", "minutes", "days" and "seconds" have also changed to an orange colour within the IDE.

    Any help or advise as to why/what has changed would be most welcome - This is the time line of my code. "Production" release was complied successfully on the 12th Aug 2020. The update happened on the 19th Nov and now things no longer compile

    Kindest regards
    Mat

  8. #233
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,125
    Quote Originally Posted by MatA View Post
    Hello all,
    Firstly I am still fairly green to C++ (and the Teensy family) but I will try and explain a problem I have encountered with the TeensyTimerTool. I have version 0.3.2 currently installed (I recently did an update of a number of libraries).

    Earlier this year I created a project called "The G.P.S.CLOCK" which I posted about in the blog project submission using an older version of this fab tool. The program behind this complied without error, however since updating the TimerTool revision the program no longer compiles with the following error.:

    ...
    Just a quess because of a post that passed by ...

    One update to the library involved allowing times specified in words ... including hours

    Seems that is indicated with this line :: typedef duration<int64_t, ratio<3600>> hours;

    Change those variable names causing errors to be unique in some way : myHours or hoursGPS ...

  9. #234
    Junior Member
    Join Date
    Mar 2020
    Location
    Bristrol - UK
    Posts
    7
    Hi, Thanks for the fast reply! Okay thanks for the advise. It was one of the approaches I was looking at but before I spend time doing this I wanted to check it was not a error with the Teensy tool as I said - my code used to work, now it doesn't

    Kindest and stay safe!
    Mat

  10. #235
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,309
    Actually 'hours' is one of the functions from the new (since c++11) std::chrono namespace which deals with handling time. Since v3.0 the TeensyTimerTool supports this namespace by default. If you don't like it you can of course opt out in the config file (see #223 of this thread). Looks like I forgot to add the opt out information to the WIKI.

    However, since you are doing clocks you might actually find std::chrono quite useful. You can use it to do things like e.g.
    Code:
    t1.begin(callback, 250ms);
    t1.begin(callback, 4us + 2ms);
    t1.begin(callback, 1h);
    t1.begin(callback, 60min);

    In case you are interested, here some general infos about how to use the new types and how to define std::chrono clocks. https://github.com/TeensyUser/doc/wi...nts-and-clocks

  11. #236
    Junior Member
    Join Date
    Mar 2020
    Location
    Bristrol - UK
    Posts
    7
    I have renamed my variables throughout my code. Now when I complete I get this new error. Sorry to ask for advise, as I said I am quite new to C++ and the Teensy.
    Thanks in advance for any advise.

    Mat


    New error:
    ---------
    Arduino: 1.8.13 (Windows 10), TD: 1.53, Board: "Teensy LC, Serial, 48 MHz, Smallest Code, US English"


    In file included from D:\Program Files\ARDUINO\hardware\teensy\avr\libraries\Teensy TimerTool\src\config.cpp:80:0:

    D:\Program Files\ARDUINO\hardware\teensy\avr\libraries\Teensy TimerTool\src\Teensy/TCK/TCK.h: In instantiation of 'static TeensyTimerTool::ITimerChannel* TeensyTimerTool::TCK_t::getTimer() [with counterType = long unsigned int]':

    D:\Program Files\ARDUINO\hardware\teensy\avr\libraries\Teensy TimerTool\src\config.cpp:84:44: required from here

    D:\Program Files\ARDUINO\hardware\teensy\avr\libraries\Teensy TimerTool\src\Teensy/TCK/TCK.h:51:32: error: invalid new-expression of abstract class type 'TeensyTimerTool::TckChannel<long unsigned int>'

    channels[chNr] = new TckChannel<counterType>();

    ^

    In file included from D:\Program Files\ARDUINO\hardware\teensy\avr\libraries\Teensy TimerTool\src\Teensy/TCK/TCK.h:4:0,

    from D:\Program Files\ARDUINO\hardware\teensy\avr\libraries\Teensy TimerTool\src\config.cpp:80:

    D:\Program Files\ARDUINO\hardware\teensy\avr\libraries\Teensy TimerTool\src\Teensy/TCK/TckChannel.h:245:11: note: because the following virtual functions are pure within 'TeensyTimerTool::TckChannel<long unsigned int>':

    class TckChannel : public TckChannelBase

    ^

    In file included from D:\Program Files\ARDUINO\hardware\teensy\avr\libraries\Teensy TimerTool\src\Teensy/TCK/TckChannelBase.h:3:0,

    from D:\Program Files\ARDUINO\hardware\teensy\avr\libraries\Teensy TimerTool\src\Teensy/TCK/TckChannel.h:5,

    from D:\Program Files\ARDUINO\hardware\teensy\avr\libraries\Teensy TimerTool\src\Teensy/TCK/TCK.h:4,

    from D:\Program Files\ARDUINO\hardware\teensy\avr\libraries\Teensy TimerTool\src\config.cpp:80:

    d:\program files\arduino\hardware\teensy\avr\libraries\teensy timertool\src\itimerchannel.h:22:23: note: virtual float TeensyTimerTool::ITimerChannel::getMaxPeriod() const

    virtual float getMaxPeriod() const = 0;

    ^
    ----------------

  12. #237
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,309
    That looks like a bug. Sorry, I don't use the LC much. Probably something LC specific.
    I'll have a look later today

  13. #238
    Junior Member
    Join Date
    Mar 2020
    Location
    Bristrol - UK
    Posts
    7
    Thanks Luni!
    The LC was just spot on for the G.P.S.CLOCK but i would like to stick with that for now and support the code if needed. Going forward the next project I am starting to work on/look at is on the 3.5!
    hopefully if it is a bug its a simple one to fix.
    Also thanks for the information on:

    t1.begin(callback, 250ms);
    t1.begin(callback, 4us + 2ms);
    t1.begin(callback, 1h);
    t1.begin(callback, 60min);

    and the link! I will go into learning mode

    Mat

  14. #239
    Junior Member
    Join Date
    Mar 2020
    Location
    Bristrol - UK
    Posts
    7
    Hi Luni,
    Just as a bit of a FYI.. My code compiles perfectly on the 3.5 but errors on the LC. I hope this supports the bug theory.

  15. #240
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,309
    @MatA: Can you give the current version on GitHub a try (need to download from the master branch, there is no release yet)

    Tested on a LC with this code, which compiles and blinks now:
    Code:
    PeriodicTimer t1(TCK);
    
    void setup()
    {
      pinMode(LED_BUILTIN, OUTPUT);
      t1.begin([] { digitalToggleFast(LED_BUILTIN); }, 250ms);
    }
    
    void loop(){
    }

  16. #241
    Junior Member
    Join Date
    Mar 2020
    Location
    Bristrol - UK
    Posts
    7
    @Luni: Downloaded the Master branch version and I am happy to report that this release has fixed the issue I reported 11:48 on the 22nd Nov.
    In conjunction with the rename of my variables I can fully compile the GPS clock code again. Thanks for fixing this so quick.

    Kindest and stay safe

    Mat

  17. #242
    Member
    Join Date
    Jun 2015
    Location
    Cambridge, UK
    Posts
    28
    Can someone please confirm that if using this library, then the "using namespace" is required?

    Code:
    #include "TeensyTimerTool.h"
    using namespace TeensyTimerTool;
    What is the impact of missing out the "using namespace".

    Some time ago I did read somewhere in this thread, but the penny hasn't dropped :-(

    Also, when I was helping a friend use this library to implement our own joystick switch debounce (on a Teensy LC), we had problems with switches not being detected. The code had "tight" while loops. On a hunch we added "delay(1)" in the while loops and the code now worked. I sort of recall reading that TeensyTimerTool uses yield? To be honest I was surprised that it was necessary. I know that the Teensy LC is less well endowed with timers, as compared to the 3 series. Do the 3 series still need to yield?

    Question is, what do I need to replace "delay(1)" with to allow TeensyTimerTool to work on the Teensy LC? In this case the added 1ms isn't too critical, but I suspect that there is a correct library call to do the same thing.

  18. #243
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,309
    Quote Originally Posted by badsector View Post
    Can someone please confirm that if using this library, then the "using namespace" is required?

    Code:
    #include "TeensyTimerTool.h"
    using namespace TeensyTimerTool;
    What is the impact of missing out the "using namespace".

    Namespaces are a c++ concept to avoid clashes of symbol names (variables, functions etc) between libraries and user code. E.g. the teensy timer tool uses a class called "Timer". It is very likely that other libraries or the user code also use some "Timer". If all of those libraries and/or the user code use the standard namespace, the linker has no chance to find out which one you want to use. One can easily prevent this, so called namespace pollution, by declaring all symbols within a dedicated namespace. E.g., the TeensyTimerTool declares all symbols in the namespace TeensyTimerTool. -> The full name of the TeensyTimerTool Timer class is:

    Code:
    #include "TeensyTimerTool.h"
    
    TeensyTimerTool::Timer t1;
    If you now have another library also declaring a Timer class but in the namespace "SomeOtherNamespace" you can distinguish them by

    Code:
    #include "TeensyTimerTool.h"
    #include "someOtherLib"
    
    TeensyTimerTool::Timer t1;
    SomeOtherNamespace:: Timer t2;
    Instead of always writing the fully qualified names you can tell the compiler to import all symbols from a namespace by:
    Code:
    #include "TeensyTimerTool.h"
    
    using namespace TeensyTimerTool; // import all symbols from the TeensyTimerTool namespace
    
    Timer t1;   // this is now a shorthand for TeeensyTimerTool::Timer t1;
    So, you don't need the "using namespace TeensyTimerTool" at all if you instead fully qualify all names (which, however, quickly gets tedious).


    Also, when I was helping a friend use this library to implement our own joystick switch debounce (on a Teensy LC), we had problems with switches not being detected. The code had "tight" while loops. On a hunch we added "delay(1)" in the while loops and the code now worked. I sort of recall reading that TeensyTimerTool uses yield? To be honest I was surprised that it was necessary. I know that the Teensy LC is less well endowed with timers, as compared to the 3 series. Do the 3 series still need to yield?
    The TTT uses hardware based timers (GPT, PIT, FTM, TMR...) and/or purely software based timers (TCK). Actually, I didn't bother to implement a hardware timer for the LC. So, for the LC only the TCK timers work (you can always use IntervalTimer if you need a hardware timer for the LC). The T3.x have 4 IntervalTimers and the TTT provides access to their hardware FTM timers. (Here the corresponding chapter of the documentation: https://github.com/luni64/TeensyTime...pported-Timers)

    The software timers can only work if their tick() function is called as often as possible. To make this easier for the user the TTT injects some code into the yield call stack which automatically calls the tick() function from yield() in the background. (You can change that behaviour in the config file). If you need to have some tight loop without calling yield(), or delay() the TCK timers can't work.

    Question is, what do I need to replace "delay(1)" with to allow TeensyTimerTool to work on the Teensy LC? In this case the added 1ms isn't too critical, but I suspect that there is a correct library call to do the same thing.
    Replacing it by "yield()" should work and doesn't eat up as much processing time as delay(1);

    Hope that helps
    Last edited by luni; 12-10-2020 at 06:53 PM.

  19. #244
    Member
    Join Date
    Jun 2015
    Location
    Cambridge, UK
    Posts
    28
    Hi luni, much appreciate you answering my questions.

    I am a C++ noob, so I appreciate your explanation of "namespace". I had no idea that you could use multiple libraries whose name(?) is the same. Apologies I am not 100% on the correct C++ terminology.

Posting Permissions

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