Can PBP read optical encoder damn fast? :)


Closed Thread
Results 1 to 40 of 47

Hybrid View

  1. #1
    Join Date
    Feb 2013
    Posts
    1,125


    Did you find this post helpful? Yes | No

    Default Re: Can PBP read optical encoder damn fast? :)

    Yes I see 150Hz limitation. But as said above, I'd like to test idea first, if it is working at all.

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Can PBP read optical encoder damn fast? :)

    I couldn't help myself, had to see what I could do with just some simple, basic (no pun intended) coding. No interrupts, no hardware assist, no inline assembly language, just 33 line loop of straight PBP.

    On an 18F4520 running at 20MHz it's seems solid as a rock at 20kHz. Above 20kHz it misses the odd count when subjected to long bursts. This is with a function generetor generating bursts of "perfect" signals with 50% dutycyle so in real life it might be a little less.
    Connecting an optical encoder works fine but a mechanical one does not due to contact bounce. Using a 16bit WORD for the position counter and simple 1x decoding, pissing away 3/4 of the resoultion but that was what was asked for.

    It bit-bangs SPI data to an AD9833 but there's no math to calculate actual frequency.

    The LCD code is there for my debug purposes but I left it there just in case.

    Code:
    DEFINE LOADER_USED 1
    DEFINE OSC 20
    
    DEFINE LCD_DREG PORTD       'LCD data port 
    DEFINE LCD_DBIT 0           'LCD data starting bit 0 or 4 
    DEFINE LCD_RSREG PORTA      'LCD register select port 
    DEFINE LCD_RSBIT 3          'LCD register select bit 
    DEFINE LCD_EREG PORTA       'LCD enable port 
    DEFINE LCD_EBIT 1           'LCD enable bit 
    DEFINE LCD_RWREG PORTA      'LCD read/write port 
    DEFINE LCD_RWBIT 2          'LCD read/write bit 
    DEFINE LCD_BITS 8           'LCD bus size 4 or 8 
    DEFINE LCD_LINES 2          'Number lines on LCD 
    DEFINE LCD_COMMANDUS 3000   'Command delay time in us 
    DEFINE LCD_DATAUS 40        'Data delay time in us
    
    
    FSYNC       VAR LATB.3
    SCLK        VAR LATB.4
    SDATA       VAR LATB.5
    Ch_A        VAR PortB.6
    Ch_B        VAR PortB.7
    
    Position    VAR WORD            ' Encoder position
    Frequency   VAR WORD            ' 
    AD9833      VAR WORD[5]         ' Array for data to be sent to the AD9833
    BitsToSend  VAR BYTE            ' Number of bits -1 to send to the AD9833 (max 127)
    Ch_A_Old    VAR BIT             ' Memory bit for edge-detection
    
    
    '-------------------------------------------------------------
    '------------------------- Init ------------------------------
    '-------------------------------------------------------------
    CMCON = 7
    ADCON1 = %00001111              ' No analog inputs.
    TRISB  = %11000001
    
    Frequency = 0
    Position = 0
    BitsToSend = 255
    
    
    PAUSE 1000
    LCDOUT $FE, 1, "AD9833..."
    
    
    ' Initialize the AD9833 as per example in AN-1070.
    ' Just to verify that we're good to go.
    ' This should make it output 400Hz with a 25MHz base clock
    AD9833[4] = $2100
    AD9833[3] = $50C7
    AD9833[2] = $4000
    AD9833[1] = $C000
    AD9833[0] = $2000
    
    FSYNC = 0
    
    For BitsToSend = 79 to 0 Step -1
        SDATA = AD9833.0[BitsToSend]
        SCLK = 0
        PAUSEUS 20
        SCLK = 1
        PAUSEUS 20
    NEXT
    
    FSYNC = 1
    
    
    Main:
    '-------------------------------------------------------------
    '--------------Poll encoder and keep count -------------------
    '-------------------------------------------------------------
        IF Ch_A = 1 THEN        
            IF Ch_A_Old = 0 THEN
                IF Ch_B = 1 THEN
                    Position = Position + 1
                ELSE
                    Position = Position - 1
                ENDIF
                Ch_A_Old = 1
            ENDIF
        ELSE
            Ch_A_Old = 0
        ENDIF
    '-------------------------------------------------------------
    
    
    '-------------------------------------------------------------
    '------------- If needed, prepare to update DDS --------------
    '-------------------------------------------------------------
        IF Position <> Frequency THEN           ' Has the count changed since last update of the DDS?
            IF BitsToSend.7 THEN                ' Are we free to update?
                Frequency = Position
                
                ' See datasheet for AD9833, this is just for basic testing.
                AD9833[2] = %0010000000000000
                AD9833[1] = %0100000000000111
                AD9833[0] = Frequency
                
                AD9833.0[15] = 0
                AD9833.0[14] = 1
           
                BitsToSend = 47                 ' 3*16 = 48 but we're using this variable to index the bits so minus 1
    
            ENDIF
        ENDIF
    '-------------------------------------------------------------    
    
    
    '-------------------------------------------------------------
    '---If DDS is to be updated, do it one bit per loop iteration----
    '-------------------------------------------------------------
        IF NOT BitsToSend.7 THEN              ' Still bits left to send ?
            FSYNC = 0                         ' Chip select
            SDATA = AD9833.0[BitsToSend]      ' Setup data
            SCLK = 0                          ' Clock low
            BitsToSend = BitsToSend - 1       ' Index next bit
            SCLK = 1                          ' Clock high
        ELSE
            SCLK = 1
            FSYNC = 1                          ' Chip select
        ENDIF
        
            
    ' This is for debugging purposes.
    ' If button is pressed and LCD updated while the encoder is moved
    ' counts will obviously be missed.            
    IF PortB.0 = 0 THEN
        LCDOUT $FE, 1, DEC Position, "  ", DEC Frequency, "   ", DEC BitsToSend
    ENDIF
    
    Goto Main

  3. #3
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,133


    Did you find this post helpful? Yes | No

    Default Re: Can PBP read optical encoder damn fast? :)

    Excellent job Henrik.

    At the expense of a little slower response, a couple of 100nF will help a lot debouncing mechanical encoders. I used that as I did not want to make a software debouncing at that time.

    Ioannis

  4. #4
    Join Date
    Feb 2013
    Posts
    1,125


    Did you find this post helpful? Yes | No

    Default Re: Can PBP read optical encoder damn fast? :)

    IF A=1 or B=1 AND A<>B

    Is this proper replacement for XOR statement?

  5. #5
    Join Date
    May 2013
    Location
    australia
    Posts
    2,645


    Did you find this post helpful? Yes | No

    Default Re: Can PBP read optical encoder damn fast? :)

    You could always write a little program to test your supposition and find out , you never know you may learn something


    Code:
    TOUCH                var byte
    A   VAR TOUCH.0
    B          VAR TOUCH.1
    RES        var byte    
        
        
    touch = 4
    Debug 9,"XOR TRUTH TABLE"
    Debug ,13 ,10,"A",9,"B",9,"A^B",9,"CUT",13 ,10
    while touch
        touch=touch-1 
        touch=~touch 
    ;CODE UNDER TEST
       IF A = 1 or  B = 1  AND A <> B THEN 
           RES=1
       ELSE
          RES=0
       ENDIF
       DEBUG #A,9,#B,9," ",#A^B ,9," ",#RES ,13 ,10
       touch=~touch     
    WEND
    Last edited by richard; - 6th June 2020 at 07:46. Reason: white space
    Warning I'm not a teacher

  6. #6
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,133


    Did you find this post helpful? Yes | No

    Default Re: Can PBP read optical encoder damn fast? :)

    And although the little debug program of Richard's might not give you a clue, the keyword is "priority".

    Machines do not follow your thoughts. Need more detailed explanations, so parenthesis will help. See page 87 of the manual to understand why your expression is way out of what you intended to.

    Ioannis

  7. #7
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Can PBP read optical encoder damn fast? :)

    If not pissing away 3/4 of the encoder resolution is something worth doing here's a replacement routine that does 4x decoding. It might not be the most optimized or elegant way but is works. Surprisingly (to me) it seems to work fine up to around 8kHz which means it does 32000 counts per second when being fed "perfect" quadrature signals my function gen.

    Code:
    ' Added variables:
    Encoder VAR BYTE
    Old_Enc VAR BYTE
    Test VAR BYTE
    Dir VAR WORD          ' Must be same size as Position variable
    
    
    '-------------------------------------------------------------
    '--------------Poll encoder and keep count -------------------
    '-------------Alternative routine with 4x decoding------------
    '-------------------------------------------------------------
    
        Encoder.0 = Ch_A
        Encoder.1 = Ch_B
    
        Test = Encoder ^ Old_Enc
    
        Dir = 0
    
        If Test = 1 THEN
            If Old_Enc = 0 THEN Dir = 1
            IF Old_Enc = 1 THEN DIR = -1
            IF Old_Enc = 2 THEN Dir = -1
            If Old_Enc = 3 Then Dir = 1
        ENDIF
    
        IF Test = 2 THEN
            IF Old_Enc = 0 THEN DIR = -1
            IF Old_Enc = 1 THEN Dir = 1
            IF Old_Enc = 2 THEN Dir = 1
            IF Old_Enc = 3 THEN Dir = -1
        ENDIF
    
        Position = Position + Dir
        
        Old_Enc = Encoder

Similar Threads

  1. HEDS5540 optical encoder
    By louislouis in forum mel PIC BASIC Pro
    Replies: 23
    Last Post: - 11th October 2016, 23:23
  2. how to read ky40 mechanical encoder ?
    By iw2fvo in forum mel PIC BASIC Pro
    Replies: 20
    Last Post: - 25th October 2015, 16:22
  3. Probe to read quadrature encoder with DT_INT need help
    By phoenix_1 in forum mel PIC BASIC Pro
    Replies: 11
    Last Post: - 31st August 2009, 20:43
  4. USB Optical mouse as motor encoder
    By RodSTAR in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 24th August 2008, 15:09
  5. Damn these low power PIC and other Microcontrollers
    By keithdoxey in forum Off Topic
    Replies: 8
    Last Post: - 12th November 2006, 21:52

Members who have read this thread : 2

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