This discussion about rotary encoders has me fascinated and confused. I don't have one to play with and have never used one. I just might have to get one to tinker with. If I understand correctly two overlapping pulses are used to indicate movement and direction. Pulses indicate movement, the order of the pulses indicates direction. If so, it seems like there are two relatively simple ways to address this, both by treating the overlapping pulses as a single pulse for the count function. First in software, using a flag variable: Let's say you have this connected to PORTB bits 4,5 with interrupt on change enabled. flg is a variable with appropriate scope to persist over various interrupts and initialized to zero. tmp is a local variable in the interrupt routine. (Note: my editor keeps capitalizing things that shouldn't be. Ignore case.) tmp =3D PORTB & 0x30; // get the bits we are interested in Switch (tmp){ Case0x 10 : if(flg =3D=3D 0) flg =3D 1; rotation++; break; // only one bit must be first rising edge Case 0x20 : if(flg =3D=3D 0) flg =3D 1; rotation--; break; // only one bit must be first rising edge Case 0 : flg =3D 0; // last falling edge - cluster over } Ignore everything where flg =3D=3D 1. A better job could be done with a simple hardware solution: Connect the device to any available input pins without interrupt on change. Connect an isolation resistor from each to the MCU external hardware interrupt. Set the interrupt for rising edge. This interrupt will fire only on the first edge as the cluster of overlapping pulses will appear to it as a single pulse. Remove all flag references from the above interrupt routine. tmp =3D PORTB & 0x30; // get the bits we are interested in Switch (tmp){ Case 0x10 : rotation++; break; // no need to test, only triggers on first rising edge Case 0x20 : rotation--; =09 } If resources are scarce the second option would be much better. It only interrupts one quarter as many times and the interrupts do not have the overhead of testing and maintaining the flag variable. Allen > -----Original Message----- > From: piclist-bounces@mit.edu [mailto:piclist- > bounces@mit.edu] On Behalf Of Manu Abraham > Sent: Tuesday, June 11, 2013 2:28 PM > To: Microcontroller discussion list - Public. > Subject: Re: [PIC] Rotary encoder, another pair of eyes > would be helpful >=20 > On Tue, Jun 11, 2013 at 11:11 PM, Joe Wronski > wrote: > > On 6/11/2013 1:16 PM, Manu Abraham wrote: > >> On Tue, Jun 11, 2013 at 10:27 PM, Manu Abraham > wrote: > >>> On Tue, Jun 11, 2013 at 9:09 PM, Joe Wronski > wrote: > >>>> Since the enc_tab[] only contains -1,0,+1, the only > explanation I can > >>>> think of would be that you are actually getting 4x the > number of > >>>> interrupts that you think you are. Have you tried > setting breakpoints > >>>> in the interrupt or print_error_code() func to step > through the code? > >>>> Also, what happens when the count goes over 9 or > less than 0? You only > >>>> have 10 digits to print 16 possible values, and count is > unsigned. > >>> Right, array returns 1, -1 or 0 only. Interrupt is fired 4 > times for RBIF, > >>> PORTB change Interrupt. > >>> > >>> The display can show 0-9, so after a reset/powerup, it > starts with 0. :-) > >>> > >>> I guess, I understand what's happening. > >> Ditched the array, looking directly at the mechanical > states. > >> Retained the small debouncing counter, It feels better > turning the knob with > >> this debouncing in there. > >> > >> Simplified the code to look thus: http://goo.gl/sjrlF > >> > >> Thanks to all the people, who helped to helped to shoot > this bug down. :-) > >> Hope the code snippet will be useful to someone, > trodding this path again. > >> > >> > >> Thanks, > >> > >> Manu > > I don't know why I started following this, maybe because I > had done some > > rotary encoder code before (and promptly forgot how it > worked). > > The new way better, because you're only using 1of the 2 > encoder bits. > > I think you're throwing away either resolution or state > information by > > ignoring the value of ENC_B. > > But, I suppose ENC_B contributes an interrupt, so it's not > as thought > > it's not there at all. >=20 > Resolution looks fine. Spinning it as fast as I can (connected > the OLED > display), Can see the charset on the display for each count > increment/decrement, > as expected even when rotating the encoder really really > fast. No glitches and > or lost counts, or reverse counts. Works just as expected. >=20 > There are 4 interrupts, due to 4 changes, due to 4 logic > states. All the logic > states are handled. In any case, you cannot change the > counter for all the 4 > states, but only for the 2 states. So, I guess things look okay > for now. >=20 > Regards, >=20 > Manu > -- > http://www.piclist.com/techref/piclist PIC/SX FAQ & list > archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist --=20 http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .