fl hex { PropForth5.2 Rotary Encoder driver 20/09/2012 23:32:37 PullUpresistor 10kohm between A_phase and 3.3V ----------------------- | | A_phase |------------- P12 |Rotary Encoder Common |------------- Gnd | B_phase |------------- P13 ----------------------- | PullUpresistor 10kohm between B_phase and 3.3V There are many type on Encoder's terminal. Please check your Encoder's terminal. Gnd might be not center. ----------> CW 20132013201320 <-- 2bit binary A_phase 00110011001100 B_phase 10011001100110 CCW <-------- prev current status 0 0 stop 0 1 CW 0 2 CCW 0 3 invalid 1 0 CCW 1 1 stop 1 2 invalid 1 3 CW 2 0 CW 2 1 invalid 2 2 stop 2 3 CCW 3 0 invalid 3 1 CCW 3 2 CW 3 3 stop } C wconstant A_phase D wconstant B_phase wvariable encoder_tbl -2 allot 0 c, 1 c, 2 c, F c, 2 c, 0 c, F c, 1 c, 1 c, F c, 0 c, 2 c, F c, 2 c, 1 c, 0 c, \ Encoder's previous value wvariable prev 0 prev W! \ encoder counter variable counter 0 counter L! wvariable dir \ read rotary_encoder ( -- n1 ) n1:read value : read_encoder ina COG@ A_phase rshift 3 and ; \ update counter for rotary_encoder ( -- ) : encoder begin read_encoder \ read encoder-value begin \ check encoder-rotate read_encoder dup rot <> if 1 else 0 then until dup 3 delms read_encoder = \ eliminate chattering if 1 else drop 0 then until dup prev W@ 2 lshift encoder_tbl + + C@ \ get CW/CCW/stop from table dup 4 < if dup 1 = if drop 1 \ cw else 2 = if -1 \ ccw else 0 \ stop then then swap prev W! dup dir W! \ save direction counter L@ + counter L! \ save counter else 2drop \ invalid then ; : check_encoder begin encoder 0 until ; \ Display Encoder's value to character-LCD (using 2_wire_LCD_sr(8bit)_1.1) : Encoder \ init encoder 0 counter L! read_encoder prev W! \ read initial value c" check_encoder" 5 cogx \ init lcd lcd_init 10 4 lcd_setup \ 16characters 4line c" Rotary Encoder" lcd_str begin 1 2 lcd_pos c" " lcd_str 1 2 lcd_pos counter L@ lcd_dec 6 2 lcd_pos dir W@ dup 0= if drop c" stop" else 1 = if c" CW" else c" CCW" thens lcd_str 32 delms fkey? swap drop until 5 cogreset ; { \ Display TeraTerm terminal : test 0 counter L! read_encoder prev W! \ read initial value c" check_encoder" 5 cogx begin counter L@ . dir W@ dup 0= if drop ." stop" else 1 = if ." CW" else ." CCW" thens cr fkey? swap drop until 5 cogreset ; } decimal