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

Thread: Encoder Library debounced

  1. #1
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    8,325

    Encoder Library debounced

    Hi,

    I made a fork of Pauls' great Encoder library.
    It is still compatible, and just uses an alternate algorithm which is debounced.
    With cheap mechanical encoders you will have a new user experience. No debouncing with capacitors needed anymore - and is better than capacitors.
    I found the algorithm on the net (link in the sourcecode), tested it, and decided to use it for the library.
    Updating your existing programs is easy: exchange

    #include <Encoder.H>
    with
    "#include <EncoderBounce.h>

    https://github.com/FrankBoesing/EncoderBounce

  2. #2
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,465
    I tested your library on a T3.2 with the output of my Encoder tester on a T3.6 (https://github.com/luni64/EncSim, precompiled hex files in the release section).

    Following findings:

    • Looks like the lib only increments every 4th step. While some mechanical encoders internally generate 4 steps per detent there are also encoders incrementing by 2 or 1 step per detent.
    • Looks like you have a problem with the starting condition. The first step counts in opposite direction (see below).

      Click image for larger version. 

Name:	Anmerkung 2020-04-17 105823.jpg 
Views:	56 
Size:	44.2 KB 
ID:	19744

    • Tested 160'000 steps up and down
      • 5kHz -> no steploss
      • 50kHz -> no steploss
      • 250kHz -> some 20 steps lost



    Standard Encoder lib:
    • Gives one count per encoder step
    • Starting condition OK (starts at 0 in the right direction)
    • No steploss up to about 200kHz (same as above)

  3. #3
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    8,325
    Quote Originally Posted by luni View Post
    I tested your library on a T3.2 with the output of my Encoder tester on a T3.6 (https://github.com/luni64/EncSim, precompiled hex files in the release section).

    Following findings:

    • Looks like the lib only increments every 4th step. While some mechanical encoders internally generate 4 steps per detent there are also encoders incrementing by 2 or 1 step per detent.
    • Looks like you have a problem with the starting condition. The first step counts in opposite direction (see below).

      Click image for larger version. 

Name:	Anmerkung 2020-04-17 105823.jpg 
Views:	56 
Size:	44.2 KB 
ID:	19744
    • Tested 160'000 steps up and down
      • 5kHz -> no steploss
      • 50kHz -> no steploss
      • 250kHz -> some 20 steps lost



    Standard Encoder lib:
    • Gives one count per encoder step
    • Starting condition OK (starts at 0 in the right direction)
    • No steploss up to about 200kHz (same as above)
    Thanks for testing!

    Looks like it is just not compatible to your "encoders". It's meant for the cheap mechanical "china" encoders.
    With these:
    - Startcondition is OK.
    - Gives one count per encoder step
    - They are operated manually, by hand. You can't reach 200kHZ manually. Even if - you'll be not able to say if it has lost 0,000125% steps or not.

    Ok, so the debounced variant seems not be good for every kind of encoder.
    I have *perfect* results.
    The original lib has hefty problems with bouncing. With the new variant, bouncing is completely eliminated with my encoders.
    Code:
    Basic Encoder Test:
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    14
    13
    12
    11
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    0
    Last edited by Frank B; 04-17-2020 at 10:00 AM.

  4. #4
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,465
    Thanks for testing!

    Looks like it not compatible to your "encoders". It's meant for the cheap mechanical "china" encoders.
    Sure, nevertheless it seems that the lib only works correctly for those encoders with 4 steps per detent. This is often the case but not always. E.g., this is the first one I find on Adarfruit https://www.adafruit.com/product/377 If you look at the datasheet this encoder comes with various relations between detends and pulses. There are also versions with no detents at all (Detent Option 0) Your lib would only give 1/4 of the specified counts per rev for those. There are options with 2 steps per detent and options with 4 steps per detent... In my rummage box I have all kinds of mechanical encoder with 1 / 2 and 4 steps per detent.

    - They are operated manually, by hand. You can't reach 200kHZ manually. Even if - you'll be not able to say if it has lost steps or not.
    Of course, I was just interested in the performance of the algorithm which obviously is good.

    Bouncing:
    I also tested with various bounce settings. Here an example:
    Click image for larger version. 

Name:	Anmerkung 2020-04-17 113927.jpg 
Views:	36 
Size:	36.5 KB 
ID:	19745

    1ms bounce duration, bounce peaks from 5Ás to 100Ás. Count frequency 500 Hz. Don't see any lost steps with any reasonable setting.

  5. #5
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    8,325
    Maybe
    The original often gives 4 counts for 1 step, too. (See various threads here, or "issues" on Github)
    I'll leave it as it is. If anyone gets 4 counts per step, just use a div by 4 ( / 4)
    If it is still not good enough, just use the original lib.

  6. #6
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,465
    Sorry I probably was unclear and don't want to bother you but the problem is the other way round. Yours would give 1/4th of the steps which unfortunately can not be cured by the usual divide by 4.

  7. #7
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    8,325
    ok - feel free to fix that. The lib is open source, algorithm starts here , description here: https://www.best-microcontroller-pro...pic-micro.html
    Last edited by Frank B; 04-17-2020 at 10:53 AM. Reason: Added link

  8. #8
    Junior Member
    Join Date
    Feb 2021
    Posts
    1

    Unhappy EncoderBounce not any longer on Github

    Hallo Frank B,

    in summer last year I downloaded your EncoderBounce library and it worked perfectly with my (also checp Chinese) encoders in the Teensy Convolution SDR code.
    In the meantime I had to reinstall my laptop and lost the EncoderBounce library. Tried to get it from Github again, but it does not exist any longer - just received an Error 404.
    Also a Google search dis not help at all.

    Does still anybody have a copy of the EncoderBounce library and could provide it to me or put it onto Github?

    Many thanks
    Joerg

    Quote Originally Posted by Frank B View Post
    Hi,

    I made a fork of Pauls' great Encoder library.
    It is still compatible, and just uses an alternate algorithm which is debounced.
    With cheap mechanical encoders you will have a new user experience. No debouncing with capacitors needed anymore - and is better than capacitors.
    I found the algorithm on the net (link in the sourcecode), tested it, and decided to use it for the library.
    Updating your existing programs is easy: exchange

    #include <Encoder.H>
    with
    "#include <EncoderBounce.h>

    https://github.com/FrankBoesing/EncoderBounce

  9. #9
    Senior Member
    Join Date
    Oct 2015
    Location
    Roma (IT, EU)
    Posts
    360
    By the way.
    I'm using the great EncoderTool library by luni:
    https://github.com/luni64/EncoderTool

    It's absolutely, by far, the best I've ever tried. Much better than Paul's library, which is something.

    Problem is, it only works on Teensies.
    They are great, but I would love to use it with other chips (RISC-V, SAMD21).

    Any hint about porting? Where to start?

    Thanks

  10. #10
    Senior Member
    Join Date
    May 2017
    Posts
    238
    Here is some simple polling code for cheap mechanical encoders. Just replace the new_ = PINC line with some digitalReads for whatever micro you are using. The code does not keep track of absolute position. If you don't want the divide by 4, comment out all code that references mod.

    Code:
    int8_t encoder(){   /* read encoder, return 1, 0, or -1 */
      
    static int8_t mod;     /* encoder is divided by 4 because it has detents */
    static int8_t dir;     /* need same direction as last time, effective debounce */
    static int8_t last;    /* save the previous reading */
    int8_t new_;     /* this reading */
    int8_t b;
    
       new_ = PINC & 3;  
       if( new_ == last ) return 0;       /* no change */
    
       b = ( (last << 1) ^ new_ ) & 2;  /* direction 2 or 0 from xor of last shifted and new data */
       last = new_;
       if( b != dir ){
          dir = b;
          return 0;      /* require two in the same direction serves as debounce */
       }
       mod = (mod + 1) & 3;       /* divide by 4 for encoder with detents */
       if( mod != 2 ) return 0;
    
       if( dir == 2 ) return 1;   /* swap return values if it works backwards */
       else return -1;
    }

  11. #11
    Senior Member
    Join Date
    Oct 2015
    Location
    Roma (IT, EU)
    Posts
    360
    Sorry, I was not clear.
    I was not searching another algorithm to read encoders, I've tried them all.
    I was looking for hint to port Luni's library specifically, from Teensy-only to other boards.

Posting Permissions

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