Problem with external interrupts (B0-B2) on 18f452


Closed Thread
Results 1 to 16 of 16

Hybrid View

  1. #1
    Join Date
    Jul 2011
    Location
    Miami
    Posts
    7

    Question Problem with external interrupts (B0-B2) on 18f452

    Hi,
    I am new to this forum, and am trying to find some wisdom on handling interrupts on 18f452. I am using timer 0 to trigger an interrupt once every second. That part is working fine. I am trying to detect and count pulses from a pulley that has 3 pulse generating sensors (Call them A, R, & B) I need to count pulses from R, While A & B determine direction. The timer will be used to calculate rate. My code appears to get the interrupts OK, but I am having difficulty determining which sensor it came from.

    There are four magnets in the pulley so I should get 12 interrupts per revolution.
    With the INTCON2 set to use the rising edge, I seem to get an interrupt every time there is a change in state on any of the three pins, thus 24 per revolution. For each sensor, most of the time, I get the appropriate int flag showing 0, while the other two show 1's, when the magnet goes off the sensor, it seems to generate another interrupt, with the values reversed. If this were consistent, I could use this and build on it. However, it isn't.

    If I change the code to trigger on falling edges, I get something quite different. Then I get only 12 interrupts per revolution (as I would expect), However, the int flags are all 1's most of the time but not always. And it is again, inconsistent.

    I'm fairly new to microchip programming with interrupts, so I don't know if my approach is flawed, I have something wrong in the code, or there is some hardware problem.

    My main control registers are as follows:
    trisb=%00000111
    T0CON=%10000011
    RCON.7=0
    INTCON=%10110000
    INTCON2=%10000000
    INTCON3=%11011000

    I would appreciate if someone could examine my code and tell me how to fix this.

    The code is attached as PulseCounter.txt

    My interrupt handler has some serial output to an LCD display so I can see the values of the int flags as they happen. I know that this will have to be removed in the final version
    Attached Files Attached Files

  2. #2
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: Problem with external interrupts (B0-B2) on 18f452

    How fast are you spinning the wheel? I have not looked at the code yet, but it seems quite possible from your description the LCD part is taking too long. If you don't get out of the ISR before the next magnet you will have serious trouble.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  3. #3
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: Problem with external interrupts (B0-B2) on 18f452

    OK, Looked at the code. By my very rough estimation, your ISR will take at least 28.125mSec to get through. That works out to around 3RPS or 180RPM assuming 12 interrupts per rev. For the purpose of debuging, How you tried to spin the wheel by hand and stopping between each magnet to see if the display shows the correct info?

    Also it may be on interrupt messing you up. You may have better luck with DT_INT.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  4. #4
    Join Date
    Jul 2011
    Location
    Miami
    Posts
    7


    Did you find this post helpful? Yes | No

    Default Re: Problem with external interrupts (B0-B2) on 18f452

    Hi Bert,
    Again, thanks for the reponse.
    Does your estimated 28.125 MSec include the serial transmission to the LCD? If so what about without it, as it is only temporary to see what I'm getting. I am turning the wheel very, very slowly, just to see interrupts the intflag values.
    Below is a table of the results for one revolution I am getting. The last column is the elapsed minutes.

    Int # Int1Flg Int0Flg Int2Flg Count(A) Count(R) Count(B) Seconds
    1 1 0 0 1 0 0 31
    2 1 1 1 1 0 0 63
    3 1 1 1 1 0 0 78
    4 1 0 0 2 0 0 96
    5 1 1 1 2 0 0 128
    6 1 1 1 2 2 2 139
    7 1 0 0 3 0 0 154
    8 1 1 1 3 0 0 165
    9 1 1 1 3 0 0 176
    10 1 1 0 3 0 0 189
    11 1 1 1 3 0 0 204
    12 1 1 1 3 0 0 211

    I plan to change timer0 to give me 10 or 100 counts per second, in order to get a more precise time with which to calculate rate. Should that work?
    Forgive me if I plead ignorance of the DT_INT, can you enlighten me?
    regards
    Tom

  5. #5
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: Problem with external interrupts (B0-B2) on 18f452

    Hi Tom, I hope you don't mind I am posting your code from the first post so its easier for folks to see. Plus it just makes it easier for me to look at your results and follow the code.
    Code:
    DEFINE LOADER_USED 1
    DEFINE USE_LFSR 1
    Include "modedefs.bas"     'this is required for RS232 comms
    ADCON1=7
    ' Assign variable names
    DBGDSPL     VAR PORTB.5      'Debug display port
    CurrPuls    var byte
    PulseA      var word
    PulseB      var word
    PulseR      var word
    LastACnt    Var word
    LastBCnt    Var word
    LastRCnt    var word
    CurrSec     var word
    LastSec     var word
    IntCount    var word                    
    pause 10
    trisb=%00000111
    T0CON = %10000011       'Define Timer0 - 1:16
    RCON.7 = 0
    INTCON = %10110000      'Enable TMR0 & Pin B0-B2 interrupts 
    INTCON2= %10000000      'Falling Edge
    INTCON3= %11011000
    goto start
    '---------------------------------------------------------Interrupt Code
    Disable                 ' No interrupts past this point
    myint:
    if INTCON.1<>0 or INTCON3.0<>0 or INTCON3.1<>0 then    'Pulse Interrupt
        IntCount=IntCount+1
        if INTCON3.0=1 and INTCON.1=0 and INTCON3.1=0 then PulseA =PulseA +1
        if INTCON3.0=0 and INTCON.1=1 and INTCON3.1=0 then PulseR =PulseR +1
        if INTCON3.0=0 and INTCON.1=0 and INTCON3.1=1 then PulseB =PulseB +1
     
        SerOut DbgDspl, N9600, [$1b,$2a,$80]        'turn on background lighting of debug display
        SerOut DbgDspl, N9600, [$1b,$30]
        SerOut DbgDspl, N9600, ["I:",#IntCount, " A:", #INTCON3.0, " R:", #INTCON.1, " B:", #INTCON3.1]
        SerOut DbgDspl, N9600, [$1b,$32]
        SerOut DbgDspl, N9600, ["A:", #PulseA, "R:", #PulseR, "B:", #PulseB, "S:", #CurrSec]
        INTCON.1=0 : INTCON3.0=0 : INTCON3.1=0
    endif
    if INTCON.2=1 then              'timer overflow interrupt
        CurrSec = CurrSec +1
        TMR0H=11 : TMR0L=186        'set tmr0 cycle count to 3002 so overflows in 1.0 sec
        'TMR0H=231 : TMR0L=147      'set tmr0 cycle count to 59283 so overflows in .1 sec
        'TMR0H=253 : TMR0L=143      'set tmr0 cycle count to 64911 so overflows in .01 sec
        INTCON.2 = 0
    endif
    Resume                  ' Return to where interrupt occured
    Enable                   
    '---------------------------------------------------------End of Interrupt code
    Start:
    PulseA=0 : PulseB=0 : PulseR=0 : CurrSec=0 : LastSec=0 : IntCount=0
    LastACnt=0 : LastRCnt=0 : LastBCnt=0
    SerOut DbgDspl, N9600, [$1b,$2a,$80]        'turn on background lighting of debug display
    SerOut DbgDspl, N9600, [$1b,$30]
    SerOut DbgDspl, N9600, ["Start "]
    SerOut DbgDspl, N9600, [$1b,$32]
    pause 10
     
    On Interrupt Goto myint ' Define interrupt handler
    Mainloop:
        if PulseR<>LastRCnt or PulseA<>LastACnt or PulseB<>LastBCnt or CurrSec<>LastSec then
    '    SerOut DbgDspl, N9600, [$1b,$2a,$80]        'turn on background lighting of debug display
    '    SerOut DbgDspl, N9600, [$1b,$30]
    '    SerOut DbgDspl, N9600, ["I:",#IntCount, " A:", #INTCON3.0, " R:", #INTCON.1, " B:", #INTCON3.1]
    '    SerOut DbgDspl, N9600, [$1b,$32]
    '    SerOut DbgDspl, N9600, ["A:", #PulseA, "R:", #PulseR, "B:", #PulseB, "S:", #CurrSec]
        endif
        pauseus 1
    GOTO Mainloop
    end
    My time estimate is based soley on the serout stuff. I was just taking a guess at the number of bytes sent at 9600 baud.


    As for DT_INT, search it on this forum and you will find tons of help. I am not so good at finding and posting the links or I would. Basically it is an awesome include to handle all your interrupt needs. It gives you true interrupts as if you had ASM interrupt, but without the hassle. With on interrupt, the problem is you are limited to only seeing the INT after each PBP instruction. So for code with a pause for instance, the interrupt won't fire until after the pause is done.
    Last edited by cncmachineguy; - 26th July 2011 at 22:54.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  6. #6
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: Problem with external interrupts (B0-B2) on 18f452

    Tom, for some reason, I am having trouble pisturing you magnet/sensor setup. Is it possible for the magnet to fire the int, but none of the 3 IF conditions are met? Is there anyway you can make a quick sketch showing the relationship of the magnets sensors, and pully? Doesn't need to be fancy, just a visual. Or even a picture might do it.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  7. #7
    Join Date
    Jul 2011
    Location
    Miami
    Posts
    7


    Did you find this post helpful? Yes | No

    Default Re: Problem with external interrupts (B0-B2) on 18f452

    Hi Bert,
    No, I don't mind.
    As a newcomer, I was hesitant to put too much in the post.
    I hope you can find whatever flaw I may have. I did a google search for DT_INT. I had seen it before when I was scouring the i-net for articles relating to my problem. I had taken note of it and saved a link for possible future use. It may improve my code and cpu time, but at this point, do see a flaw in the existing approach I am taking? Should this work?
    Regards
    Tom
    PS: I see your next post requesting sketch as I am posting this reply, I'll post a sketch in my next reply

  8. #8
    Join Date
    Jul 2011
    Location
    Miami
    Posts
    7


    Did you find this post helpful? Yes | No

    Default Re: Problem with external interrupts (B0-B2) on 18f452

    Thanks for the response.
    With this code, I am moving the wheel very slowly so I can see the interrupts and what values the intflags have. I know that when I actually start spinning the wheel quickly that portion will have to be taken out of the interrupt handler. There is a section of code in the mainloop to display the counters and elapsed time, that is diabled so that the display from the actual interrupt subroutine is long enough to be able to read it.
    In the final version (assuming I can solve this problem, the max rpm will be 100-150 RPM

Members who have read this thread : 0

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

Tags for this Thread

Posting Permissions

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