Forum Rule: Always post complete source code & details to reproduce any issue!
Page 2 of 2 FirstFirst 1 2
Results 26 to 43 of 43

Thread: Teensy 4.x H/W Quadrature Encoder Library

  1. #26
    I am using this library, and it works well.

    In my application, I am reading a quad encoder feedback from an electric motor. Since the encoder is naturally a differential measurement, it starts at zero on power up. However, I need it to start at some non zero quantity on startup.

    Here is my setup:

    const int c_Steering_Angle_Rev_Count = 42000;

    //Encoder Setup
    myEnc1.setInitConfig(); //
    myEnc1.EncConfig.revolutionCountCondition = ENABLE;
    myEnc1.EncConfig.enableModuloCountMode = ENABLE;
    myEnc1.EncConfig.positionModulusValue = c_Steering_Angle_Rev_Count;
    // with above settings count rev every 20 ticks
    // if myEnc1.EncConfig.revolutionCountCondition = ENABLE;
    // is not defined or set to DISABLE, the position is zeroed every
    // 20 counts, if enabled revolution counter is incremented when
    // phaseA ahead of phaseB, and decrements from 65535 when reversed.
    myEnc1.EncConfig.positionInitialValue = 0;
    myEnc1.EncConfig.filterCount = 0;
    myEnc1.EncConfig.filterSamplePeriod = 6;
    myEnc1.init();



    I have an external Analog rotary potentiometer to use as an absolute position reference. So, I would like to read the Analog position - convert it to a number of revolutions and position counts, then set the appropriate registers.

    So, I can set the positionInitialValue to the converted position counts,
    myEnc1.EncConfig.positionInitialValue = reset_value;

    But, how can I set the revolution counter to a value? I can't seem to find a function to do this. But, I'm also dumb. So there's that.

  2. #27
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    6,967
    In my application, I am reading a quad encoder feedback from an electric motor. Since the encoder is naturally a differential measurement, it starts at zero on power up. However, I need it to start at some non zero quantity on startup.
    Setting the myEnc1.EncConfig.positionInitialValue sets the starting value for the counter so instead of 0 it will be set to your reset_value.

    how can I set the revolution counter to a value
    The actual revolution counter can not be set by the user. That is an internal counter used the by IMXRT1062 itself. By calling:
    Code:
      myEnc2.EncConfig.positionMatchMode = ENABLE;
      myEnc2.EncConfig.positionCompareValue = 200;
    automatically resets when the internal counter hits 200.

    Code:
     mCurPosValue = myEnc1.read();
    and the subsequent print of mCurPosValue will give you the counts.

    So I am not entirely sure what you want to do with setting revolution counter?

  3. #28
    I have a motor with 42,000 counts per revolution. Lock to lock position on the motor is 5 turns, or 5 x 42,000 counts = 210,000 total counts. I need to know the absolute position when initially powered on - it can theoretically be located anywhere in the range of the 5 turns on powerup. So, I have an external analog rotary potentiometer input that I can use as an absolute position reference. So I was thinking of reading the absolute position reference, converting it to absolute counts, then setting the revolution counter accordingly. Sounds like that can't happen.

    I could turn off the modulo counter, but then I would run out of resolution on the counter as it is only valid to 65,536, which is only slightly more than one revolution? Is there a way to cast the counter to a long? Or some easier way to accomplish an absolute position counter up to 210,000 counts?

  4. #29
    Junior Member
    Join Date
    Apr 2020
    Posts
    1
    Quote Originally Posted by Frank_and_Beans View Post
    I have a motor with 42,000 counts per revolution. Lock to lock position on the motor is 5 turns, or 5 x 42,000 counts = 210,000 total counts. I need to know the absolute position when initially powered on - it can theoretically be located anywhere in the range of the 5 turns on powerup. So, I have an external analog rotary potentiometer input that I can use as an absolute position reference. So I was thinking of reading the absolute position reference, converting it to absolute counts, then setting the revolution counter accordingly. Sounds like that can't happen.

    I could turn off the modulo counter, but then I would run out of resolution on the counter as it is only valid to 65,536, which is only slightly more than one revolution? Is there a way to cast the counter to a long? Or some easier way to accomplish an absolute position counter up to 210,000 counts?
    pretty sure this is a 32 bit hw encoder? but you use the analog to know the position, counts are not for absolute positioning.... they're good for PID and moving the motor at specific velocity or acceleration.... you can convert it to move X distance but from what reference point will always be unknown unless you "home" the motor to a known location using a trigger.. switch or IR sensor, it's unreliable even if you could because you assume that the motor wasn't manually moved when the system was off. if you already have the analog position with a Potentiometer, you do not need counts to know the position, you already know it. you map the potentiometer values to degrees.... 0 being center, + 180 all the way left, -180 all the way right right. 0 could be 2.5v, 0v +180, 5v -180... however you want to do it.....

  5. #30
    Junior Member
    Join Date
    Dec 2020
    Posts
    3
    Hello everyone, I'm new here.
    I'm just now testing your QuadEncoder library with SimpleEncoder example,
    but compilinig it gives me this error:
    C:\Users\...\Teensy-4.x-Quad-Encoder-Library\QuadEncoder.cpp:39:76: error: invalid application of 'sizeof' to incomplete type 'const QuadEncoder::ENC_Hardware_t []'
    const uint8_t QuadEncoder::_hardware_count = (sizeof(QuadEncoder::hardware)/sizeof(QuadEncoder::hardware[0]));

    Any guess? Thank you

  6. #31
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    6,967
    Quote Originally Posted by crk View Post
    Hello everyone, I'm new here.
    I'm just now testing your QuadEncoder library with SimpleEncoder example,
    but compilinig it gives me this error:
    C:\Users\...\Teensy-4.x-Quad-Encoder-Library\QuadEncoder.cpp:39:76: error: invalid application of 'sizeof' to incomplete type 'const QuadEncoder::ENC_Hardware_t []'
    const uint8_t QuadEncoder::_hardware_count = (sizeof(QuadEncoder::hardware)/sizeof(QuadEncoder::hardware[0]));

    Any guess? Thank you
    I just compiled the SimpleEncoder sketch on the T4.0 and the T4.1 and didn't receive any error messages from the library.

    Right now I am using Arduino 1.8.13 with the Teensyduino 1.53- beta5. So really need a bit more info on your config and processor you are using.

  7. #32
    Junior Member
    Join Date
    Dec 2020
    Posts
    3
    Quote Originally Posted by mjs513 View Post
    I just compiled the SimpleEncoder sketch on the T4.0 and the T4.1 and didn't receive any error messages from the library.

    Right now I am using Arduino 1.8.13 with the Teensyduino 1.53- beta5. So really need a bit more info on your config and processor you are using.
    Arduino 1.8.10 and Teensyduino 1.48, are there any significant differences?

  8. #33
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    6,967
    Maybe not with Arduino 1.8.10 but definitely between Teensyduino versions. I just tested the sketch with 1.8.10 with TD 1.50 and didn't receive a compile error. So would recommend updating - besides a lot of things have been fixed and improved on since 1.48

  9. #34
    Junior Member
    Join Date
    Dec 2020
    Posts
    3
    I had also to update Arduino to 1.8.13 because Teensyduino 1.53 does not support 1.8.10,
    now it works with no compiling errors!
    Also the manual update of imxrt.h is not needed anymore.
    Thank you

  10. #35
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    6,967
    Quote Originally Posted by crk View Post
    I had also to update Arduino to 1.8.13 because Teensyduino 1.53 does not support 1.8.10,
    now it works with no compiling errors!
    Also the manual update of imxrt.h is not needed anymore.
    Thank you
    Great that is working and yep no more manual updates

  11. #36
    Junior Member
    Join Date
    Feb 2017
    Posts
    11
    Hello, and thank you for the great library. Not sure if it si proper conduct to post on an older thread, but it looks like it has happened twice before and fairly recently.

    I am implementing a design with three DC motors with encoders running a pretty fast PID loop. The encoders are on the following pins:
    #define XENC_CHANNEL 1 //Encoder Channel
    #define XENC_A 0 //Encoder Phase A
    #define XENC_B 1 //Encoder Phase B
    #define YENC_CHANNEL 2 //Encoder Channel
    #define YENC_A 30 //Encoder Phase A
    #define YENC_B 31 //Encoder Phase B
    #define ZENC_CHANNEL 3 //Encoder Channel
    #define ZENC_A 4 //Encoder Phase A
    #define ZENC_B 36 //Encoder Phase B

    And the encoders are starting with the following code:
    _motor_encoder(enc_channel, enc_a, enc_b, 0)

    _motor_encoder.setInitConfig(); //Loads default configuration for the encoder channel
    _motor_encoder.EncConfig.positionInitialValue = 00;
    _motor_encoder.init(); //Initializers the encoder for the channel selected

    We read them every millisecond.

    We currently have two problems:
    1. The encoder for Y always works, but it seems that only the X or Z can function at the same time. I saw the warning about not using pin 0, 5 and/or 37 at the same time, but it appears we have stumbled upon another combination.

    2. The encoders when they are working appear to be loosing counts. Each motor has a gearhead and when we back drive it, the counts climb then stop. Also, if the PID loop is not tuned properly and there is an oscillation, the motor slowly drifts to one side as it jitters back and forth even as the encoder doesn't indicate net motion.

    Any ideas?

    I would really like to use the hardware encoders because of the speed, but have really hit an impasse. Thanks in advance,
    Tim




    excited about using the

  12. #37
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    6,967
    Real late for me but the reason for certain pins not working together is because they share the same IO enconder connection. So basically:

    Pins 1 and 36 can not be used together so you can use only one in your sketch if you are using multiple channels. So in your sketch you can use Pin 1 or 36.
    Pins 0, 5, and 37 are mutually exclusive so you can use only one in your sketch if you are using multiple channels. So in your sketch you can use Pin 0 or 5 or 37.

    Looks like I left out pin 1 and 36 on that list in the read me. Thanks for pointing this out.

    As to your second problem, not seeing your whole sketch you need to initialize the 3 encoders in setup once, not keep intializializing them as you need them. To zero an encoder out _motor_enc.write(0);

    Look at the simple_encoder sketch in the examples folder and you will see what I mean.

    The encoder will only change if it sees a interrupt signal from the encoder on the motor - if the motor is just jittering it may not hit an indent. But then the jitter may cause some problems in counts - never tested that way.

    Again with seeing your code or hardware hard to say.

  13. #38
    Junior Member
    Join Date
    Feb 2017
    Posts
    11
    Thanks a lot, and I am massively impressed with the speed of the reply.

    I am a happy to have a clear cut answer on pins 1 and 36, if a little disappointed. That helps keep me from chasing gremlins.

    I have the encoders within a custom written library with the PID and a bunch of other functions that together form an Axis. I need to do some more digging on the speed/jitter and will post a follow up with some scope traces and a cleaner outline of the code. I am not continually initializing them, only in the constructor so that is not it. Based on some previous posts about the pulse rate, my suspicion is that it is on my end. Thank you, and more info to come.

  14. #39
    Senior Member
    Join Date
    Jan 2014
    Posts
    181
    I need to multiplex (with a Teensy 4.1) 24 encoders.

    Which is better?
    A. multiplex 6 encoders per each of the 4 hardware encoder ports
    B multiplex 24 encoders using i/o pins and software

    thanks

    Richard

  15. #40
    Junior Member
    Join Date
    Jan 2020
    Posts
    7
    Quote Originally Posted by RichardFerraro View Post
    I need to multiplex (with a Teensy 4.1) 24 encoders.

    Which is better?
    A. multiplex 6 encoders per each of the 4 hardware encoder ports
    B multiplex 24 encoders using i/o pins and software

    thanks

    Richard
    Hai Richard

    I think it is a mistake to say that the tinsy has 4 harware encoders ports. I can not find that kind of ports I think it is a software limitation.
    Perhaps this limitation is due too build into the software library. I think that is because timing considerations, that is the most likely explanation.
    In case you try to do the job using 24 I?O pins you will encounter the same problem. Perhaps it is possible to define two or more encoder
    objects in your application and reassign the ports. A other option is to look into the software and try to modify it for the use of more encoders.
    I think you need some advice of the developer of the board. An important question is the speed you need of the decoders

    John

  16. #41
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    6,967
    Quote Originally Posted by JNivard View Post
    Hai Richard

    I think it is a mistake to say that the tinsy has 4 harware encoders ports. I can not find that kind of ports I think it is a software limitation.
    Perhaps this limitation is due too build into the software library. I think that is because timing considerations, that is the most likely explanation.
    In case you try to do the job using 24 I?O pins you will encounter the same problem. Perhaps it is possible to define two or more encoder
    objects in your application and reassign the ports. A other option is to look into the software and try to modify it for the use of more encoders.
    I think you need some advice of the developer of the board. An important question is the speed you need of the decoders

    John
    The T4.1, which is based on the nxp 1162 supports has 4 H/W Quadrature encoders. There is a library as this thread mentions that provides the access you need to use those 4 H/W Quadrature encoders. The library setups up the pin configurations that are needed to get access to the builtin Quad encoders. So while technically the cards don't show "ports" the pins can be reconfigured.

  17. #42
    Senior Member
    Join Date
    Jan 2014
    Posts
    181
    Sorry for the confusion. I replied to the wrong thread.

    I have a library based on NXP Quad Encoder SDK driver for the Encoder module but modified to support the Teensy 4.x infrastructure.

    NOTE: you will need to incorporate the Update imxrt.h for encoder structure #402 to make use of the library.

    There are 4 hardware quadrature encoders available the Teensy 4.0. These are currently supported on FlexIO pins: 0, 1, 2, 3, 4, 5, 7, 30, 31 and 33. The library is available in my GitHub repository: https://github.com/mjs513/Teensy-4.x...ncoder-Library.

    thanks,

    Richard

  18. #43
    Senior Member
    Join Date
    Jan 2014
    Posts
    181
    I see now that the hardware encoders are best suited to motor encoders. I currently like this thread which uses SPI:
    https://forum.pjrc.com/threads/42514...tary-Encorders

Posting Permissions

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