Another quadrature Rotary Encoder question - Page 1
Forum section: electronics / projects

author: 741
author_rank: Frequent Contributor
timestamp: August 12, 2018, 03:17:13 pm
content: It's ages since I used a state machine to get modest results (at various ferocities of twiddle) out of a PEC11 18-detent encoder. By that I mean that sometimes my code seems responsive to all speeds of rotation, but then when I use the encoder slowly, sometimes a 'click' is missed. (My higher-level code uses a 'ballistic profile' so overall a user can change large amounts quickly, then finely adjust an exact value).Wanting to re-visit encoders, I've had a fair look around today, and read Jack Ganssle's interesting PDF on the general topic of debouncing.I do not have a DSO, (although I did borrow one for this purpose once), so it's hard for me to quantify the noise. I suspect that perhaps both contacts are simultaneously noisy on occasion.Bourns themselves suggest(1) An off the shelf MC14490(2) An RC circuit with 2x 10k plus 10n. There is no diode to even out bounce up / bounce down.(3) Just codeSo far, in the interests of 'purity' I've kept to (3), but I wonder if I might as well supplement my existing code with the RC. I'm a little surprised at the 0.1 ms time constant (0.2 ms for pull-up). I'd have guessed more like 1ms.On the subject of RC - do the suggested values work well? I'd be surprised if Bourns have not suggested carefully chosen values, but I just wondered.

author: JS
author_rank: Frequent Contributor
timestamp: August 12, 2018, 03:28:32 pm
content: It's just to take the edge off, any value would help as long as it isn't way too big so you miss steps when going fast. Those sound fine.JS

author: Peabody
author_rank: Super Contributor
timestamp: August 13, 2018, 05:28:11 am
content: In my experience, all "just code" solutions depend on the premise that the two switches won't be bouncing at the same time. If they are, I don't think there's any way for software alone to determine what's actually going on. I guess in theory some R/C stuff would help in those situations when both are bouncing, depending on how bad it is, but I think what most find is that for reasonably good encoders like the Bourns, code is plenty good enough unless the encoder is actually defective or dirty. That state machine lookup table method you used still works awfully well.Also, I think missing a click now and then isn't all that bad. What's bad is getting the direction wrong, and that's a good indication that the encoder is bad.

author: 741
author_rank: Frequent Contributor
timestamp: August 13, 2018, 02:20:21 pm
content: Yes, the "both contacts bouncing" scenario is hard to think about.My final application circuits often do things other than look at the decoder of course, eg RS232 or driving an AD9850. Also, I typically use a modest PIC (28 pin PIC24 etc) at 8MHz clock.To test the encoder, I used CMOS logic. Using 2x4029B CMOS counters and the Bournes RC circuit (10k x2, 10nF), PEC11 24-Detent encoder, I tried several full turns, some fast (but not crazy), some slow/ fairly careful.I had presumeda Schmitt Trigger input would exist on these CMOS counters. It looks like 'no' therefore I interposed a Schmitt Trigger - that would be more like a PIC logic input. I uses a 40106 device for that.The 2x10k & 10nF circuit from the DS was not brilliant. 100n worked better in my tests.By raising C to 100nF, both 24 detent and 18 detent units gives pretty good results - several perfect runs (both slow and fast), and often within 3 counts.But note - I needed that 40106.

author: Peabody
author_rank: Super Contributor
timestamp: August 14, 2018, 01:59:17 pm
content: If you're concerned about the time needed to service the encoder with everything else going on, you might consider setting the encoder lines to generate interrupts rather than polling every few milliseconds. One way to do that is to enable the interrupt on only one line at a time. So for example, when you get an interrupt on the falling edge of A, as part of that service routine you disable the A interrupt, but enable the B interrupt for a falling edge. When A changes state and bounces, B should already be stable, so all of the bouncing on A at that point generates no interrupts at all because interrupts aren't enabled on A. In theory, you can go through a complete cycle of four transitions from one detent to the next by servicing exactly four interrupts. And of course there are no interrupts at all unless the knob is being turned.This gets complicated when there's a direction change. I worked something up on this a while back and posted it on Github. It might be useful.https://github.com/gbhug5a/Rotary-Encoder-Servicing-RoutinesBut I still think the bottom line is that it's ok for either or both of the encoder switches to bounce for a while when they change state, but if you're using software-only debouncing, they just can't be bouncing at the same time. If you have encoders like that, hardware debouncing, or both, is probably the way to go.Edit: You might also want to look at this thread:https://www.eevblog.com/forum/projects/rotary-encoder-dubious-video/msg1460649/#msg1460649It was my thread, and the results the included video displayed with software-only were so good that I questioned whether the video might be faked. Everybody else seemed to think it was legit, and if that's the case then it's a demonstration of just how well software debouncing can work. Unfortunately, he does not disclose his routines.

author: 741
author_rank: Frequent Contributor
timestamp: August 15, 2018, 11:40:27 am
content: Thank you. I have had a quick read through your PDF to get an overview. I find it reassuring you seem to have the same kind of problems I had, and that basically it's not as easy as it looks.Do you have a picture of the ideal waves for type 1 vs type 2 encoders?What class are the Bourns PIC11 encoders for instance? From the datasheet I think they are "Type 1", because the "D"etent label occurs only once in the waveform. But actually the diagram is a bit unsure here because they show the start of another full wavefom, and this should have another "D" annotation.AfterthoughtAny sw routine must presumably aim to catch all hardware transitions. With no hardware smoothing, polling must sample faster than twice the fastest noise-to-noise period. For ISR, we want to be sure somehow that no "noise" is missed during the ISR (it might not be "noise" anyway, hard to define what noise is here really). Not that we want noiseper se, but we do want all the information.

author: Peabody
author_rank: Super Contributor
timestamp: August 15, 2018, 02:20:18 pm
content: The encoder type is really a function of what configuration you order. If you order one with pulses per rotation equal to detents per rotation, then between detents the encoder will go through a complete cycle on both switches, so there will be a total of four transitions between detents (ignoring bounce). In the case of the PEC11s, it will end up with both switches open at the detent. It looks like the PEC9 ends up with both switches closed.But if you look at the PEC11R datasheet How To Order, you'll see that you can also order an encoder with half as many pulses per rotation as detents per rotation. For those, a detent occurs at every half-cycle. There are only two transitions between detents, and at any detent the switches can be either both open or both closed. You can still get one encoder "tick" per detent, and determine the proper direction. So if you can get the same information processing only half as many transitions, why wouldn't you always use this type? Well, because half the time on average an idle encoder will end up with both switches closed, and drawing current through the pullup resistor. But for some types of processing, that may not matter. My writeup discusses this.On your afterthought, I look at it the opposite way. I don't want to capture all the transitions. I want to ignore as many as I can, particularly the ones that occur during bouncing. If you use pin-based interrupts to process the encoder, servicing all the bounce interrupts may impact on your main application processes even if it detects the encoder movements correctly. My alternating interrupts system is intended to eliminate any bounce processing at all, so for a good encoder you only have to service four interrupts to get from one detent to the next, or only two interrupts in the case of the second type of encoder.In the case of timer-based periodic polling, you can't eliminate exposure to some bounce, but you defintely do not need to poll so often that you detect every bounce. You can poll at 1 or 2 milliseconds, or even slower, and do just fine.