Semi-random INT count???


Closed Thread
Results 1 to 7 of 7
  1. #1

    Default Semi-random INT count???

    Last night, the azimuth on my dish was counting up 11541 to move the dish 180 deg. I changed NOTHING. I went to bed and came in this morning, and now it's only 3100. Now, in my code, I have it intentionally stepped down to only count every 10th pulse from the encoder, but I did not change it. I did this because on arduino, it was showing ~100,000 pulses @ 180 deg and the PIC I'm using doesn't support LONG.

    It was doing this to me on the elevation randomly. Maybe it still is, it just isn't showing itself. The elevation should only be 3600+ counts full travel. That's what it was with an arduino 3 months ago when I started this project. Now it's 7200, but I tweaked that encoder's settings, so I can see that change. But sometimes, at random, it'll overflow a WORD 4 or 5 times @ full travel. That's a far cry from 3600 or 7200! And the kicker is, I do not think it's the encoder. When it would do this, I am watching it on a scope, and there would be zero change. Same PW and freq as it always has been.
    PIC16F1829

    Code:
    '****************************************************************
    '*  Name    : UNTITLED.BAS                                      *
    '*  Author  : [select VIEW...EDITOR OPTIONS]                    *
    '*  Notice  : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
    '*          : All Rights Reserved                               *
    '*  Date    : 6/7/2014                                          *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          :                                                   *
    '****************************************************************
    INCLUDE "DT_INTS-14.bas"
    INCLUDE "ReEnterPBP.bas"
    
    
    DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
    DEFINE HSER_SPBRG 129 ' 9600 Baud @ 20MHz, 0.16%
    DEFINE HSER_CLROERR 1 ' Clear overflow automatically
    APFCON0.2 = 1
    APFCON0.7 = 1
    OPTION_REG.6 = 1
    
    
    #CONFIG
        __config _CONFIG1, _FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF &  _CLKOUTEN_OFF & _IESO_OFF
        __config _CONFIG2, _PLLEN_OFF & _LVP_OFF
    #ENDCONFIG
    
    
    DEFINE OSC 20
     
    ANSELA = 0
    ANSELB = 0
    ANSELC = 0
    
    
    
    
    DEFINE LCD_DREG PORTB
    DEFINE LCD_DBIT 4
    DEFINE LCD_RSREG PORTA
    DEFINE LCD_RSBIT 0
    DEFINE LCD_EREG PORTA
    DEFINE LCD_EBIT 1
    DEFINE LCD_BITS 4
    DEFINE LCD_LINES 2
    DEFINE LCD_COMMANDUS 1500
    DEFINE LCD_DATAUS 44
    LED var PORTC.7
    high LED
    
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler    INT_INT,  _doEncoder,    PBP,  yes
        endm
        INT_CREATE            ; Creates the interrupt processor
    ENDASM
    @   INT_ENABLE   INT_INT
    
    
    stowlight var byte
    stowlight = 1
    TRISC.6 = 1
    DOWN var PORTC.1
    TRISC.1 = 0
    DOWN = 0
    EAST var PORTC.2
    TRISC.2 = 0
    EAST = 0
    WEST var PORTC.5
    TRISC.5 = 0
    WEST = 0
    UP var PORTC.0
    TRISC.0 = 0
    UP = 0
    RX var PORTC.6
    TRISC.6 = 1
     
    
    
    a0 var byte
    a1 var byte
    e0 var byte                                                                                       
    e1 var byte
    i var byte
    VerboseMode var byte
    cereal var byte
    Aencoder0Pos var word
    Eencoder0Pos var word
    HEL var byte
    HAZ var byte
    oldpos var word
    newpos var word
    distance var word
    Eoldposition var word
    Enewposition var word
    stowed var byte
    apple var byte
    SatLocEl var word
    SatLocEl = 6837
    SatLocAz var word
    SatLocAz = 52198
    VerboseMode = 0
    
    
    goto startup
    
    
    
    
    doEncoder:
        if UP = 1 then 
    '        if e0 = 10 then 
                Eencoder0Pos = Eencoder0Pos + 1
    '            e0 = 0
                lcdout $FE, $01, "EL= ", #Eencoder0Pos
                lcdout $FE, $C0, "AZ= ", #Aencoder0Pos
    '        endif
    '        e0 = e0 + 1
        endif
        if down = 1 then
    '        if e1 = 10 then 
                Eencoder0Pos = Eencoder0Pos - 1
    '            e1 = 0
                lcdout $FE, $01, "EL= ", #Eencoder0Pos
                lcdout $FE, $C0, "AZ= ", #Aencoder0Pos
    '        endif
            e1 = e1 + 1
        endif
        if EAST = 1 then 
            if a0 = 5 then 
                Aencoder0Pos = Aencoder0Pos - 1
                A0 = 0
                lcdout $FE, $01, "EL= ", #Eencoder0Pos
                lcdout $FE, $C0, "AZ= ", #Aencoder0Pos
            endif
            a0 = a0 + 1
        endif
        if WEST = 1 then 
            if a1 = 5 then 
                Aencoder0Pos = Aencoder0Pos + 1
                a1 = 0
                lcdout $FE, $01, "EL= ", #Eencoder0Pos
                lcdout $FE, $C0, "AZ= ", #Aencoder0Pos
            endif
            a1 = a1 + 1
        endif
    @ INT_RETURN
    
    
    Startup:
        gosub CLR
        hserout ["Running Startup Procedures!", 13, 10]
        hserout ["PLEASE WAIT....", 13, 10]
        pause 3000
        Eencoder0Pos = 0
        Eoldposition = Eencoder0Pos
        DOWN = 1
        pause 1000
        gosub allSTOP
        Enewposition = Eencoder0Pos
        IF Eoldposition = Enewposition THEN
            stowed = 1
            apple = 1
            Eencoder0Pos = 0
            Aencoder0Pos = 40000
            gosub CLR
            hserout ["Startup Sequence Good!", 13, 10]
            hserout ["Continuing to Main Menu...", 13, 10]
            pause 5000
            goto MainMenu
        ENDIF
        IF Enewposition <> Eoldposition THEN
            stowed = 0
            apple = 1
            UP = 1
            pause 1000
            gosub allSTOP
            gosub CLR
            hserout ["Startup Error!", 13, 10]
            hserout ["Dish will need homing before move will be allowed!", 13, 10]
            hserout ["Continuing to Main Menu...", 13, 10]
            pause 5000
            goto Mainmenu
        ENDIF
    
    
    MainMenu:
        gosub CLR
        HSEROUT ["******** MAIN MENU ********", 13, 10, 10]
        HSEROUT [" 1. Start Homing Sequence", 13, 10]
        HSEROUT [" 2. Manual JOG Mode", 13, 10]
        HSEROUT [" 3. Auto-Acquire Satellite", 13, 10]
        HSEROUT [" 4. Stow Dish for Travel", 13, 10, 10]
        HSEROUT ["Enter Your Selection:",13,10]
        SERIN RX, 2, cereal
        if VerboseMode = 1 then HSEROUT [#cereal,13,10]
        If cereal = "1" then goto HomeDish 
        If cereal = "2" then 
            if apple = 1 then goto JogMenu
            if apple <> 1 then gosub ForceHome
        endif
        If cereal = "3" then 
            if apple = 1 then goto RoughAcquire
            if apple <> 1 then gosub ForceHome
        endif
        If cereal = "4" then 
            if apple = 1 then goto StowMenu
            if apple <> 1 then gosub ForceHome
        endif    
    goto MainMenu
    
    
    RoughAcquire:
    if Eencoder0Pos < 7000 then
        UP = 1
        uploop1:
        pause 100
        if Eencoder0Pos < 7000 then goto uploop1
        gosub allSTOP
    endif
    If Aencoder0Pos < SatLocAz then
        WEST = 1
        azloop1:
        pause 100
        if Aencoder0Pos < SatLocAz then goto azloop1
        gosub allSTOP
    elseif Aencoder0Pos > SatLocAz then
        EAST = 1
        azloop2:
        pause 100
        if Aencoder0Pos > SatLocAz then goto azloop2
        gosub allSTOP
    endif
    If Eencoder0Pos > SatLocEl then
        DOWN = 1
        dnloop1:
        pause 100
        if Eencoder0Pos > SatLocEl then goto dnloop1
        gosub allSTOP
    endif
    goto MainMenu
                                                                                 
    HomeDish:
        gosub CLR
        hserout ["******** HOME DISH ********", 13, 10, 10]
        hserout [" 1. Start Homing Sequence", 13, 10, 10]
        hserout [" 2 Abort Homing", 13, 10, 10]
        hserout ["Enter Your Selection:"]
        serin RX, 2, cereal
        if cereal = "2" then goto MainMenu
        homeloop:
        IF cereal = "1" THEN 
            HAZ = 0
            HEL = 0
            gosub HomeEL
            gosub HomeAZ
            'Haz = 1
            IF (HEL = 1) AND (HAZ = 1) THEN
                gosub clr
                hserout ["HOME PROCESS WAS SUCCESSFUL!", 13, 10]
                apple = 1
                goto MainMenu
            ENDIF
            IF (HEL = 0) OR (HAZ = 0 ) THEN
                gosub clr
                hserout ["DIS HOME PROCESS CAN SUCK MY DICK!", 13, 10]
                goto MainMenu
            ENDIF
        ENDIF
        pause(200)
       if cereal <> "1" then goto HomeDish
        goto homeloop
    goto HomeDish
    
    
    HomeAZ:
        gosub clr
        hserout ["HOMING AZIMUTH - PLEASE WAIT..", 13, 10]
        PAUSE(500)
        Aencoder0Pos = 0
        oldpos = 0
        WEST = 1
        PAUSE(250)
        IF Aencoder0Pos = 0 THEN
            gosub allSTOP
            EAST = 1
            PAUSE(250)
            gosub allSTOP
            PAUSE(500)
            Aencoder0Pos = 0
            WEST = 1
            PAUSE(500)
            IF Aencoder0Pos = 0 THEN goto moveerror
        ENDIF
        pause 1000
        loop4:
        pause 250
        oldpos = newpos
        newpos = Aencoder0POS
        if oldpos > newpos then 
            distance = oldpos - newpos
            hserout ["oldpos = ", #oldpos, "   newpos = ", #newpos, " --- Distance = ", #distance, 13, 10]
        endif
        if newpos > oldpos then 
            distance = newpos - oldpos
            hserout ["newpos = ", #newpos, "   oldpos = ", #oldpos, " --- Distance = ", #distance, 13, 10]
        endif
        if (oldpos = newpos) and (oldpos <> 0) then distance = 0    
        if (distance < 5) or (distance > 500) then
            gosub allSTOP
            Aencoder0Pos = 54000
            newpos = Aencoder0POS
            
            hserout ["HOMING AZIMUTH WAS SUCCESSFUL!", 13, 10]
            HAZ = 1
        endif
        IF HAZ = 0 THEN goto loop4
        EAST = 1
        loop8:
        pause 100
        hserout ["Aencoder0Pos = ", #Aencoder0Pos, 13, 10]
        if Aencoder0Pos > 50000 then GOTO LOOP8
        GOSUB allSTOP
        return
      
    
    
    HomeEL:
    gosub CLR
    hserout ["HOMING ELEVATION - PLEASE WAIT..", 13, 10]
    PAUSE(500)
    Eencoder0Pos = 0
    UP = 1
    PAUSE(250)
    IF Eencoder0Pos = 0 THEN
        gosub allSTOP
        DOWN = 1
        PAUSE(250)
        gosub allSTOP
        PAUSE(500)
        Eencoder0Pos = 0
        UP = 1
        PAUSE(500)
        IF Eencoder0Pos = 0 THEN goto moveerror
    ENDIF
        pause 1000
        loop1:
        pause 250
        oldpos = newpos
        newpos = Eencoder0POS
        if oldpos > newpos then distance = oldpos - newpos
        if newpos > oldpos then distance = newpos - oldpos
        if oldpos = newpos then distance = 0
        if distance < 5 then
            gosub allSTOP
            Eencoder0Pos = 7220
            newpos = Eencoder0POS
            hserout ["HOMING ELEVATION WAS SUCCESSFUL!", 13, 10]
            HEL = 1
        endif
        IF HEL = 0 THEN goto loop1
        DOWN = 1
        loop2:
        pause 100
        'hserout ["Eencoder0Pos = ", #Eencoder0Pos, 13, 10]
        if Eencoder0Pos > 7000 then GOTO loop2
        oldpos = 0
        newpos = 0
        GOSUB allSTOP
    return
    
    
    StowMenu:
        gosub CLR
        hserout ["******** STOW DISH ********", 13, 10, 10]
        hserout [" 1. Start STOW Sequence", 13, 10, 10]
        hserout [" 2 Abort STOW", 13, 10, 10]
        hserout ["Enter Your Selection:"]
        serin RX, 2, cereal
        if cereal = "2" then goto MainMenu
        if (cereal = "1") and (apple = 1) and (stowed <> 1) then goto StowDish
        goto moveerror
        
    StowDish:
        gosub CLR
        hserout ["***** PLEASE WAIT ******", 13, 10]
        if Eencoder0Pos < 5500 then
            UP = 1
            loop3:
            pause 250
            if Eencoder0Pos < 5500 then goto loop3
            gosub allSTOP
        endif
        If Aencoder0Pos > 40000 then
            east = 1
            loop5:
            pause 250
            if Aencoder0Pos > 40000 then goto loop5
            gosub allSTOP
        elseif Aencoder0Pos < 40000 then
            WEST = 1
            loop6:
            pause 250
            if Aencoder0Pos < 40000 then goto loop6
            gosub allSTOP
        endif
        If stowlight = 1 then
            down = 1
            loop7:
            pause 250
            oldpos = newpos
            newpos = Eencoder0POS
            distance = oldpos - newpos
            if (Eencoder0Pos > 0) and (distance <> 0) then goto loop7
            gosub allSTOP
        elseif stowlight <> 1 then
            gosub moveerror
            gosub forcehome
            apple = 0
        endif
        goto mainmenu
        
            
    
    
    JogMenu:
        gosub CLR
        pause 250
        HSEROUT ["***** JOG MENU *****", 13, 10, 10]
        HSEROUT ["U - UP", 13, 10]
        HSEROUT ["D - DOWN", 13, 10]
        HSEROUT ["E - EAST", 13, 10]
        HSEROUT ["W - WEST", 13, 10]
        HSEROUT ["S - ALL STOP", 13, 10]
        HSEROUT ["X - MAIN MENU", 13, 10, 10]
        SERIN RX, 2, cereal
        IF cereal = "A" then Eencoder0Pos = 0
        if cereal = "B" then Aencoder0Pos = 0
        if cereal = "U" Then
            gosub allSTOP
            UP = 1
        endif
        if cereal = "D" then
            gosub allSTOP
            DOWN = 1
        endif
        if cereal = "E" then
            gosub allSTOP
            EAST = 1
        endif
        if cereal = "W" then
            gosub allSTOP
            WEST = 1
        endif
        if cereal = "S" then gosub allSTOP
        if cereal = "X" then 
            gosub allSTOP
            goto MainMenu
        endif
    goto JOGMenu
    
    
    allSTOP:
        EAST = 0
        UP = 0
        DOWN = 0
        WEST = 0
        if VerboseMode = 1 then GOSUB POS
    return
    
    
    CLR:
        if VerboseMode = 0 then
            For i = 0 to 30
                HSEROUT [10]
            next i
        endif
    return
    
    
    abort:
        gosub allSTOP
        gosub clr
        HSEROUT ["USER STOP! -- MOVE ABORTED!", 13, 10]
        PAUSE(5000)
    goto MainMenu
    
    
    ForceHome:
    gosub CLR
    hserout ["SYSTEM ERROR!", 13, 10]
    hserout ["SYSTEM'S HOMING COORDINATES NOT SET!", 13, 10]
    hserout ["SYSTEM CANNOT BE MOVED UNTIL HOMING IS PERFORMED!", 13, 10]
    pause 7000
    return
    
    
    moveerror:
        gosub allSTOP
        gosub clr
        HSEROUT ["SYSTEM ERROR! -- MOVE ABORTED!", 13, 10]                     
        PAUSE(5000)
    goto MainMenu
    
    
    POS:
    lcdout $FE, $01, "EL= ", #Eencoder0Pos
        lcdout $FE, $C0, "AZ= ", #Aencoder0Pos
    return

  2. #2
    Join Date
    May 2013
    Location
    australia
    Posts
    2,386


    Did you find this post helpful? Yes | No

    Default Re: Semi-random INT count???

    most satellite positioner encoders are a reed switch operated by a multipole disc magnet , you have two encoders sharing one interrupt . what happens if one positioner stops with the reed closed ,wont that lead to lost impulses for the other encoder ?
    as has been discussed before when you have a multi-byte variable that's altered in a interrupt routine its true value is indeterminate while the isr is active .
    the correct procedure to access the var is to
    disable isr
    examine var (copy compare or whatever)
    enable isr

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: Semi-random INT count???

    Ok... These are quadrature encoders. Each one has two signal wires producing a dual square wave at 50% offset. Which one is first is dependent on which way the encoder is rotating. I am only using one signal wire from each encoder. There will be three. Right now there are only two... Elevation and Azimuth. I have the chip and BT module inside on my breadboard temporarily. The encoders DID join outside onto one wire, but due to growing concerns as to what happens when the unused encoder is in an "other than floating" position, I separated them all the way to the breadboard. They still go into the PIC on just one leg, but are physically separated by a SPDT relay now. I will re-code and put them to their own leg in the end, but at the moment, the relay seems sufficient to separate them so as to eliminate that as the cause of this problem.

    It's really baffling to me how I can be looking at the exact same pattern on the scope, and yet the PIC is reading an ENTIRELY different thing. To go from ~7500 pulses from end to end, all the way to 300,000 to 400,000 pulses would cause a MAJOR difference that I just couldn't mistake on the scope, and it's just not the case... it looks like no change at all, but the number count is insanely different.

  4. #4


    Did you find this post helpful? Yes | No

    Default Re: Semi-random INT count???

    Quote Originally Posted by richard View Post
    as has been discussed before when you have a multi-byte variable that's altered in a interrupt routine its true value is indeterminate while the isr is active .
    the correct procedure to access the var is to
    disable isr
    examine var (copy compare or whatever)
    enable isr
    I'm unfamiliar with this black magic you speak of... tell me more...

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


    Did you find this post helpful? Yes | No

    Default Re: Semi-random INT count???

    lets have a word var count and a word var pos
    count is the one used in your isr , pos will be the " current " position outside the isr

    we have a sub to get pos
    getpos:

    @ INT_DISABLE INT_INT
    POS= COUNT
    @ INT_ENABLE INT_INT
    RETURN

    now whenever you wish to use pos just call getpos first to "refresh" its value


    some more thoughts
    1 are your encoders mechanically switched ( ie contact bounce could be an issue)
    2 isr's should be kept as short a possible , lcd routines in isr may cause unexpected issues
    3 have you tesed with only one encoder is connected ?
    4 have you a schematic of your setup and a link to the positioner encoder data sheet

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


    Did you find this post helpful? Yes | No

    Default Re: Semi-random INT count???

    Hi,
    A schematic would be nice but I think we've covered this before. Two encoder signals on the same pin, fighting each other, is most likely not a good solution. You mention a relay, switching between the two, and that should be fine. Just make sure the signal at the PIC input is well defined (pulled up/down) and not floating at any point.

    And Richard is spot on. If the frequeuncy of the encoder signal is anything above "a couple of Hz" you definitely do not want the LCDOUT statements within the ISR. Those two statments takes at least 5ms to exectute, then there's the rest of the ISR itself (which isn't much but still...) and the system variable save/restore. But let's say 5ms (and that's probably on the LOW side) then your input frequency can't be higher than 200Hz.

    If you have a two channel scope you can test this.
    1) Scope the input signal to the PIC with channel 1 on the scope.
    2) Set a pin high at the beginning of the ISR. Set it LOW at the end of the ISR.
    3) Scope this output of this pin with channel 2 on the scope.

    The time between the rising edge on Ch1 and the rising edge on Ch2 is the interrupt latency, the time it takes to save the system vars and "get to" the actual ISR code.
    The pulse width on Ch2 is the execution time of the ISR itself.
    Then there's the time it takes to restore the system vars and "get out" of the ISR. This is pretty much equal to the measured latency.

    Add the numbers together, ie 2*latency + ISR execution time and see what you get. Make sure you do this with a LOW(ish) input frequency to ENSURE you're not "overrunning" yourself. Then remove the LCDOUT statements from the ISR and measure again.

    /Henrik.
    Last edited by HenrikOlsson; - 24th June 2014 at 06:35.

  7. #7


    Did you find this post helpful? Yes | No

    Default Re: Semi-random INT count???

    OK, bummer! My debugging was buggy.... Those are only there for the moment to see where I am. My fastest encoder, according to the scope is running about 50-60 hz. So that may be the problem. I'm headed out the door, but I'll try to deal with it when I get back this afternoon and see how it goes. I am still skeptical though, since it was the slow encoder that first showed the problem, and I still cant see how it would go from 3500 counts in say 120 seconds, all the way up to multiple WORD stackoverflows in the same time from this issue, but maybe I just still dont see the big picture....

Similar Threads

  1. is random really not so random?
    By mrpackethead in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 4th November 2011, 01:57
  2. Random
    By ruijc in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 16th March 2011, 12:49
  3. Using both hardware int and Timer Int together?
    By ozarkshermit in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 6th January 2010, 01:09
  4. Random
    By SELTZER in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 13th April 2006, 16:48
  5. Poor mans "semi" logic analyzer
    By anj in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 21st September 2004, 13:26

Members who have read this thread : 1

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