Rotary Encoder Help
After posting in the general forum it seams to me this may have been the correct area to ask for assistance for my issue, original post is here:
http://forums.parallax.com/showthread.php/145613-Rotary-Encoder-Help
http://forums.parallax.com/showthread.php/145613-Rotary-Encoder-Help

Comments
Close, with an encoder, you need to consider not just valid states, but also how the states get from one to another.
eg Imagine your encoder is break-before-make, or you get one or more polls of 000, (or indeed, any 'illegal' combination ) - try that with a pencil thru your CASE statements, and see what the outcome is.
If you do have these resistors, which way? pulling up to the supply voltage, or pulling down to ground?
what value are these resistors?
with 3 inputs it's just a matter of patience as things will always settle out even with switch bounce.
Like if you're at the A state, and then the dial is turned to B, well eventually the B input is just going to be asserted, no matter how much B bounces or is delayed from the transition of A.
That is true for the pins, but not quite so true for a (poorly written) state-engine following those pins.
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 knob_offset = 8 ' The rotary encoder uses a modified rotary switch with 12 positions connected together as 3 groups of 4 ' knob_offset+1 = 9 ' Requires 3 pins to sense direction of rotation, offset is set to the lsb ' knob_offset+2 = 10 ' Clockwise rotation produces the pattern 011, 110, 101 (with common on ground and pullups on pins) VAR byte knob_pos PUB Main | counter knob_pos := knob_position ' Initialize knob position repeat if CW counter++ if CCW counter-- PRI Knob_position : pos pos := (ina >> knob_offset) & %111 PRI CW | c_pos c_pos := Knob_position if (c_pos == %011 and knob_pos == %110) or (c_pos == %110 and knob_pos == %101) or (c_pos == %101 and knob_pos == %011) knob_pos := c_pos result := 1 PRI CCW | c_pos c_pos := Knob_position if (c_pos == %011 and knob_pos == %101) or (c_pos == %101 and knob_pos == %110) or (c_pos == %110 and knob_pos == %011) knob_pos := c_pos result := 1It works great, though it requires three IO pins to read the knob. I later redesigned it to use only one pin with a RC circuit:{{ Determine the direction of a knob rotation using one pin and a RC circuit Knob is constructed using a modified 12-position switch 100Ω 100Ω 100Ω ──┳────────┳──┳─┳─ 1 │ │ ┣───┼─ 2 0.1µF ┣────┼───┼─ 3─────┐ │ │ │ ┣─ 4 │  │ ┣───┼─ 5  ┣────┼───┼─ 6 │ │ ┣─ 7 │ ┣───┼─ 8 ┣────┼───┼─ 9 │ │ └─10 │ └─────11 └──────────12 Set IO pin to output a high to charge the capacitor Wait for the capacitor to charge Clear a counter Set IO pin to an input Increment counter each clock tick that input remains above the logic threshold This produces readings of ~1051, ~1674, and ~2304 }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 Knob_pin = 16 VAR byte knob_pos OBJ FDS : "FullDuplexSerial" PUB Main | Counter FDS.start(31,30,0,115_200) waitcnt(clkfreq + cnt) ctra := 01000 << 26 | Knob_pin ' Set counter A to increment each 12.5ns that RC_pin is high frqa := 1 outa[Knob_pin]~~ knob_pos := Read_knob Counter := 0 FDS.tx($00) FDS.dec(counter) repeat if CW Counter++ FDS.dec(counter) FDS.tx($0D) if CCW Counter-- FDS.dec(counter) FDS.tx($0D) PRI Read_knob dira[Knob_pin]~~ ' Charge capacitor waitcnt(cnt + clkfreq / 1000) phsa := 0 dira[Knob_pin]~ ' Begin discharging repeat until not ina[Knob_pin] ' Wait for discharge case phsa 745..1375 : result := 1 1376..2005 : result := 2 2006..2635 : result := 3 PRI Read_avg : Average ' Only used to find the values Average := 0 repeat 1024 dira[Knob_pin]~~ waitcnt(cnt + 600) phsa := 0 dira[Knob_pin]~ repeat until not ina[Knob_pin] Average += phsa Average /= 1024 PRI CCW | c_pos c_pos := Read_knob if (c_pos == 2 and knob_pos == 1) or (c_pos == 3 and knob_pos == 2) or (c_pos == 1 and knob_pos == 3) knob_pos := c_pos result := 1 PRI CW | c_pos c_pos := Read_knob if (c_pos == 3 and knob_pos == 1) or (c_pos == 1 and knob_pos == 2) or (c_pos == 2 and knob_pos == 3) knob_pos := c_pos result := 1Thanks again!
-ADZ
This is the correct answer and you should always do this for cases like this.
When dealing with digital circuitry you have to drive in both directions. an input should either be at the level of the supply voltage (+5V, +3.3V, etc), or at ground level (0V). Never left floating. For hobbyist applications on microcontrollers, we just generally leave unused inputs floating, but in professional practice this is bad. It tends to waste power and amplify noise and send more noise into the adjacent circuits with all the almost-random toggling from 1 to 0 and back.
I know industrial equipment (PLC I/O) acts differently, where you can connect one side of a mechanical switch to the voltage source, and the other side to the input. Works perfectly where if the switch is closed, the input is read as a 1 because CURRENT is flowing, otherwise 0 because no significant current is flowing. But not with digital circuitry. Digital circuitry uses VOLTAGE to determine the 1 or 0.
ABC_Encoder.spin
I will continue to update as this project moves along.
Thanks Again!
-ADZ