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

Thread: Encoder

  1. #1

    Encoder

    Hi to all, I'm new...
    I want to ask if anyone have connected a Teensy 3.5 to and Encoder and calculate the max frequency teensy 3.5 is able to read.

    Use the encoder.h library is the best performance choice?
    Use the arduino-compiler is the best performance choice?

    What's the relationship between clock frequency processor and encoder frequency max count?

  2. #2
    Senior Member
    Join Date
    Jan 2013
    Posts
    843
    No, Encoder is not the fastest. Teensy 3.5 has two hardware decoders that can reliably do several MHz. There is some discussion in this thread:
    https://forum.pjrc.com/threads/37747...upgrade-to-3-5

    The latest Teensyduino beta has new and much faster pin interrupt dispatching, which does improve performance of Encoder. Putting a number on how fast it can count is tricky, since it will start loosing counts if there is a library that disables interrupts for too long. Under ideal circumstances, the limit is probably around 300'000 counts per second. If there is a library that disables interrupts, that limit can be far lower.

    I have a DMA-based encoder library that can do more than 1MHz, which I plan to release soon.

    Teensyduino uses GCC. Although the version is a bit old at this point, don't expect better performance from a different compiler.

  3. #3
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    460
    If you need to be really fast you can use the integrated hardware quadrature counters. Tlb did all the required register settings and overflow counting. See this thread for details and code: https://forum.pjrc.com/threads/26803...for-Teensy-3-x

  4. #4
    Thanks so much for answering.
    I need to read just 170 kHz...I just realizing a step-dir --> Analog -10/+10V servo controller with pid.
    So if limit is so high for my application (300 kHz) I think encoder library is enough fast and I have enough time for pid control...of course I think is better to don't use serial interface during pid and encoder reading


    Use an interrupt to read (while encoder are in use) the step can alterate encoder count?
    Last edited by Alessandro; 10-27-2016 at 10:23 AM.

  5. #5
    Senior Member
    Join Date
    Jan 2013
    Posts
    843
    Reading the encoder count in an ISR is fine.

    At 170kHz, you want to increase the pin interrupt priority, so that you don't loose encoder steps. By default, most Teensy interrupt priorities are 128. Interrupts at the same priority level can't interrupt each other.

    There isn't really a pin interrupt, interrupts are for a complete IO port. A pin to IO port map is here (the native column):
    https://forum.pjrc.com/threads/34808...l=1#post106291

    The priority of the port interrupt can be set with (use IRQ_PORTA, IRQ_PORTB, IRQ_PORTC, IRQ_PORTD, IRQ_PORTE depending on the port(s)):
    Code:
    NVIC_SET_PRIORITY(IRQ_PORTA, 32);

  6. #6
    Senior Member
    Join Date
    Apr 2013
    Posts
    1,885
    The Teensy Serial port 1 uses a hardware FIFO so you can handle short (16 byte?) serial messages without interrupts causing to much trouble and just wait till the number of bytes is enough to pull out and parse.

  7. #7
    Great explanation!
    This evening I'll try all...and of course I'll update what's happen!

  8. #8
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    460
    170 kHz shouldn't be a big issue. I'm using a T3.1 system which easily does the following tasks in parallel:

    • Reading 3 encoders at about 200kHz
    • Managing a web socket connection and send out encoder data over the connection to a display (web browser on a tablet)
    • Running a web server to serve the html for the display


    I'm using the system more or less daily on my lathe and did never observe any lost steps so far. (If somebody is interested: https://www.youtube.com/watch?v=WNYi6aPL8Rg and here a test of the hardware counters running at about 800kHz: https://www.youtube.com/watch?v=ZLVXQfjfS6Q)

  9. #9
    Junior Member
    Join Date
    May 2017
    Posts
    5
    Hi luni, would you be willing to share your code or which libraries you used for the encoders in your project?
    Thanks.

  10. #10
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    460
    Yes, sure. I'll post it in the evening. I assume you need it for the 6-motors @120 rpm project you introduced in your other post https://forum.pjrc.com/threads/43812...-motor-control? If so, the encoder readout should work without problem and will not generate significant load on a T3.6.

  11. #11
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    460
    Rod,

    here my code. Opposed to the standard encoder library I don't use port interrupts for counting the quadrature signals but a fixed sampling frequency.

    Reason:
    My main application is to read out high resolution encoders on my lathe. If the machine stops "near an encoder edge" vibrations can generate a high frequency up/down counting signal which would lead to a very high number of interrupts. Using a fixed sampling frequency is said to be more robust in these situations. Algorithm and discussion (german) can be found here https://www.mikrocontroller.net/articles/Drehgeber

    In case you want to try it, I extracted my encoder code into a library and did a small example with 6 encoders (attached). Just out of curiosity I tested the performance with a T3.6 @240Mhz. I connected an encoder (Heidenhain ROD426-1000) and tried to rotate it by hand to get about 10kHz pulse frequency which roughly corresponds to your 130rpm / 4096 counts/rev. Sampling frequency was 33kHz.

    The pictures show the A/B signal (trace 2/3) and the time spent in the interrupt (trace 1).

    Click image for larger version. 

Name:	encoder1.PNG 
Views:	93 
Size:	31.3 KB 
ID:	10533


    Click image for larger version. 

Name:	encoder2.PNG 
Views:	80 
Size:	17.3 KB 
ID:	10534

    Result:
    • reading out 6 encoders requires a total time of about 0.8Ás. At 30 kHz sampling rate this corresponds to a processor load of 2.4%.
    • 6 encoders with a required count rate of 200kHz would need a sampling frequency of at least 400kHz. This would lead to a processor load of about 30%


    Would be interesting to compare to performance data of the standard encoder lib.

    Usage:

    Code:
    #include "AltEncoder.h"
    
    using namespace AltEncoder;
    
    // Define a list of as much encoders you need
    // Parameters are pin numbers for 
    // phase A and phase B
    
    Encoder* encoderList[] =
    {//            A  B
      new Encoder( 3, 4),
      new Encoder( 5, 6),
      new Encoder( 7, 8),
      new Encoder( 9,10),
      new Encoder(11,12),
      new Encoder(14,15),
      nullptr
    };
    
    void setup() 
    {
      Serial.begin(0);
      Controller::begin(encoderList, 30/*Ás*/);   // choose a sampling period which is at least a factor of two smaller than the shortest time between two encoder signal edges. 
    }                                            
    void loop() 
    {
      for(int i = 0; i< 6; i++) 
      {
        Serial.println(encoderList[i]->counter);
      }
      Serial.println();
    
      delay(100);
    }
    Attached Files Attached Files
    Last edited by luni; 05-08-2017 at 09:42 PM.

  12. #12
    Junior Member
    Join Date
    May 2017
    Posts
    5
    I appreciate you sharing your code and looking into my problem, I'll have the teensy on wednesday and will update my thread with the results with both libraries as soon as possible.

    I was wondering: how did you measure or estimate the 0.8Ás time required to sample the encoder signals?

  13. #13
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    460
    I just set a pin to HIGH when I enter the ISR and back to LOW when I leave it. For the actual measurement I use a cheap logic analyzer (traces shown in the post). This of course does not measure the time required for e.g. pushing/popping registers and it does not take into account that the optimizer might shuffle the execution order (pin might be set HIGH some time after the code enters the ISR). But for that kind of performance estimations it should be accurate enough.

  14. #14
    Junior Member
    Join Date
    May 2017
    Posts
    5
    Your code worked perfectly to take all of the encoders in and was easy to understand, Thank you.

Posting Permissions

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