Help with Quadrature encoder input and direction
hello all. i have a quadrature encoder that i want to use as a input device, its a oaks-grigsby optical encoder, (like a pot) with two outputs, (a and b). for the life of me i cant figure out how to read this thing with spin. im looking for a simple spin program that will take a and b on two pins and show a count number, incrementing in one direction, decrementing in the other, showing the result in PST. like if a then b = fwd cnt=cnt_1, if b then a = rev cnt=cnt-1 not looking for high speed or anything, just something simple where i (and others) may learn from. i seen the objects in the obex, but i think they are way more than what im needing. thanks in advance.:thumb:

Comments
Well ... you'll need to modify it slightly .. but this one reads my US Digital E4P encoder:
http://www.usdigital.com/products/encoders/incremental/rotary/kit/e4p/
... Tim
John Abshier
i seen that one, but im confused on how to use it for some reason. im thinking i need to call this object from another object, but im confused on the parameters, how and what do i pass the pin numbers then read the data from that object. this is my first time in spin trying to use an encoder and was hoping for something a little more 'idiot proof'. for me, calling on other objects other than pst or fds and i get lost quick.
Dang it, i didnt read down past the assembly code, i feel really dumb right now. sorry. i will try this and see what happens. thank you all for the help.
OBJ Encoder : "Quadrature Encoder" pst : "Parallax Serial Terminal" VAR long Pos[3] 'Create buffer for two encoders (plus room for delta position support of 1st encoder) PUB Init Encoder.Start(0, 1, 0, @Pos) 'Start continuous two-encoder reader (encoders connected to pins 8 - 11) pst.Start(115200) PUB Main repeat Pos[0] :=0 'Read each encoder's absolute position 'd :=Encoder.ReadDelta(0) 'Read 1st encoder's delta position (value since last read) pst.Str(String(pst#cs, pst#NL, pst#HM, "Counts ")) pst.Dec(Pos) 'pst.Dec(Delta)there is nothing showing up in pst. i am only using one encoder on pins 0 and 1.
change Pos[3] to Pos[4]
Encoder.Start(8, 2, 2, @Pos) pins start at pin 8. First encoder is 8&9, second is 10&11. 2 encoders, 2 deltas
I don't think that you are allowed to reset the data so remove the Pos[0] := 0 line
To get absolute position pst.Dec(Pos[0 or 1]
To get relative position pst.Dec(Encoder.ReadDelta(0 or 1))
If it reads in the wrong direction, going up when you want it to go down, physically reverse the wires.
John Abshier
PS. I am not familar with that specific encoder. It may require pull-ups or pull-downs on the a and b lines.
ok, im still not getting anything in pst, not even the "counts" string. i put 2.2k pull downs on the a and b outputs to pins 0 and 1, using a prop demo board.
CON _clkmode = xtal1 + pll16x 'Crystal and PLL settings. _xinfreq = 5_000_000 OBJ Encoder : "Quadrature Encoder" pst : "Parallax Serial Terminal" VAR long Pos[4] 'Create buffer for two encoders (plus room for delta position support of 1st encoder) PUB Init Encoder.Start(0, 1, 2, @Pos) 'Start continuous two-encoder reader (encoders connected to pins 8 - 11) pst.Start(115200) PUB Main | Go repeat pst.Str(String(pst#cs, pst#NL, pst#HM, "Counts ")) Pos := Pos[0] 'Read each encoder's absolute position 'Delta :=Encoder.ReadDelta(0) 'Read 1st encoder's delta position (value since last read) pst.Dec(Pos[0]) 'pst.Dec(Delta)CON _clkmode = xtal1 + pll16x 'Crystal and PLL settings. _xinfreq = 5_000_000 OBJ Encoder : "Quadrature Encoder" pst : "Parallax Serial Terminal" VAR long Pos[4] 'Create buffer for two encoders (plus room for delta position support of 1st encoder) PUB Main Encoder.Start(0, 1, 2, @Pos) 'Start continuous two-encoder reader (encoders connected to pins 8 - 11) pst.Start(115200) repeat waitcnt(clkfreq/10 + cnt) pst.Str(String(pst#cs, pst#NL, pst#HM, "Counts ")) Pos := Pos[0] 'Read each encoder's absolute position 'Delta :=Encoder.ReadDelta(0) 'Read 1st encoder's delta position (value since last read) pst.Dec(Pos[0]) 'pst.Dec(Delta)im still working on the delta part and will update when i get it resolved.
CON _clkmode = xtal1 + pll16x 'Crystal and PLL settings. _xinfreq = 5_000_000 OBJ Encoder : "Quadrature Encoder" pst : "Parallax Serial Terminal" VAR long Pos[4] long ReadDelta[4] 'Create buffer for two encoders (plus room for delta position support of 1st encoder) PUB Main dira[16..17]~~ Encoder.Start(0, 1, 1, @Pos) 'Start continuous two-encoder reader (encoders connected to pins 8 - 11) pst.Start(115200) repeat waitcnt(clkfreq/10 + cnt) '10Hz screen refresh pst.Str(String(pst#cs, pst#NL, pst#HM, "Counts ")) Pos := Pos[0] 'Read each encoder's absolute position pst.Dec(Pos[0]) pst.Str(String(pst#NL, "Delta ")) pst.Dec(Encoder.ReadDelta(0)) if (Encoder.ReadDelta(0)) > 1 outa[16]~~ if (Encoder.ReadDelta(0)) < -1 outa[17]~~ if (Encoder.ReadDelta(0)) ==0 outa[16..17]~one thing im trying now, if you look at the bottom of the code, im trying to have the leds 16 and 17 come on on the demo board, 16 come on when the delta is >1, led 17 come on when delta is <-1, both off when delta is 0 but i cant get that to work, i think im trying to read the varible wrong into the if statement. i've tried assigning a varible to (encoder.ReadDelta(0)) using this...
but i get an error when i hit f11, expected an instruction or varible with the word delta highlighted. Any thoughts on why this doesn't work or what im doing wrong?
John Abshier
i did but did it wrong, thanks for pointing me in the right direction, i really appreciate your help!
Here is the updated code for anyone interested...
CON _clkmode = xtal1 + pll16x 'Crystal and PLL settings. _xinfreq = 5_000_000 OBJ Encoder : "Quadrature Encoder" pst : "Parallax Serial Terminal" VAR long Pos[4] long Delta[4] 'Create buffer for two encoders (plus room for delta position support of 1st encoder) PUB Main dira[16..17]~~ Encoder.Start(0, 1, 1, @Pos) 'Start continuous two-encoder reader (encoders connected to pins 8 - 11) pst.Start(115200) repeat waitcnt(clkfreq/10 + cnt) '10Hz screen refresh pst.Str(String(pst#cs, pst#NL, pst#HM, "Counts ")) Pos := Pos[0] 'Read each encoder's absolute position pst.Dec(Pos[0]) pst.Str(String(pst#NL, "Delta ")) pst.Dec(Encoder.ReadDelta(0)) Delta := (Encoder.ReadDelta(0)) if Delta => 1 outa[16]~~ if Delta =< -1 outa[17]~~ if Delta ==0 outa[16..17]~