PDA

View Full Version : Rotary encoders



mister_e
- 12th October 2004, 03:11
Hi,
is there anybody who have a snippet of code to increase/decrease value of a variable by a rotary encoder.

I did one who works perfectly one a gray code based rotary encoder but the rotary encoder was so simple to use. 1 gray code change by shaft step.

The new one i have now do half of gray code change by shaft step.

example in clockwise turning:

initial state : 00
01
one step later: 11
10
one step later: 00

any idea ??

regards

mister_e
- 12th October 2004, 03:35
O.K. after reading my post i realize how stupid i'm now ;(

encoder is connect to PORTD.0 and PORTD.1

here's the code:




value=127

GetInitial:
OldPos = PORTD & $3
NewPos=OldPos

while (NewPos==0) or (NewPos==3)
NewPos = portd & $3
wend

select case NewPos
case 1
select case OldPos
case 0
value=value+1
case 3
value=value-1
end select
case 2
select case OldPos
case 3
value=value+1
case 0
value=value-1
end select
end select

lcdout $fe,$c0,dec value
goto GetInitial


Any improvement will be apreciate. But it works really well

sorry for that

regards

Dwayne
- 12th October 2004, 14:27
Hello Mister_e,

M>>O.K. after reading my post i realize how stupid i'm now ;(


Well, it works like this Mister_e... I have done this so many times, and I know it won't be the last time I do it <g>. Welcome to the Titanic... we can all have fun together laughing at what we do as we sink.

Dwayne

mister_e
- 12th October 2004, 17:59
Hi Dwayne,
yes you're right. Since i program thos PIC i don't know how many times it happen to me and of course it will happen again since every project are different too.

But this time, i was really disapointed of me. Usualy i figure out every conditions on paper... but not this time.

So when i read back my post, i realize how simple and clear it was to do. After a few minute of crying... i finally laugh of me....

regards

CocaColaKid
- 21st February 2007, 15:42
Steve,

Could you explain this code for me as I'm a whole lot green on these things. I have one connected and it works great but I have to connect 5 of them and need to know what everything actually does first before I can adjust the code properly.

Thanks,
Paul

mister_e
- 21st February 2007, 16:57
a blast from the past ;)

Well, i thought it was self explained but anyways. The actual monitor the encoder initial state, store them in a variable (OldPos) and then spin in round until the value change. Most encoder use the gray code.
http://en.wikipedia.org/wiki/Gray_code

now you need to know the direction, this is done by when you compare the NewPos and OldPos.

here's another version with a littlt bit more comments 'round.


'
' ////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
'
GetEncoder:
' ===========
'
' Procedure to get value change from rotary encoder
' 1. Read variant of rotary encoder (move, enter pushbutton)
' 2. Store result in 'MenuChoice' & 'MenuPointer' variables
'
' Resume conditions:
' ------------------
' 1. Encoder Move
' 2. PBEnter button is pressed
' 3. User move to previous menu
'
' ////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
'
OldPos = (PORTB & %11000000)>>6 ' get only PORTB<7:6> bits
NewPos = OldPos
'
' -----------------------------------------------------
' see if encoder has move or if ENTER button is pressed
' -----------------------------------------------------
while ((NewPos==0) or (NewPos==3)) and PBEnter
NewPos = (PORTB & %11000000)>>6 ' get only PORTB<7:6> bits
wend
pause 20 ' debounce delay
'
' --------------------
' Get encoder movement
' --------------------
'
' Rotary encoder output table (clockWise rotation):
' -------------------------------------------------
' 00
' 01 between move (half detent)
' 11
' 10 between move (half detent)
'
' Using XOR
'
' OldPOS : 0 0 3 3
' NewPos : 1 2 1 2
' movement : CW CCW CCW CW
' XOR -------------------------------
' 1 2 2 1
'
' So, if NewPos XOR OldPos = 1 => increment
' Newpos XOR OldPos = 2 => Decrement
'
Newpos=newpos ^ oldpos
select case newpos
'
case 1
menuchoice=menuchoice+1
Menupointer=menupointer+1
'
case 2
menuchoice=menuchoice-1
Menupointer=menupointer-1
'
end select
'
' ---------------------------
' test the actual menu choice
' ---------------------------
' if higher than the maximum menu item... stay there
'
If menuchoice > Item then
menuchoice = Item
menupointer = thisSCREENLINES
endif
return

For 5 different encoder, you'll have to read ALL related encoder i/o in oneshot, determine which one has moved, and in which direction. mmm

depending what else your program need to do, make sure you never miss any movements. you have to read and react really fast. Assembler could be handy here. For a background process, as you need 10 interrupts source, it's not going to be really easy.

Sometimes it's handy to have few different dedicated controller for that.