Author Topic: Any good examples on rotary encoder library "WITH" velocity ?  (Read 35901 times)

0 Members and 1 Guest are viewing this topic.

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #25 on: September 17, 2013, 02:52:59 pm »
Quote
This is a cut down snippet which is called from a timer interrupt.

That's effectively polling and consequentially not terribly efficient and may miss pulses if the encoder goes fast (aka on a motor).

The state machine approach + interrupts is really the only way to go, short of hardware encoder support.
================================
https://dannyelectronics.wordpress.com/
 

Offline TerminalJack505

  • Super Contributor
  • ***
  • Posts: 1310
  • Country: 00
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #26 on: September 17, 2013, 02:57:56 pm »

Are you willing to insert them in the post again?

Alright.  Here are the attachments from my original post.

Note that they don't even address the question of "velocity."  I was just pointing out a way to implement bounce tolerance.
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26892
  • Country: nl
    • NCT Developments
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #27 on: September 17, 2013, 02:59:54 pm »
That's effectively polling and consequentially not terribly efficient and may miss pulses if the encoder goes fast (aka on a motor).
The state machine approach + interrupts is really the only way to go, short of hardware encoder support.
Its not inefficient because most of the code is only executed when an edge occurs. The problem is that a mechanical encoder will bounce. Before I came up with my piece of code I tried using interrupts and a hardware counter only to find out I needed proper debouncing in software. You may call it polling but in fact the real code (not the cut down version) also does filtering by skipping edges which are to close to eachother. Whether or not you miss pulses depends on how often its called (the sampling frequency).
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline TerminalJack505

  • Super Contributor
  • ***
  • Posts: 1310
  • Country: 00
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #28 on: September 17, 2013, 03:32:03 pm »
That's effectively polling and consequentially not terribly efficient and may miss pulses if the encoder goes fast (aka on a motor).
The state machine approach + interrupts is really the only way to go, short of hardware encoder support.
Its not inefficient because most of the code is only executed when an edge occurs. The problem is that a mechanical encoder will bounce. Before I came up with my piece of code I tried using interrupts and a hardware counter only to find out I needed proper debouncing in software. You may call it polling but in fact the real code (not the cut down version) also does filtering by skipping edges which are to close to eachother. Whether or not you miss pulses depends on how often its called (the sampling frequency).

Wow.  And you called my code too complicated.

I do advise that if you use code similar to mine that you use an RC filter on the two encoder signals but there's no other "software filtering" required.  You don't really want the interrupt running unnecessarily and the RC filter will help in this aspect.  (Note that my code can be easily adapted to be used in a polling-type of scheme.)

With the finite state machine, if the switches bounce then the state machine just ping-pongs back and forth between two adjacent states.  It only emits a "clockwise" or "counterclockwise" action when it has reached the point where all 4 required states have been visited.  Once it emits either the "clockwise" or "counterclockwise" action then the state machine returns to the idle state.  Note how the state machine doesn't bounce between "idle" and either CW10 or CCW01 so there's no problem with false actions.
 

Offline nessatse

  • Regular Contributor
  • *
  • Posts: 99
  • Country: za
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #29 on: September 17, 2013, 04:26:32 pm »

Nice diagrams TerminalJack505.
[/size]Using a FSM is the only reliable way to read these encoders, especially the cheap mechanical ones that will bounce in weird and wonderful ways. 


That is pretty complicated. You just need to look for edges on one line 'A' and then check the state of line 'B'. Executing two 'if' statements is enough.
[/size]
This is a naive approach, it will not only count on invalid transitions, but your example also does not count all the valid transitions. 


I do however agree that polling during a timer interrupt is preferable to edge interrupts, especially when dealing  with multiple encoders.  Running your timer tick at a decent frequency, say 1000Hz, will minimise the chance of missing a step, and even if you do the FSM will recover elegantly.
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26892
  • Country: nl
    • NCT Developments
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #30 on: September 17, 2013, 04:30:36 pm »
So your statemachine approach requires a full period (two events) to determine the direction? The problem with that is that most encoders for manual input have audible/tactile feedback every half period so you need to respond to a half period otherwise the user has to advance the knob two 'clicks' to advance by 1 which is counter intuitive.

Whether you do the filtering in software or hardware depends on where you need to save something. My method also works when called from a GPIO interrupt or a timer capture interrupt. Either way the golden rule is to never ever create an interrupt from an I/O pin which has 1) no proper filtering and 2) no schmitt trigger otherwise a simple fault like a loose wire or a worn contact can make your software come to a grinding halt because it keeps servicing interrupts. All in all using GPIO inferred interrupts just costs extra hardware.

@nessatse: the code I posted is just to show how to use the edges on the 'A' line in order to determine the steps. Depending on the actual hardware filtering may be required. In the real software I keep track of the number of timer ticks between the edges for de-bouncing and determining velocity. If the number of ticks is too small the edge is ignored.
« Last Edit: September 17, 2013, 05:17:16 pm by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline Rufus

  • Super Contributor
  • ***
  • Posts: 2095
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #31 on: September 17, 2013, 04:49:43 pm »
I do advise that if you use code similar to mine that you use an RC filter on the two encoder signals but there's no other "software filtering" required.

Hardware filters increase cost and board space, a few extra instructions usually costs nothing.
 

Offline nessatse

  • Regular Contributor
  • *
  • Posts: 99
  • Country: za
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #32 on: September 17, 2013, 05:10:52 pm »
So your statemachine approach requires a full periode (two events) to determine the direction?

I admit I haven't worked through TerminalJack505's code, but for the code I posted earlier, (which used the same FSM logic, although in a slightly different way) this is definitely not the case.  The fsm  in fact acts just like a type of software filter, preventing counters from changing during illegal state transitions that you would typically get with noisy/bouncy switches.  It will respond to every valid transition on either the A or B legs, i.e. "half" periods.

The encoders I have used all count 4 counts, i.e. a full cycle 00-01-11-10, between detents, I have been running the code I posted in a real environment, without any external hardware or further software filtering and it has been performing flawlessly.
 

Offline TerminalJack505

  • Super Contributor
  • ***
  • Posts: 1310
  • Country: 00
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #33 on: September 17, 2013, 05:15:05 pm »
So your statemachine approach requires a full periode (two events) to determine the direction? The problem with that is that most encoders for manual input have audible/tactile feedback every half period so you need to respond to a half period otherwise the user has to advance the knob two 'clicks' to advance by 1 which is counter intuitive.

That particular code was written for the cheap mechanical quadrature encoders that produce one pulse per detent.  One cycle for these encoders (where each detent is located) is shown on the state diagram by a dotted line.  The vast majority of the inexpensive mechanical encoders are of this variety.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #34 on: September 17, 2013, 05:22:18 pm »
"that produce one pulse per detent."

That's fairly rare: most produce 4 pulses, cheap or not.

As to the rc filter: it doesn't pay to solve a hardware problem with software. Though I have to agree with the other poster that the state machine approach is remarkably resistent to invalid pulses.
================================
https://dannyelectronics.wordpress.com/
 

Offline TerminalJack505

  • Super Contributor
  • ***
  • Posts: 1310
  • Country: 00
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #35 on: September 17, 2013, 05:40:13 pm »
"that produce one pulse per detent."

That's fairly rare: most produce 4 pulses, cheap or not.

As to the rc filter: it doesn't pay to solve a hardware problem with software. Though I have to agree with the other poster that the state machine approach is remarkably resistent to invalid pulses.

That's not my experience.  Last time I went shopping for mechanical quadrature rotary encoders, the one pulse per detent type was pretty much all I could find.  Unfortunately, Digi-key doesn't have this as a parameter so you can't search by it but I remember going through page, after page of encoders looking for the half- and quarter-pulse per detent type and finding very few.

Keep in mind that I'm talking about mechanical encoders.  Optical encoders are another story.
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2806
  • Country: au
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #36 on: September 17, 2013, 09:20:38 pm »
I'm implementing a rotary encoder in a current project.  Both the original one and a replacement type are mechanical and 4 pulses per click.  Both were bought from Digikey and were only a few dollars in one off quantity.
 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #37 on: September 17, 2013, 09:35:07 pm »
It may be a question of terminology, whether you count all four edges or just the full cycles.

Offline Rufus

  • Super Contributor
  • ***
  • Posts: 2095
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #38 on: September 17, 2013, 11:15:59 pm »
Still no response with any velocity sensitivity.

I have a spare time project using a Bourns PEC11 series mechanical encoder. It is working with code similar to the examples already posted here. It might benefit from some velocity sensitivity as it is used to cycle through menu options and to adjust numbers.

I will probably do some work on it eventually but I am pretty sure it will take some experimentation to get it to 'feel' right. Overshooting on number adjustment would be undesirable so the acceleration will have to 'feel' predictable.
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #39 on: September 17, 2013, 11:51:12 pm »
Heh, yeah, no velocity. If BravoV can write up a decent spec for what's needed, maybe someone will magically code it up.
 

Offline BravoVTopic starter

  • Super Contributor
  • ***
  • Posts: 7547
  • Country: 00
  • +++ ATH1
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #40 on: September 18, 2013, 04:24:04 am »
Woah .. lots of updates and discussions, keep it going, ideas exchange and also different algorithms are good thing imo, especially to capture what other people are thinking on countering this matter.  :-+

Please understand, I'm still learning, and while I did write my own code (even though it sucks big time), it works though not optimal, now when it comes to integrate with "velocity" feature, everything falling apart and turned into chaos, don't ask, I'm too embarrassed to post my code, just forget it. .. LOL ...  :-DD

Also, I repeat, I may not be active in discussing this, please trust me, I'm observing this thread intensively while learning how each of you tackle it from each perspective, thats matter and valuable to me in this learning process.


Heh, yeah, no velocity. If BravoV can write up a decent spec for what's needed, maybe someone will magically code it up.
There are few previous posters already mentioned the idea like Psi did on 3 type of speeds, or nessatse's code implementing three velocity thresholds like coarse, medium and fine.

To be honest, actually I have my own very crude idea "pirated"  :P from TI tiva cortex m4f's API that handles it's hardware based QEI (Quadrature Encoder Interface). But I was hesitated to post this at the beginning since I don't want to have our hands tie up only to TI's idea/solution, and of course "ideally" the code should be easily adaptable to other platforms if possible.

But since you mentioned it, here a snippet on TI's QEI's API brief description, captured screen for your viewing pleasure without needing to download the PDF with the highlighted regions at the "velocity" feature :



Above quoted from chapter 19 at page 227, download link -> TivaWare™ Peripheral Driver Library for C Series User's Guide (PDF approx 1.8 MB)

Again, this is just my noob idea, prolly I don't know heck what I'm talking about, but for me maybe that is a good start on the idea at handling/interfacing with the "velocity" feature. And its the way how you experts/experienced people tackle it that I love to learn from.

Feel free to drop this TI's related thingy should you think this is useless, way too complicated or not feasible for easily adaptable to other different mcu architectures.  :-+

Offline BravoVTopic starter

  • Super Contributor
  • ***
  • Posts: 7547
  • Country: 00
  • +++ ATH1
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #41 on: September 18, 2013, 04:44:54 am »
On hardware level, this is how TI QEI module handles bounces, attached the print screen from the datasheet on the QEI hardware (highlighted).

Again, just ignore this post if you think this is useless.
« Last Edit: September 18, 2013, 04:47:52 am by BravoV »
 

Offline Rufus

  • Super Contributor
  • ***
  • Posts: 2095
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #42 on: September 18, 2013, 05:04:38 am »
Please understand, I'm still learning, and while I did write my own code (even though it sucks big time), it works though not optimal, now when it comes to integrate with "velocity" feature, everything falling apart and turned into chaos, don't ask, I'm too embarrassed to post my code, just forget it. .. LOL ...  :-DD

Well if you wanted to do some experimentation your results might save me some effort, however, I am currently interested in cheap mechanical encoders with one pulse (or 4 edges) per dedent. So is that what you are working with?
 

Offline BravoVTopic starter

  • Super Contributor
  • ***
  • Posts: 7547
  • Country: 00
  • +++ ATH1
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #43 on: September 18, 2013, 05:07:10 am »
Well if you wanted to do some experimentation your results might save me some effort, however, I am currently interested in cheap mechanical encoders with one pulse (or 4 edges) per dedent. So is that what you are working with?
Yep, dirt cheap mechanical with 4 edges, not even Bourns brand.  :P

Offline Rufus

  • Super Contributor
  • ***
  • Posts: 2095
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #44 on: September 18, 2013, 05:45:21 am »
Well if you wanted to do some experimentation your results might save me some effort, however, I am currently interested in cheap mechanical encoders with one pulse (or 4 edges) per dedent. So is that what you are working with?
Yep, dirt cheap mechanical with 4 edges, not even Bourns brand.  :P

My suggestion then would be to implement a polled scheme from a timer interrupt at about 1kHz and use the previous + current state to index into a 16 element array of count deltas like the examples in this thread.

Bounce on either input causes jitter on the LSB of the count, but, detent to detent the count changes by 4 so you should be ignoring the 2 LSBs of the count anyway. 

I think there is an issue that I have noticed (without actually investigating) where turning the encoder faster than it can track causes the count to get out of sync with the encoder dedents so I would suggest using a time out on encoder activity to set the count 2 LSBs to zero (on the assumption the encoder will be in a dedent).

For velocity a similarly triggered timeout could be used and when you see a whole pulse if the timeout is still running you would adjust the count by more than 1. You could have more than one timeout to detect more than one velocity level. That said I suspect it could 'feel' better if you don't accelerate the second pulse but delay it till the 3rd or 4th which gets more complicated.

I tend to use a lot of what I call software monostables.

if(mono)
  mono--

running at the 1kHz or whatever rate. You can trigger and re-trigger by setting mono to a value and mono being zero indicates timed out.
 

Offline nessatse

  • Regular Contributor
  • *
  • Posts: 99
  • Country: za
 

Offline TerminalJack505

  • Super Contributor
  • ***
  • Posts: 1310
  • Country: 00
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #46 on: September 18, 2013, 11:28:33 am »
It may be a question of terminology, whether you count all four edges or just the full cycles.

Yes, the manufacturers seem to give different names to the same thing so I think we're probably talking about the same thing.

  1 Pulse per Detent == 4 Phase per Click == 4 edges per Detent

All of them seem to agree on the term "Pulses Per Revolution."  So if the number of pulses per revolution is the same as the number of detents per revolution then that's also the same type.
 

Offline TerminalJack505

  • Super Contributor
  • ***
  • Posts: 1310
  • Country: 00
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #47 on: September 19, 2013, 06:25:49 am »
Here's something I've been working on.  It's a bounce and skip tolerant rotary encoder class with support for velocity.  It's still half-baked.  The port/pin stuff is still hard coded and I haven't even run it yet.  I just bolted-on the skip handling and velocity stuff to my earlier code.

The idea behind the velocity support is to sample the number of actions (full clockwise or counter-clockwise clicks) at a period of approximately 100ms to 300ms and report this as the velocity.  This isn't the instantaneous velocity, obviously, and introduces a lag but hopefully that won't matter so long as the sampling periods are small enough.  If it works then there won't be as much data to keep track of.  I'm targeting the class toward 8-bit MCUs with limited resources--particularly SRAM.

The velocity, as reported to the user (the class user) will be the number of actions during the last complete time slice.  So, if the user (the end user) is turning a 24 pulse per rotation encoder counter-clockwise at 40 detents per second (pretty fast) and the sample period is 200ms, then velocity would be reported as -8.  How this velocity is interpreted is up to class user.

It will probably be a trick finding the best sample period size so that lag is minimized while resolution is maximized.  This method will also benefit from using encoders with a higher number of pulses per rotation.
 

Offline BravoVTopic starter

  • Super Contributor
  • ***
  • Posts: 7547
  • Country: 00
  • +++ ATH1
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #48 on: September 19, 2013, 07:09:22 am »
TerminalJack505, much appreciated !  :-+

Since I'm still novice, when it comes to reading other people's code at interested topic, I always expect and really love the excitement when .. "How come I didn't think of that !" moment.  ;)

Going to print it on paper and bring it to bed later on.  ;D

Again, thanks Jack.

Offline TerminalJack505

  • Super Contributor
  • ***
  • Posts: 1310
  • Country: 00
Re: Any good examples on rotary encoder library "WITH" velocity ?
« Reply #49 on: September 19, 2013, 07:22:50 am »
No problem.  I'll let you know how testing works out.  I'm sure there will be some changes.  Hopefully minor.

Note that the skip tolerance code isn't the same as the skip tolerance state machine diagram I posted earlier.  The skip logic takes the current velocity into account so that when a skip occurs it gives a bias to the current rotation direction.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf