interrupt with 16F88


Closed Thread
Results 1 to 7 of 7
  1. #1
    Join Date
    Mar 2008
    Location
    london
    Posts
    15

    Red face interrupt with 16F88

    hello every body
    i m trying to program a small robot which will detect objects and avoid them and will also avoid edges.
    i managed to write two separate codes, one for the edges detection and avoidance and the second one for obstacle avoidance.
    then i tried to combine the two codes together, it works fine but there is a very large delay on going from obstacle detection to edge detection.
    I think that it will work fine if i could use an interrupt to interrupt the obstacle detection when an edge is detected and come back to obstacle detection when it is safe (no edge is detected)

    i m very not familiar with interrupt, can you help me on that matter please?

    how to activate interrupt?...how to go back to the main program?....?????

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    There are many ways to do Interrupts. But the easiest to use is ON INTERRUPT GOTO.

    To activate a particular interrupt, you'll set the appropriate Enable bit for the interrupt you want to use.

    Then in the interrupt handler you clear the Interrupt Flag before RESUME'ing which returns control to the Main program.

    With more information, we could probably give more direction as to which Enable bits and flags to use.
    <br>
    DT

  3. #3
    Join Date
    Mar 2008
    Location
    london
    Posts
    15


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Darrel Taylor View Post
    There are many ways to do Interrupts. But the easiest to use is ON INTERRUPT GOTO.

    To activate a particular interrupt, you'll set the appropriate Enable bit for the interrupt you want to use.

    Then in the interrupt handler you clear the Interrupt Flag before RESUME'ing which returns control to the Main program.

    With more information, we could probably give more direction as to which Enable bits and flags to use.
    <br>
    hello,
    this is a peace of my code, the main routine called main is detecting object and avoiding them and the interrupt subroutine is called start.

    basically its a robot which detect and avoid obstacle (which works fine ) but should jump to a subroutine if either port.b0 or port.b1 or portb2 or portb3 goes low (meaning that an edge is detected) in order to avoid the edge ;and as soon as the 4 portbs '0 to 3' are high together (meaning that no edge is detected) the program should go back to the main routine.

    here is the code:

    '-------------------------interrupt set up ----------------------

    ON INTERRUPT GOTO start

    resume

    '------------------------obstacle mode-----------------------------
    main:
    INTCON = %10010000 'enable interrupt on portb.0
    gosub turnhead_extleft 'position head to the left

    position[11] = 0 'reset last position of array to 0

    for i = 0 to 10 'take 11 distance measurements
    gosub sr_sonar 'get sonar readings for each of the 11 dist measuremens
    position[i] = dist_inch 'store sonar reading in the array
    gosub turnhead_right 'rotate head right by 15 degrees

    next i 'do it again

    best_pos = 11 ' ?????

    for i = 0 to 10 'sorting routine to find location
    if position[i] >= position[best_pos] then 'if the distance measured [i] is > than 11 inches
    best_pos = i 'then best position will be that distance i

    serout lcd,baud,[254,135,#best_pos," "]

    endif
    next i
    most_space = 11 - best_pos 'number of left positions needed to get the bot head
    'back to position with the most space

    for turn = 1 to most_space 'position the bot head in the direction with the most
    gosub turnhead_left 'free space
    next turn

    for turn = 1 to 15 'walk forward for 15 steps
    gosub sr_sonar 'take sonar readings
    if dist_inch < 6 then 'if obect is too close,ie <6inches

    gosub walk_reverse 'back the bot up for 10 steps
    goto main 'go back to start and scan for the most space again

    endif
    gosub walk_forward
    next turn
    goto main
    end
    '--------------------end obstacle mode------------------------------------------

    '--------------------edge mode-------------------------------------------------

    start:

    if portb.0 = 0 && portb.1 = 0 && portb.2 = 0 && portb.3 = 0 then 'if nothing is detected
    goto do_nothing
    endif
    if portb.0 = 0 && portb.1 = 0 && portb.2 = 0 && portb.3 = 1 then 'if left is detected
    goto stop_to_move
    endif
    if portb.0 = 0 && portb.1 = 0 && portb.2 = 1 && portb.3 = 0 then 'if right is detected
    goto stop_to_move
    endif
    if portb.0 = 0 && portb.1 = 0 && portb.2 = 1 && portb.3 = 1 then 'if right and left are detected
    goto stop_to_move
    endif



    if portb.0 = 0 && portb.1 = 1 && portb.2 = 0 && portb.3 = 0 then 'if back is detected
    goto back
    endif
    if portb.0 = 0 && portb.1 = 1 && portb.2 = 0 && portb.3 = 1 then 'if back and left are detected
    goto back_headright
    endif
    if portb.0 = 0 && portb.1 = 1 && portb.2 = 1 && portb.3 = 0 then
    goto back_headleft
    endif
    if portb.0 = 0 && portb.1 = 1 && portb.2 = 1 && portb.3 = 1 then
    goto slow_back_headextright
    endif



    if portb.0 = 1 && portb.1 = 0 && portb.2 = 0 && portb.3 = 0 then
    goto front
    endif
    if portb.0 = 1 && portb.1 = 0 && portb.2 = 0 && portb.3 = 1 then
    goto front_left
    endif
    if portb.0 = 1 && portb.1 = 0 && portb.2 = 1 && portb.3 = 0 then
    goto front_right
    endif
    if portb.0 = 1 && portb.1 = 0 && portb.2 = 1 && portb.3 = 1 then
    goto front
    endif



    if portb.0 = 1 && portb.1 = 1 && portb.2 = 0 && portb.3 = 0 then
    goto front
    endif
    if portb.0 = 1 && portb.1 = 1 && portb.2 = 0 && portb.3 = 1 then
    goto front_left
    endif
    if portb.0 = 1 && portb.1 = 1 && portb.2 = 1 && portb.3 = 0 then
    goto front_right
    endif
    if portb.0 = 1 && portb.1 = 1 && portb.2 = 1 && portb.3 = 1 then
    goto front
    endif
    goto start

  4. #4
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    General code flow when using ON_INTERRUPT's...(you mileage may vary, others do it other ways, I do it this way)...

    1) resetplaceholder: 'just a placeholder

    2) ------DEFINEs needed thru the program

    3) DISABLE 'need to disable interrupts while actually processing an interrupt

    4) CLEAR

    5) ------any eeprom data, variable definitions, etc.

    6) ------macro's you might be using

    7) startupholder: goto skipsubs 'skip over all the commonly used subroutines

    8) ON INTERRUPT GOTO INTHANDLER

    9) INTHANDLER: 'process your interrupts.

    10) 'check the interrupt bits, if the interrupt you want is active, reset the bit and process it

    11) INTFINISH: 'I usually recheck the interrupt sources. If one of them tripped while I was processing a previous interrupt, I go back and re-process the interrupt

    12) INTRESUME: RESUME 'resume AFTER you've processed the interrupt

    13) 'commonly used subroutines start below here

    14) commonly_used_sub_1: 'do something here and return from it

    15) ..........

    16) 'end of commonly used subroutines, skipsubs block for setting up registers, lcd, whatever

    17) skipsubs: 'set up the PIC as required

    18) mainloop: 'the main program runs here waiting to get interrupted

    19) ------------more program stuffed in here.........

    20) goto mainloop

    21) END

  5. #5
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Here's some of my advices. Assumming your INTCON an all interrupts settings are nice, i prefer to read the whole PORTB and keep only the revealant bits in one shot.

    INTSOURCE = PORTB & $0F ' this will keep PORTB<3:0> only

    and then you use a Select Case INTSOURCE or BRANCH.

    You forgot the DISABLE/ENABLE RESUME stuff.

    Code:
    ON INTERRUPT GOTO start
    
    resume
    MIIIIIIIIIIP! that resume will act as a RETURN... and will cause you something like a stack underflow. remove it.

    Read the manual once again.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  6. #6
    Join Date
    Mar 2008
    Location
    london
    Posts
    15


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by skimask View Post
    General code flow when using ON_INTERRUPT's...(you mileage may vary, others do it other ways, I do it this way)...

    1) resetplaceholder: 'just a placeholder

    2) ------DEFINEs needed thru the program

    3) DISABLE 'need to disable interrupts while actually processing an interrupt

    4) CLEAR

    5) ------any eeprom data, variable definitions, etc.

    6) ------macro's you might be using

    7) startupholder: goto skipsubs 'skip over all the commonly used subroutines

    8) ON INTERRUPT GOTO INTHANDLER

    9) INTHANDLER: 'process your interrupts.

    10) 'check the interrupt bits, if the interrupt you want is active, reset the bit and process it

    11) INTFINISH: 'I usually recheck the interrupt sources. If one of them tripped while I was processing a previous interrupt, I go back and re-process the interrupt

    12) INTRESUME: RESUME 'resume AFTER you've processed the interrupt

    13) 'commonly used subroutines start below here

    14) commonly_used_sub_1: 'do something here and return from it

    15) ..........

    16) 'end of commonly used subroutines, skipsubs block for setting up registers, lcd, whatever

    17) skipsubs: 'set up the PIC as required

    18) mainloop: 'the main program runs here waiting to get interrupted

    19) ------------more program stuffed in here.........

    20) goto mainloop

    21) END

    hello,
    i wanted to test an interrupt in a simple small code , i found a code on the internet and modified it and got this:
    @ DEVICE INTRC_OSC, LVP_OFF, WDT_OFF, MCLR_OFF

    DEFINE OSC 4

    OSCCON=%01101000 ' INTRC = 8MHz
    ANSEL=%00000000
    CMCON=%00000111


    OPTION_REG.6=1 'Trigger on rising edge
    INTCON = %10010000 'Enable INTE
    INTCON.1 = 0 'Clear RB0/INT External Interrupt Flag bit

    On Interrupt Goto UpdateCounter

    PORTB=0 ' PORTBs are outputs
    Pause 500 ' Wait for startup
    'LOW PORTB.6

    loop:
    low portb.6
    HIGH PORTB.5
    Pause 2000 ' Wait 2 second

    low portb.6
    LOW PORTB.5
    Pause 2000 ' Wait 2 second
    Goto loop ' Do it forever

    Disable
    UpdateCounter:
    LOW PORTB.5
    HIGH PORTB.6
    pause 500
    low portb.5
    LOW PORTB.6
    pause 500

    INTCON.1=0 're-enable interrupts

    resume
    ENABLE
    GOTO loop

    END


    the code works, but the interrupt routine doesn't work, doesn t light the led connected to pin portb.6.
    I mean when the portb.0 is connected to ground the led connected to portb.5 blinks as soon as i connect the portb.0 to +5v the portb.5 stops to blink and nothing happens to portb.6 led.
    can you help me on that please???
    how can I use a digital signal to activate the interrupt for example, with an if statement??

    if portb.0 = 1 , the interrupt is activated and the program jumps to the int subroutine and if portb.0 = 0 the program comes back to the main loop???????

    thank you

  7. #7
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    And yet again, one very important step is missing and one not so important step is also not present...
    No, your code doesn't follow my example exactly, and no, it doesn't have to follow it exactly. Mine is only an example, one of many ways to accomplish the same thing.
    However, I believe in this case, if you follow the example provided, and write your code following said example, you will solve your problem.
    And no, I'm not playing games with you...

Similar Threads

  1. Can't ID interrupt source with this IntHandler??
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 3rd June 2009, 02:35
  2. 16f88 interrupt
    By tur_bot in forum mel PIC BASIC Pro
    Replies: 11
    Last Post: - 2nd April 2008, 11:35
  3. 16F88 Interrupt
    By sskeet in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 24th January 2006, 15:51
  4. How to use an Interrupt to drive a menu on 16f88
    By Tom Gonser in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 15th March 2005, 01:16
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 01:07

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