Author Topic: Rotary encoder with PIC16F887 troubles  (Read 3681 times)

0 Members and 1 Guest are viewing this topic.

Offline Peabody

  • Super Contributor
  • ***
  • Posts: 2106
  • Country: us
Re: Rotary encoder with PIC16F887 troubles
« Reply #25 on: January 08, 2023, 11:12:27 pm »
Ok, you're just ignoring the first three of the four transitions between one detent and the next.  When you get to a detent (11),  you just see how you got there, and if one of the two possible valid transitions has occurred, you recognize a tick.  I think some would contend that your approach is somewhat more susceptible to errors when there is bouncing.  If you instead pay attention to all transitions, you have to have accumulated a net four transitions is the same direction when you arrive at a detent before recognizing that a valid tick has taken place.  But you know, if it works for you, it works, and there's no need to do more.

But I do want to talk you into using the lookup table.  If 14 of the 16 possible entries are zero, and if the two valid entries are +.5 and -.5, then you can just add the indexed lookup table value to your volume, and you're done.  No IF statements required.
 

Offline PCB.Wiz

  • Super Contributor
  • ***
  • Posts: 1738
  • Country: au
Re: Rotary encoder with PIC16F887 troubles
« Reply #26 on: January 09, 2023, 01:08:43 am »
I ended up using a TI CD74AC14E Schmitt trigger to fix this. However, it only worked perfectly after adding an additional 100ms delay before toggling the LEDs otherwise it would still skip once or twice.

Screenshots showing the signal before and after the Schmitt trigger.

R1, R2 = 10K
R3, R4 = 1K
C1, C2 = 10nF
If resting power matters, you can increase those R values significantly and lower the C.


Such a Schmitt + series RC design is 'solid' and the benefit it gives you is the hardware RC defines a minimum time possible between edges.
Series RC is better than simpler parallel C, as parallel C is tougher on the contacts, and fall time is still very short.

In theory, quadrature designs can track bouncing contacts, but that theory assumes the time between edges is sufficiently long for the code to act on each one. Nasty contacts can mean that is not true.

Some MCUs have Schmitt pins/options, so you can use that feature if available.

Another advantage of using a hardware RC cleanup of contact bounce, is you can more easily apply rate-of-spin non linear smarts to your quad interface.

 
 
The following users thanked this post: newtekuser

Offline paulca

  • Super Contributor
  • ***
  • Posts: 4176
  • Country: gb
Re: Rotary encoder with PIC16F887 troubles
« Reply #27 on: January 09, 2023, 08:22:32 am »
Ok, you're just ignoring the first three of the four transitions between one detent and the next.  When you get to a detent (11),  you just see how you got there, and if one of the two possible valid transitions has occurred, you recognize a tick.  I think some would contend that your approach is somewhat more susceptible to errors when there is bouncing.  If you instead pay attention to all transitions, you have to have accumulated a net four transitions is the same direction when you arrive at a detent before recognizing that a valid tick has taken place.  But you know, if it works for you, it works, and there's no need to do more.

But I do want to talk you into using the lookup table.  If 14 of the 16 possible entries are zero, and if the two valid entries are +.5 and -.5, then you can just add the indexed lookup table value to your volume, and you're done.  No IF statements required.

It won't suffer from bounces.  I the case of my encoder all valid transitions end with both contacts closed.  All you really need to know is, was is at a valid LEFT or a valid RIGHT before it got there.  Hence 0111 or 1011.  It can't get there from a bounce.

Using the look up table and being able to just add transitions[ state&0xF ] does sound nice, but you still have to define the whole 16 value lookup table.  I'm not sure that is a benefit over an if/else.
"What could possibly go wrong?"
Current Open Projects:  STM32F411RE+ESP32+TFT for home IoT (NoT) projects.  Child's advent xmas countdown toy.  Digital audio routing board.
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 13006
Re: Rotary encoder with PIC16F887 troubles
« Reply #28 on: January 09, 2023, 08:37:26 am »
It won't suffer from bounces.  I the case of my encoder all valid transitions end with both contacts closed.  All you really need to know is, was is at a valid LEFT or a valid RIGHT before it got there.  Hence 0111 or 1011.  It can't get there from a bounce.

Using the look up table and being able to just add transitions[ state&0xF ] does sound nice, but you still have to define the whole 16 value lookup table.  I'm not sure that is a benefit over an if/else.
Unfortunately you can get there from overlapping bounces on both A and B, which *CAN* look like the quadrature signal you are expecting from movement,  The encoder is made with multi-finger contacts to reduce the risk of this happening, but as it ages and surface contamination builds up false counts become inevitable.  Short of complex code that monitors the encoder transition rate, and rejects implausibly fast transition sequences, your only defence is asymmetric RC filtering - fast to pull down but slow to pull up to 'bridge' the bounces, with enough wetting current to keep the contacts clean.

However, the simple approach works well with optical and hall effect quadrature encoders, as although rotational vibration can cause jitter on one channel, the other channel can never change state near a transition of the first, and visa-versa.
 

Offline paulca

  • Super Contributor
  • ***
  • Posts: 4176
  • Country: gb
Re: Rotary encoder with PIC16F887 troubles
« Reply #29 on: January 09, 2023, 09:03:10 am »
Unfortunately you can get there from overlapping bounces on both A and B, which *CAN* look like the quadrature signal you are expecting from movement,

I might have read the datasheet wrong, but it shows several full complete transitions and there are gaps between the contacts aligning which limits the plausible bounces to single pins.

I can suffer a bounce, say for example I get: 

0111 - which I take as clockwise.

If a pin bounces it could go to:

1100 - which is invalid
or
1101 - which is invalid

A double bounce I suppose could go:

0111 - Valid CW
1101
0111 - Valid - ERROR double bounce.

Maybe my vTaskDelay( 1 milisecond ) is helping as well here.  I was going to replace it with a yeild.  I don't really like hot looping because in other hardware it's very expensive and frowned upon to do so unless absolutely necessary.

EDIT:  On rotary encoders as a user.  Yes they seem to be one of the first things to go on items like HiFis and similar devices.  My Sony Amp circa 1995 lost it's volume control a long while ago.  Have to use the remote.  The EQ preset encoder jumps all over the place.  I expect the volume control has "anti-bounce" coding or hardware and that's why it's mode of failure was just that it started ignoring more and more inputs until it just stopped altogether, it no long sees any valid transitions!

But if you use a pot and an ADC it too is subject to wear and tear causing bouncing due to "scratchy tracks" syndrome.

Hall effect encoders seem the only way.  Might see how expensive they are.  I did try and find a hall effect analogue joystick for a different project and found they tend to be expesnive.
« Last Edit: January 09, 2023, 09:27:31 am by paulca »
"What could possibly go wrong?"
Current Open Projects:  STM32F411RE+ESP32+TFT for home IoT (NoT) projects.  Child's advent xmas countdown toy.  Digital audio routing board.
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 13006
Re: Rotary encoder with PIC16F887 troubles
« Reply #30 on: January 09, 2023, 09:48:33 am »
Typically, low cost mechanical encoders use sliding contacts and a sectored contact disk attached to the shaft.   Fairly obviously, if an insulating sector is under a contact, it *can't* bounce low.  However it only takes a brief open circuit while the contact is on a conducting sector for it to bounce high, and any bounces on different channels that overlap look like a valid movement as I noted above.
 

Offline Peabody

  • Super Contributor
  • ***
  • Posts: 2106
  • Country: us
Re: Rotary encoder with PIC16F887 troubles
« Reply #31 on: January 09, 2023, 02:41:45 pm »
@paulca, lets say you have a 0111 valid transition.  But then the first line bounces back low temporarily.  When that happens you shift 0111 left and add in the bounce state, yielding 1101, which is invalid.  But then the line bounces back high again, and you shift left and add again, giving you 0111, which is another valid transition.  So you've recognized two valid transitions when only one (plus bouncing) has taken place.

If you follow all the transitions, looking to accumulate four in the same direction on arriving at a detent, only one valid tick would be recognized.  Even that method isn't perfect because the processor may not be able to recognize all the bouncing transitions if they occur fast enough, and it still suffers from having to service an interrupt on each bounce transition, which can really slow you down if you have a noisy encoder.  That's why I was working on enabling only one interrupt at a time, hoping to avoid any bounce-generated interrupts.  But I suspect a hardware solution is probably the best fix in the end.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf