Can PBP read optical encoder damn fast? :)


Closed Thread
Results 1 to 40 of 47

Hybrid View

  1. #1
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,821


    Did you find this post helpful? Yes | No

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

    If I get it right, you will use a PIC to read a quadrature encoder, then communicate with I2C to another PIC and the second PIC will send the data to your DDS?

    Does this sound logical and efficient?

    You have a PIC then just do it! Use some lines in ISR and get the job done.

    After all, it is a good programming exercise! And the bonus is that you will be thrilled when finished! Don't be afraid of the ISR. A bit of work but you can do it!

    Ioannis

    P.S. what is your current PIC?
    Last edited by Ioannis; - 2nd June 2020 at 21:09.

  2. #2
    Join Date
    Feb 2013
    Posts
    1,079


    Did you find this post helpful? Yes | No

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

    I'm result-oriented person
    And knowing my programming skill, literally saying, I'd prefer to buy wheel, instead of inventing it
    I have many different PICs, but no software knowledge that deep to handle all this stuff

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,522


    Did you find this post helpful? Yes | No

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

    Have you read the specs for that HackADay thing?
    •It's support the standard rotary encoder and the RGB encoder
    •It's possible to set all the 7bit of the I2C address trough a SMD jumper
    •Dimension of 25x25mm or 0.98x0.98in
    •With the castellated holes is possible to connected several boards on the 4 sides
    •Possibility to solder the pull-up resistor on the I2C bus
    •3 General Purpose pins. (GP pins)
    •256byte of internal EEPROM divided in the 2 bank of 128 byte
    •Advanced configuration respect the first version
    •The maximum frequency of the A/B signal is 150Hz.
    Anything that sticks out?

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


    Did you find this post helpful? Yes | No

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

    I am a terrible programmer but have done some ISR routines that also do things fast.

    If I can do it, everyone can do it! Try it and see how it goes. After all we are still here...

    I'd select a PIC of relatively recent 18F series so the famous DT INTS-18 will support it, follow the instructions for the DT INTS and do some test. See here: http://dt.picbasic.co.uk/INT16/DTINTS-18

    Nothing to be afraid of.

    Ioannis

  5. #5
    Join Date
    Feb 2013
    Posts
    1,079


    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.

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,522


    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

  7. #7
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,821


    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

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