2-bit Gray rotary encoder code example

vertigo

Member
Copied from the Active Forum

Hello,
I have purchased the 2-bit rotary encoders described in this thread, but I could not find a correct way of using them in the forum (I am sorry if I have missed some threads) : None of the code examples posted, that I have tried, gave me a usable result.
So, after some tests, I finally wrote this small piece of code that works perfectly with the above rotary encoders. The program has been written and tested on a 08M, but should run on any Picaxe. In this example, the program detects the rotation direction and increment or decrement a counter.
I have also included some comments.
I hope this will help.

Code:
'picaxe 08M
'
'           +V 1 U 8 0V
'    GND - 10K 2   7 (0) OUT
' I/O/ADC4 (4) 3   6 (1) I/O/ADC1 --- rotary encoder
'   IN3    (3) 4   5 (2) I/O/ADC2 --- rotary encoder
'
' b1  b0 b3  b2 b5  b4 b7  b6 b9  b8 b11 b10 b13 b12
' --w0-- --w1-- --w2-- --w3-- --w4-- --w5--- --w6---

'b0 = bit7  : bit6  : bit5  : bit4  : bit3  : bit2  : bit1 : bit0
'b1 = bit15 : bit14 : bit13 : bit12 : bit11 : bit10 : bit9 : bit8

#rem

Rotary encoder connection:

                0V
                |
               4.7K (pull down resistor)
                |
encoder pin1 o--.----o Picaxe 08M pin1 (physical 6)
encoder pin2 o--R330-- +5V
encoder pin3 o--.----o Picaxe 08M pin2 (physical 5)
                |
               4.7K (pull down resistor)
                |
                0V

Encoder result (early detection):
pin1 pin2
  1    0  one direction
  0    1  other direction
  0    0  init and final (= "detent") status

One direction: pin1 goes high before pin2
         ___     ___
pin1 ___|   |___|   |___
           ___     ___
pin2 _____|   |___|   |___

Other direction: pin2 goes high before pin1
           ___     ___
pin1 _____|   |___|   |___
         ___     ___
pin2 ___|   |___|   |___

#endrem

'           Used bits                                          xxxx   xxxx
symbol getBits   = b0 'b0 = bit7 : bit6 : bit5 : bit4 : bit3 : bit2 : bit1 : bit0
symbol dir       = b1
symbol counter   = b3

setint %00000010,%00000010 'interrupt on pin1 high only

main:
  do
   sertxd("Main loop - Counter=",#b3,13,10)
   pause 1000
  loop
  
interrupt:
 bit2 = pin2: bit1 = pin1       'save rotary encoder pins status
 getBits = getBits & %000000110 'isolate rotary encoder pins
 if getBits <> 0 then           'if both pins are low, the direction is undetermined: discard
  dir = bit2 * 2                'direction: if bit2=low then dir=0; if bit2=high then dir=2
  counter = counter - 1 + dir   'change counter variable accordingly
  do while getBits <> 0         'wait for the encoder to go to the next "detent" position
   getBits = pins & %000000110
  loop
 endif
 setint %00000010,%00000010     'restore interrupt on pin1 high
 return
Regards,
Christophe
 
Top