encoder wowes


Closed Thread
Results 1 to 17 of 17

Thread: encoder wowes

  1. #1
    Join Date
    Jul 2005
    Posts
    11

    Default encoder wowes

    G'day forum people

    I have a small problem getting a dual encoder from ALPS to work, it is the type that when you go right, both outputd rise or fall, one slightly in front of the other, depending on direction. I found some excellent code examples from the archives here but it does funny things.
    The counter which increments or decrements depending on how many times you rotate seems to jump up in 2's, i.e 1000 - 1002 - 1004
    I have spent 3 days trying to get it to count up in 1's ( or down ).

    I am new to programming, mainly an RF hardware guy - this is probably something real simple, can anyone work it out. This is for a ham radio project that when finished I will gladly display the full code. The PLL is an LMX2306 for use on 144 Mhz.

    Hope its O.K to post a long post, cheers from Queensland, Australia

    Code follows:

    '************************************************* ***************
    '* Name : 2 metre _PLL.BAS *
    '* Author : [Nigel Andrews] *
    '* Notice : Original encoder code based on picbasic forum *
    '* Date : 12/07/2005 *
    '* Version : 1.0 *
    '* Notes : Attempt to write some code that outputs bits to *
    '* : the LMX2306 PLL in conjunction with displayed *
    '* : LCD frequency, remember to add 21.4 Mhz offset *
    '* : for the receiver Intermediate Frequency *
    '* : *
    '************************************************* ***************


    '************************************************* ***************
    ' *
    'LCD commands *
    ' *
    'Command Operation *
    ' *
    '$FE, 1 Clear display *
    '$FE, 2 Return home (beginning of first line) *
    '$FE, $0C Cursor off *
    '$FE, $0E Underline cursor on *
    '$FE, $0F Blinking cursor on *
    '$FE, $10 Move cursor left one position *
    '$FE, $14 Move cursor right one position *
    '$FE, $C0 Move cursor to beginning of second line *
    '$FE, $94 Move cursor to beginning of third line *
    '$FE, $D4 Move cursor to beginning of fourth line *
    '$FE, $18 Shift entire line left one position *
    ' *
    '************************************************* ***************

    ' DEVICE IS A 16F877 AT 4MHZ


    DEFINE LOADER_USED 1 'bootloader software


    clear

    ' Port allocations:
    ' Port A LCD Port
    ' A.0 - DB4 on LCD
    ' A.1 - DB5 on LCD
    ' A.2 - DB6 on LCD
    ' A.3 - DB7 on LCD
    ' A.4 - Register Select ( R/S )
    ' A.5 - Enable ( E )

    ' Note LCD is in 4 bit mode, R/W tied to ground ( Write only )

    ' Port B

    ' B.0 - Do not use, used by code to calculate encoder position by bit swapping
    ' B.1 - Do not use, used by code to calculate encoder position by bit swapping
    ' B.2 - B2 Encoder tied high
    ' B.3 - B1 Encoder tied high
    ' B.4 - A2 Encoder tied high (Low voltage programming - PGM )
    ' B.5 - A1 Encoder tied high
    ' B.6 - not allocated (ICSP Clock - PGC )
    ' B.7 - not allocated (ICSP Data - PGD )
    ' *Note - ICD inputs are switched from ICSP programming to encoder with a 3 pole switch

    ' Port C

    ' C.6 - RS-232 Transmit ( also used for loading program using bootloader )
    ' C.7 - RS-232 Receive ( also used for loading program using bootloader )



    ' LCD SETUP DEFINES


    define LCD_DREG PORTA ' set LCD data port
    DEFINE LCD_DBIT 0 ' set starting bit ( 0 or 4 ) if 4 bit bus
    dEFINE LCD_RSREG PORTA ' set LCD register select port
    DEFINE LCD_RSBIT 4 ' set LCD register select bit
    DEFINE LCD_EREG PORTA ' set LCD enable port
    DEFINE LCD_EBIT 5 ' set LCD enable bit
    DEFINE LCD_BITS 4 ' set LCD bus size ( 4 or 8 bits )
    DEFINE LCD_LINES 2 ' set number of lines on LCD
    DEFINE LCD_COMMANDUS 2000 ' set command delay time in us
    DEFINE LCD_DATAUS 50 ' set data delay time in us


    'encoder setup

    zFlags var byte
    Changed var zflags.0

    OldA var byte ' Previous state of encoder A bits
    NewA var byte ' Current state of encoder A bits
    DirectionA var bit ' Direction of encoder A travel; 1=CCW.
    zza6 var NewA.0 ' the first bit
    zza15 var OldA.1 ' the second bit
    PositionA var word ' To hold position count 0 to 65536

    OldB var byte ' Previous state of encoder B bits
    NewB var byte ' Current state of encoder B bits
    DirectionB var bit ' Direction of encoder B travel; 1=CCW.
    zzb6 var NewB.0 ' the first bit
    zzb15 var OldB.1 ' the second bit
    PositionB var word ' To hold position count 0 to 65536

    true con 1
    false con 0

    PositionA = 1000 'initialize position A counter
    PositionB = 1000 'initialize position B counter


    Init:
    adcon1 = 6 'set porta to digital I/O
    trisa = %00000000 'set porta to outputs
    trisb = %11111111 'set portb to inputs


    lcdout $fe,1 ' Clear LCD
    pause 1000 ' 1 second delay

    lcdout $fe,$80,#DirectionA," ",#positionA 'display 0 or 1 on top line encoder A
    '0 = right, 1 = left plus position count

    lcdout $fe,$c0,#DirectionB," ",#positionB 'display 0 or 1 on bottom line encoder B
    '0 = right, 1 = left plus position count

    MainLoop:

    OldA = newA
    OldB = newB
    Changed = false


    Again:

    NewA = PortB & %00110000 'copy encoder bits to NewA
    NewB = PortB & %00001100 'Copy encoder bits to NewB
    NewA = NewA >> 4 'shift input of PortB the first and second bit
    'comment, does this mean that bits 0 and 1 cannot
    'be used for other I/O usage?

    NewB = NewB >> 2 'shift input of PortB the third and fourth bit
    'again, does this mean that bits 0 and 1 cannot
    'be used for other I/O usage?
    IF NewA <> OldA Then Gosub ChangedA
    IF NewB <> OldB Then Gosub ChangedB
    if Changed = false then Again

    lcdout $fe,1
    lcdout $fe,$80,#DirectionA," ",#positionA 'display 0or1 on top line encoder A
    '0 = right, 1 = left plus position count

    lcdout $fe,$c0,#DirectionB," ",#positionB 'display 0or1 on bottom encoder B
    '0 = right, 1 = left plus position count


    Goto mainloop


    'The following checks the direction and increments/decrements the counter
    'note the counter goes in reverse, this is because the encoder is wired
    'in reverse, final version will be corrected to line up with code

    ' Current BUG - counter counts by 2! cannot get it to count up by 1
    ' if you partially rotate the encoder it will increment up or down by 1 but this
    ' is not its normal operation, it appears the software does not like 2
    ' rising or falling edges even though one leads the other.

    ChangedA:

    DirectionA = zza6 ^ zza15 'XOR right bit of new w/ left bit of old.
    'give 1 if the two bits are different,
    'and 0 if they are the same.


    IF DirectionA = 1 Then 'first bit and second bit are different

    PositionA = PositionA -1 'Currently increments counter up by 2

    else
    PositionA = PositionA + 1 'Currently decrements counter down by 2
    pause 5
    endif
    Changed = true
    Return

    ChangedB:

    DirectionB = zzb6 ^ zzb15 'XOR right bit of new w/ left bit of old.
    'give 1 if the two bits are different,
    'and 0 if they are the same.

    IF DirectionB = 1 Then
    PositionB = PositionB - 1 'Currently increments counter up by 2


    else
    PositionB = PositionB + 1 'Currently decrements counter down by 2
    pause 5
    endif
    Changed = true
    Return


    end

  2. #2
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default

    wallaby, This is a subroutine I use for the 6 channel repeater voter I designed. The A and B outputs from the rotary encoder are wired to port pins 0 and 1 respectively. The varaible KNOBLIM is used for a maximum rollover count ie(KNOBLIM to 0) and a underflow count ie(0 to KNOBLIM) and this variable can not be greater than 65535. The variable MULTIPLY is to be set for 1,10,100,1000,10000 to be used for incrementing or decrementing individual digits of the variable to be manipulated. The variable UPDOWN can be preloaded with a starting target value before calling the routine. As for the direction of the knob rotation as far as incrementing or decrementing the variable, just switch the A and B input wires of the encoder to adjust which input edge leads the other.

    OFS VAR BYTE 'ENCODER + or - COUNT
    TEMP1 VAR BYTE 'ENCODER SCRATCH VARIABLE
    TEMP2 VAR BYTE 'ENCODER SCRATCH VARIABLE
    KNOBLIM VAR WORD 'UP-DOWN COUNTER LIMIT
    UP_DOWN VAR WORD 'COUNTER PASS VARIABLE
    MULTIPLY VAR BYTE 'KNOB MULTIPLIER FOR SPEED

    '************************************************* ********************
    ENCOD: 'READ ROTARY ENCODER POSITION
    '************************************************* ********************
    TEMP2 = TEMP1 | (PORTD & %00000011)
    LOOKUP TEMP2,[2,3,1,2,1,2,2,3,3,2,2,1,2,1,3,2],OFS
    TEMP1 = (TEMP2 << 2) & %00001100
    UP_DOWN = UP_DOWN + ((OFS * MULTIPLY) - (2 * MULTIPLY))
    IF UP_DOWN = (KNOBLIM + MULTIPLY) THEN UP_DOWN = 0
    IF UP_DOWN > KNOBLIM THEN UP_DOWN = KNOBLIM
    MULTIPLY = 1
    RETURN

    Usage:
    TEMP1 = (PORTD & %00000011) << 2 'only executed once to preload temp1

    MODEX: 'SETUP KNOB TO SELECT WHICH ROUTINE
    UP_DOWN = PROGRAM 'Preset for current porgram
    KNOBLIM = 6 'SET PROGRAM NUMBER SELECTION LIMIT
    GOSUB ENCOD 'READ ENCODER
    PROGRAM = UP_DOWN
    IF OLDPRG <> PROGRAM THEN 'IF THE SAME THEN DON'T RE-DISPLAY
    OLDPRG = PROGRAM
    GOSUB DSPSEL 'IF NEW SELECTION THEN DISPLAY IT
    ENDIF

    Dave Purola,
    N8NTA
    Last edited by Dave; - 14th July 2005 at 18:33.

  3. #3
    Join Date
    Jul 2005
    Posts
    11


    Did you find this post helpful? Yes | No

    Default encoder help

    Thanks Dave, will give it a go and see what happens.

    Cheers

    Nigel VK4FNA

  4. #4
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default

    wallaby, First place these declarations at the top of your program:

    ' LCD SETUP DEFINES
    DEFINE LCD_DREG PORTA ' set LCD data port
    DEFINE LCD_DBIT 0 ' set starting bit ( 0 or 4 ) if 4 bit bus
    DEFINE LCD_RSREG PORTA ' set LCD register select port
    DEFINE LCD_RSBIT 4 ' set LCD register select bit
    DEFINE LCD_EREG PORTA ' set LCD enable port
    DEFINE LCD_EBIT 5 ' set LCD enable bit
    DEFINE LCD_BITS 4 ' set LCD bus size ( 4 or 8 bits )
    DEFINE LCD_LINES 2 ' set number of lines on LCD
    DEFINE LCD_COMMANDUS 2000 ' set command delay time in us
    DEFINE LCD_DATAUS 50 ' set data delay time in us

    '******** DEFINE VARIABLES **********
    OFS VAR BYTE 'ENCODER + or - COUNT
    TEMP1 VAR BYTE 'ENCODER SCRATCH VARIABLE
    TEMP2 VAR BYTE 'ENCODER SCRATCH VARIABLE
    KNOBLIM VAR WORD 'UP-DOWN COUNTER LIMIT
    UP_DOWN VAR WORD 'COUNTER PASS VARIABLE
    MULTIPLY VAR BYTE 'KNOB MULTIPLIER FOR SPEED

    '*********** INITIALIZE VARIABLES ************
    Multiply = 1 'set multiplier to 1
    Variable = 100 'set variable initially to value of 100
    Knoblim = 1000 'set maximum rollover to occur at 1000
    TEMP1 = (PORTB & %00000011) << 2 'only executed once to preload temp1


    Next, run this code and then rotate the encoder
    to see the action. By the way don't forget the A and B outputs from the rotary encoder are wired to PORTB pins 0 and 1 respectively.

    loop:'
    UP_DOWN = Variable 'make current position equal to value of variable
    GOSUB ENCOD 'READ ENCODER
    Variable = UP_DOWN 'add up/down count to variable
    lcdout $FE,$02,DEC5 Variable
    goto loop


    '*************************************************
    ENCOD: 'READ ROTARY ENCODER POSITION SUBROUTINE
    '*************************************************
    TEMP2 = TEMP1 | (PORTB & %00000011)
    LOOKUP TEMP2,[2,3,1,2,1,2,2,3,3,2,2,1,2,1,3,2],OFS
    TEMP1 = (TEMP2 << 2) & %00001100
    UP_DOWN = UP_DOWN + ((OFS * MULTIPLY) - (2 * MULTIPLY))
    IF UP_DOWN = (KNOBLIM + MULTIPLY) THEN UP_DOWN = 0
    IF UP_DOWN > KNOBLIM THEN UP_DOWN = KNOBLIM
    MULTIPLY = 1
    RETURN

    Dave Purola,
    N8NTA

  5. #5
    Join Date
    Jul 2005
    Posts
    11


    Did you find this post helpful? Yes | No

    Default reply to dave

    Thanks Dave, I owe you a beer! Will try this out and post results. The 2 metre receiver works a treat, better than .2uv for 12 db sinad and the frontend tracks nicely. It will cover 108 to 161 Mhz.

    Cheers from Oz

    Nigel Andrews

  6. #6
    Join Date
    Jul 2005
    Posts
    11


    Did you find this post helpful? Yes | No

    Default Reply to Dave 2

    Dave,

    I tried it out and it is counting nicely, but still in increments of 2! It seems to think that the encoder has transitioned twice ( both going high, albeit one in front of the other ) so it goes up by 2. If you carefully half turn the encoder and make one input go up on its own, it then goes up by one. As soon as you let go and the other goes up, it counts up by one again.

    If you can give me a mailing address in the US I will post one off to you free, they are quite a nice encoder and I have a few spare. If you like you can email me direct at [email protected] with your address and I will send it. Might come in handy for a project of yours in the future.

    Otherwise I will keep playing around with the test one here.

    Cheers

    Nigel

  7. #7
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default

    Thanks Nigel, I just emailed you my address.

  8. #8
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default

    wallaby, I just received the encoder yesterday and it sure looks cool... You didn't tell me that it had a pushbutton on it as well. I'll hook it up this weekend and get back to you on Monday. Once again thanks....

    Dave Purola,
    N8NTA

  9. #9
    Join Date
    Jul 2005
    Posts
    11


    Did you find this post helpful? Yes | No

    Default encoder

    O.K , glad to see it arrived safely.

    Cheers

    Nigel

  10. #10
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default

    Nigel, After hooking up the encoder you sent me and looking at it with a scope I found it is working as advertised. I went to the ALPS website and lo & behold the documentation says it has detents on every other (2 of the 4 states) of the encoder output. That is why the encoder seems to be counting by 2 because it actually is. Attached is the waveform for the output of the encoder at the detents. The suggested connection is 5 volts thru a 10k to the switch. Then a 10k from the switch in series with a .01uF to ground with the connection of the 10k and the .01uF going to the processor. This provides a filter mechanism to counter act any switch bounce that may occure due to the nature of the rotary switch. Once again, Thanks Nigel....

    Dave Purola,
    N8NTA
    Attached Images Attached Images  

  11. #11
    Macgman2000's Avatar
    Macgman2000 Guest


    Did you find this post helpful? Yes | No

    Default

    Hello Wallaby,

    Are you posting the hardware schematic of the radio? I tinker with receivers also. I am always looking to learn something new!!!

    Best Regards,
    Nick
    KC6SDF
    Last edited by Macgman2000; - 3rd August 2005 at 17:04.

  12. #12
    Join Date
    Jul 2005
    Posts
    11


    Did you find this post helpful? Yes | No

    Default encoder

    Hi Dave,

    O.K on the encoder, did you manage to get it to go up by one, even though it has two steps for one turn? or does the cap R/C take care of this.

    Yes when the receiver goes I will, it uses a commercial VCO module which is custom made so you would need to insert your own design. The front end is fairly standard, using BF998 RF and IF, BB814 varactors and toko SMD coild. The 21.4 IF has a 25 khz 8 pole filter, the receiver chip is the toko 10931V. These were chosen because they had AM, and the receiver tunes 118 to 137 mhz as well.

    Cheers

    Nigel

  13. #13
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default

    Nigel, With the routine I gave you it decodes all 4 states of the encoder so what has to be done is a divide by 2 on the final variable. This can be accomplished by a shift statement ">> 1".

    Dave Purola,
    N8NTA

  14. #14
    Join Date
    Jul 2005
    Posts
    11


    Did you find this post helpful? Yes | No

    Default encoder

    O.K, will try it and see.

    Nigel

  15. #15
    G8RPI's Avatar
    G8RPI Guest


    Did you find this post helpful? Yes | No

    Default

    Hi,
    just a rider,
    I've been looking at the ALPS encoders and it would appear that they have a design feature that departs from the classic quadrature encoder.
    The contacts require a 10K pull-up to Vdd and go low when the shaft is rotated. Rather than maintain the low state, both outputs go open when the shaft is in the detent position. This reduces the power consumption by 500uA (0.5mA) when the encoder is idle, significant power in battery operated designs. This also gives the two pulse per click characteristic. There was nothing wrong with your code.

    Robert G8RPI.

  16. #16
    Join Date
    Jul 2005
    Posts
    11


    Did you find this post helpful? Yes | No

    Default encoder

    Thanks Robert, it sort of makes sense now and yes there is a position where it stays high, or low. They are a very reliable pot, we have used well over 6000 in our radios over the years with very little trouble.

    Cheers

    Nigel , VK4FNA

  17. #17
    stefano's Avatar
    stefano Guest


    Did you find this post helpful? Yes | No

    Default lmx2306 info

    Hi, I am Stefano from Italy, I am interested to the construction of a vfo pll with lmx2306.
    Is possible to have .bas code and circuit project ?

    Thanks & regards.

    Stefano Dian.

Similar Threads

  1. Reading incremental encoder interupt
    By RFsolution in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 1st March 2017, 13:50
  2. Quadrature encoder and ASM Interrupts. questions..
    By godfodder in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 17th March 2013, 15:45
  3. Instant Int and encoder (Elect. Gearing)
    By boroko in forum mel PIC BASIC Pro
    Replies: 13
    Last Post: - 29th November 2009, 03:29
  4. Reset timer / encoder transition
    By DJEE in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 22nd June 2007, 15:37
  5. encoder HEDL 5540
    By kutsi in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 11th June 2007, 15:00

Members who have read this thread : 3

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts