I've had good experience using the following method (probably only fast enough for a human-turned encoder rather than a motor-driven one): First, you have a timer, let's call it TimerA. TimerA should be decremented once per millisecond inside a timer ISR. If it reaches zero, the ISR will not decrement it further. In your main loop, you keep three registers: last_measurement, state, and last_state. Let encoder_measurement be the A and B channels together as a two bit numbe= r. The rest I will explain in pseudocode: // Init code // Note: make sure that TimerA is set as a volatile variable so that both the ISR and the main loop can access it. state=3Draw_inputs() last_state=3Dstate last_measurement=3Dstate // Main loop starts here main: last_state=3Dstate encoder_measurement=3Draw_inputs() disable_interrupts // to prevent accessing TimerA at the same time as the I= SR if last_measurement !=3D encoder_measurement then TimerA=3D20 else if TimerA =3D=3D 0 then state=3Dlast_measurement enable_interrupts if state !=3D last_state then // Change happened { if last_state.A=3D=3D0 and state.A=3D=3D1 then { if state.B=3D=3D0 then DoClockwise() else DoCounterClockwise() } else if last_state.A=3D=3D1 and state.A=3D=3D0 then { if state.B=3D=3D0 then DoCounterClockwise() else DoClockwise() } else if last_state.B=3D=3D0 and state.B=3D=3D1 then { if state.A=3D=3D0 then DoCounterClockwise() else DoClockwise() } else { if state.A=3D=3D0 then DoClockwise() else DoCounterClockwise() } } last_measurement=3Dencoder_measurement goto main This waits 20 milliseconds from the last change before doing anything. It then uses simple comparison of previous and current A and B states to determine what change just happened. I'm sure that the if statements can be greatly simplified by using logical bit manipulations but I did it in a very easily readable format. Sean On Sat, Sep 5, 2009 at 9:17 PM, Bob Axtell wrote: > Actually, interrupt on change is just about the only way to make quad > encoding work. Set the PIC up to capture a change on both the A and > the B pins. When you get into the routine, immediately read repeatedly > until you get 3-5 SAME results on BOTH A and B. The XOR with old > state, etc as is needed. I think you will see things clear up. > > --Bob > > On Sat, Sep 5, 2009 at 5:58 PM, Josh Koffman wrote: >> On Sat, Sep 5, 2009 at 8:36 PM, Ray wrote: >>> Josh, >>> I was doing 4 quadrant decoding of a rotary encoder on a motor back in = the 70's >>> The problem is when the encoder rests on an edge instead of off 45 degr= ees. >>> On an edge the dithering =A0of +1/-1 can be very high frequency in X4 m= ode. >>> that means you need to do interrupt on edge (plus & minus) of both chan= nels. >>> I would guess that is the mode you are in. >>> That give you the most steps per revolution. >>> X2 is easier and X1 more so if you do not mind less steps per revolutio= ns. >>> >>> 3x means you are not keeping up with changes. >>> >>> I could draw you a logic drawing for X1/X2/X4 that you can convert to l= ogic. >>> Or a truth table. >>> Let me know. >> >> Hi Ray, >> >> I think I sort of understand what you're getting at. I'm not 100% sure >> how it applies to me though. My data sheet shows that at each detent >> my B channel should be transitioning. I'm not sure interrupt on change >> is a possibility in my situation. >> >> So...I guess what I'm saying is that I'm confused. Help! >> >> By the way, my current thought is to try feeding the port with my >> encoders on it through my debounce routine to see what happens if I >> verify all the current states. My only concern is that this might not >> be fast enough to capture a quickly moving knob (which isn't that >> quick, these are user controls, not on a motor). I'd still like to >> know for sure why this is happening though. >> >> Thanks! >> >> Josh >> -- >> A common mistake that people make when trying to design something >> completely foolproof is to underestimate the ingenuity of complete >> fools. >> =A0 =A0 =A0 =A0-Douglas Adams >> >> -- >> http://www.piclist.com PIC/SX FAQ & list archive >> View/change your membership options at >> http://mailman.mit.edu/mailman/listinfo/piclist >> > > -- > http://www.piclist.com PIC/SX FAQ & list archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist > -- = http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist