Let's Make Robots!

Interrupts causing problems

I dislike asking questions - usually it means I didn't RTFM or that my Google skills are sub-par.  Or that I'm missing the obvious.  But here we are.  The following advenure takes place on a Picaxe 28x1 project board (that came with the Solarbotics "Start Here" kit) with a resistor pack replacing the Darlington chip.  The Parallax unit is connected to digital i/o pin 3 (though I see the same behavior on other pins).  Output pin 2 is connected to an LED (but the same behavior holds for pins 4-7 which drive the motor outputs).

Here is some code:

 


 

setint %10000000, %10000000 ; interrupt when pin7 goes high

main:

  ;This area is "before" the sonar code


   low portc 3
   high portc 3
   pause 1
   low portc 3
   let dirsc = %00000000
   pulsin 3,1,w1
   sertxd("Ping))): ",#w1,13,10)
   pause 80

 ; This area is "after" the sonar code

goto main

interrupt:
  high 1 ; LED_1 on
  pause 100
  low 1  ; LED_1 off
  setint %10000000, %10000000 ; re-activate interrupt
return

 


 

The above code works as intended.  Appropriate values are sent to the serial stream, and the LED flashes when the interrupt (a bumper switch) is engaged.

If I add the following LED flash snippet:

   high 2
   pause 1000
   low 2

"after" the sonar code - everything still works like it's suppose too.  However, if I add that snippet "before" the sonar code, the Parallax unit returns "0" every time.  If I comment out the interrupt setting, the behavior is as expected and I get proper sonar readings again.

To further confuse things:  If I remove the sonar code and put it into a subroutine the behavior changes.  Now it doesn't matter whether I put the LED flash code "before" or "after" the gosub call - either way the Parallax returns a "0" reading as long as the interrupt is defined.  Removing the interrupt clears the problem and I get the desired behavior.

What am I doing wrong?  I've tried changing the interrupt and Parralax i/o pins but get similar behaviors.  Where do I go next to troubleshot the problem.  I suspect it is software, but perhaps there is a hardware problem I'm not looking for.  Any advice or direction is appreciated.  If I've left out any critical information, please let me know and I'll answer as best I can.

Thank you.

 

 

AttachmentSize
interrupt_test.bas888 bytes

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Have you tried stepping through your code with the emulator? You may find something that way.

I hadn't tried that before (hadn't even looked at it).  I've been playing with it and while it doesn't show me the problem, I did learn a bit about the emulator.  So thanks for pointing it out to me and giving me another tool to work with!

ps: I was able to fix the problem in my test code by increasing the pause length, but it didn't fix the problem when I made that fix in the navigation code.  So I'm back to getting rid of the second "low portc 3" and looking for more incriminating code lines.  At least I have a fix.  I think a scope would help me see the problem, but that's not available.

A big mystery to me is why changing state on one of the output pins (beit LED, motor, etc) affects the sonar routine differently depending on whether the routine is written directly in main: or if it's put into a subroutine.  And if the routine is directly coded in main:, it still depends on whether the state change occurs before or after the sonar code.  And none of this (directly) should be affecting the state of the I/O pins on portc.

If I had a scope maybe I could see what was happening on the I/O pins when I re-arrange the code, but for now I'll live with it.

 

Thanks.

OK.  Here's the final answer - for tonight.  It's a timing problem.  I guess that the one millisecond pause between the "high portc 3" and "low portc 3" isn't quite long enough - depending on what else is going on with the processor.  That might explain why the behavior changes when other pin change states and whether or not the sonar routine is hardcoded in main: or put into a subroutine.  It also explains why getting rid of the second "low portc 3" worked as a fix.  I also changed the "high 2" command to light an LED to "high b.2" - it fixed some of the problems, but not all of the error conditions.

I've changed the "pause 1" in the sonar routine to "pause 2" and now the code seems to work regardless of what the pins on portb are doing, and whether or not the sonar code is written directly in main: or in a subroutine.  I'm a little happier with this fix - if it's a problem with timing, then there's not much I can do to see that with the equipment at hand.

Thanks for all the help guys - especially JAX and CtC.  I'll test this fix further and see if it holds up.

-Cactus

I put your code in the editor and instead of, for instance, LOW 1 I put in LOW B.1 or LOW PORTC 1 and it passed syntax. Maybe better pin definition can help? If you have time and the inclination, let me know what it does :)

Without pulldown resistors on my int pins they would drift high and trigger the obstacle avoidance routine. Yours would exhibit such a thing in the form of a blinking light at odd times, which could interrupt the correct reading of your sonar pulse.

I hate work arounds. Want... to... solve... prob...... lem....

And to finally answer your question - no, the interrupt never appears to trigger accidentally.

Sorry that was a pointless comment. I failed to refresh the page so I could see your replies. Glad to see it worked out, well, at least the functioning sonar part.

Okay, I'm not a Picaxe guy but, I do know Pause statements in other languages cause problems for interrupts unless the interrupt routine is done in assembler. I mostly use Picbasic Pro and a pause routine actually stops code execution until it is complete so your interrupt routine might not get executed. As a test, take out the pause routines and setup a for..next loop as a substitute.

The interrupt gets constantly polled during a "pause" command, so the pauses never seem to be a problem.

I'm still confused why the bug exists, but since I have a work-around, I guess I just need to let it go.