Quad Encoder Problem


Closed Thread
Results 1 to 37 of 37

Hybrid View

  1. #1


    Did you find this post helpful? Yes | No

    Default Re: Quad Encoder Problem

    It doesn't work with or without the 'Pause 100' in the interrupt service routine - I actually only added that based on some sample interrupt code from DT (I thought it made sense if there's some latency to saving to EEPROM you might want to wait a tiny bit).

    Other than saving the new MotorRPM to EEPROM everytime it changes, I don't know what else I can do. Users won't be modifying the motor speed very often (once they find the speed they like, they'll just leave it). I suppose I could set up a timer to save the value to EEPROM if it's changed, but I'm open to suggestions

    For the above code line, are you saying I could just use this instead?

    Code:
    IF New_Bits = Old_Bits THEN DoneRotEnc

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


    Did you find this post helpful? Yes | No

    Default Re: Quad Encoder Problem

    Hi,
    According to the manual the WRITE command "is self-timed and may take up to 10 milliseconds to execute on a PIC MCU".
    I suspect that's the issue, most encoders produce a full quadrature cycle, ie 4 edges (4 interrupts) per click/detent. IF the WRITE operation takes 10ms (and/or you have that Pause 100 in there) it's likely that it will miss pulses/edges and get confused.

    Try commenting out the Write operation and see if that fixes it.

    Yes, that's what's I'm saying regarding New_Bits = Old_Bits.
    At the beginning of the ISR you do New_Bits = PortA & %00000011 so the top 6 bits of New_Bits are cleared. At the end of the ISR you assign the value in New_Bits to Old_Bits so the top 6 bits in Old_Bits will also be zero. Therefor the second AND operation is unnecessary, but it doesn't have anything to do with the actual problem....

    /Henrik.

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: Quad Encoder Problem

    I'll try this out tonight, Henrik. Thanks so much for your help here and on my other thread from this week.

    If the WRITE operation in the interrupt service routine is the cause, then I'll move that to the check in the Main loop.

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,607


    Did you find this post helpful? Yes | No

    Default Re: Quad Encoder Problem

    Hi,
    Just realised I misunderstood you a bit. I thought you were trying to use the 12F1840 with this code, then I realised you're actually using the 16F1825 that's in the schematic...duh...

    Anyway, I've breadboarded a 12F1840 (don't have any 18F1825) and now have an encoder counting properly, sending the count over the USART. I simulated the EEPROM write by adding a PAUSEUS xxx in the handler and found that the limit for correct response - in my case - is around 500us. Anything above that it starts missing edges, coutning the wrong way etc.

    So, if the EEPROM write takes even remotely as long as 10ms then that is most likely the issue.

    /Henrik.

  5. #5


    Did you find this post helpful? Yes | No

    Default Re: Quad Encoder Problem

    That gives me strong confidence that it is the WRITE line; I'll comment it out but ultimately move it to the main loop.

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


    Did you find this post helpful? Yes | No

    Default Re: Quad Encoder Problem

    It is too much to have very often (on every click of the rotary encoder) to write the value in EEPROM.

    Do it when there is really a need for this, e.g. when the value is different from old value AND a certain time has passed. This time should be reset while the encoder is rotating.

    Ioannis

  7. #7


    Did you find this post helpful? Yes | No

    Default Re: Quad Encoder Problem

    Quote Originally Posted by Ioannis View Post
    It is too much to have very often (on every click of the rotary encoder) to write the value in EEPROM.

    Do it when there is really a need for this, e.g. when the value is different from old value AND a certain time has passed. This time should be reset while the encoder is rotating.

    Ioannis
    That makes sense, Ioannis. I didn't want to lose a user setting if power was interrupted before the save but maybe I could set up a timer (using DT's interrupt library) to check if the value is changed every 30 seconds or so.

  8. #8


    Did you find this post helpful? Yes | No

    Default Re: Quad Encoder Problem

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    Just realised I misunderstood you a bit. I thought you were trying to use the 12F1840 with this code, then I realised you're actually using the 16F1825 that's in the schematic...duh...

    Anyway, I've breadboarded a 12F1840 (don't have any 18F1825) and now have an encoder counting properly, sending the count over the USART. I simulated the EEPROM write by adding a PAUSEUS xxx in the handler and found that the limit for correct response - in my case - is around 500us. Anything above that it starts missing edges, coutning the wrong way etc.

    So, if the EEPROM write takes even remotely as long as 10ms then that is most likely the issue.

    /Henrik.
    Ok, it works now - mostly. What's weird is the 'MotorRPM' as displayed on the LCD jumps by 3-4 (i.e. current setting is '120' and then one click of the encoder makes it '124'). The only thing I did was comment out the WRITE line (and the PAUSE 100 too, of course). Sometimes, it misses incrementing the click completely (although only rarely).

    Does this have something to do with the comparison logic?

    Code:
    ' ***************************************************************
    ' [IOC - interrupt handler]
    ' ***************************************************************
    RotEncAdjust:
        New_Bits = PORTA & (%00000011)
        IF (New_Bits & %00000011) = (Old_Bits & %00000011) Then DoneRotEnc
    
        RotEncDir = New_Bits.1 ^ Old_Bits.0
        IF RotEncDir = 1 Then
            ; CW rotation - increase speed but only to a max of 'MaxDuty'
            IF MotorRPM < MaxDuty then MotorRPM = MotorRPM + 1
        Else
            ' CCW rotation - decrease speed to a min of 0
            IF MotorRPM > 0 Then MotorRPM = MotorRPM - 1
        EndIF
    
    ;    WRITE EE_MotorRPM, MotorRPM
    ;    pause 100
    
    DoneRotEnc:
        Old_Bits = New_Bits
        
        IOCAF.0 = 0      ' Clear interrupt flags
        IOCAF.1 = 0
    
    @ INT_RETURN

  9. #9


    Did you find this post helpful? Yes | No

    Default Re: Quad Encoder Problem

    Another weird thing - If I comment out this line:

    Code:
    ' Enable interrupts on RPM control now that motors are fully spun up
    INTCON   = %10001000        ' Global int enabled, IOCI enabled, 
                                ' INTF flag bit 0 clr, IOCI flag bit 0 clr
    IOCAP.0  = 1                ' Enable positive (rising edge) change
    IOCAP.1  = 1                ' Enable positive (rising edge) change
    IOCAN.0  = 1                ' Enable negative (falling edge) change
    IOCAN.1  = 1                ' Enable negative (falling edge) change
    IOCAF.0  = 0                ' Clear interupt-on-change flag
    IOCAF.1  = 0                ' Clear interupt-on-change flag
    
    @ INT_ENABLE   IOC_INT      ; Interrupt-on-Change interrupt
    and these ones:

    Code:
    ' ***************************************************************
    ' [IOC - interrupt handler]
    ' ***************************************************************
    RotEncAdjust:
        New_Bits = PORTA & (%00000011)
        IF (New_Bits & %00000011) = (Old_Bits & %00000011) Then DoneRotEnc
    
        RotEncDir = New_Bits.1 ^ Old_Bits.0
        IF RotEncDir = 1 Then
            ; CW rotation - increase speed but only to a max of 'MaxDuty'
            IF MotorRPM < MaxDuty then MotorRPM = MotorRPM + 1
        Else
            ' CCW rotation - decrease speed to a min of 0
            IF MotorRPM > 0 Then MotorRPM = MotorRPM - 1
        EndIF
    
    ;    WRITE EE_MotorRPM, MotorRPM
    ;    pause 100
    
    DoneRotEnc:
        Old_Bits = New_Bits
        
        IOCAF.0 = 0      ' Clear interrupt flags
        IOCAF.1 = 0
    
    @ INT_RETURN
    ... the interrupts don't seem to fire. And then the button push doesn't work, either (and that's not interrupt driven):

    Code:
    Main:
        ' Check if motor RPM has changed
        IF MotorRPM <> Old_RPM Then
            Old_RPM = MotorRPM
            GOSUB ChngMotorHPWM
        EndIF   
       
        TimeCnt = 0
    	While ButtonPress = 0
    	    TimeCnt = TimeCnt + 1
    	    Pause 10
    	    If TimeCnt > 500 Then BtnAction
    	Wend
     
        BtnAction:
            If TimeCnt > 0 and TimeCnt < 200 Then
                PortEngDir = PortEngDir + 1
                If PortEngDir > 1 Then PortEngDir = 0
        
                WRITE EE_PortEngDir, PortEngDir
                #IFDEF USE_LCD_FOR_DEBUG
                    HSEROUT [LCD_INST, LCD_CLR]
                    pause 5
                    HSEROUT ["PortEngDir=", DEC PortEngDir, "  ", 13, 10] ' Send text followed by carriage return and linefeed
                #ENDIF
    
                GOSUB ReversePortEng
            ElseIf TimeCnt >= 200 Then
                WRITE EE_MotorRPM, MotorRPM_Default  ; restore Default value
            
                MotorRPM = MotorRPM_Default
            EndIf
     
        GOTO Main

Similar Threads

  1. RF600E & RF600D encoder/decoder problem
    By Megahertz in forum Off Topic
    Replies: 0
    Last Post: - 17th April 2012, 17:18
  2. using Quad UART
    By harryweb in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 30th April 2011, 00:13
  3. quad encoders
    By cpayne in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 13th March 2007, 17:49
  4. Quad encoder problems
    By smitty505000 in forum mel PIC BASIC Pro
    Replies: 51
    Last Post: - 5th October 2006, 22:44
  5. Encoder problem
    By precision in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 12th September 2006, 22:21

Members who have read this thread : 0

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