interrupting an interrupt

Bloody-orc

Senior Member
Hi there
i have a robot soft that has an interrupt sub in it. but will the interrupt work when the programm is running in the interrups subroutine also? so that i could make a wait for buttonpress and then see if the button is pressed again for example (it is not what i'm doing though. i'm using it to detect serin commands from another picaxe)
 

TheFallenAngel

New Member
I believe, and I am new at this, but by putting something in the interrupt program you can get it to act only when the button's been released. I'm not too sure how you'd do that with a serial input.

Uhm here's the link:
http://www.rev-ed.co.uk/docs/picaxe_manual2.pdf

That'll take you to the Basic commands datasheet, look for setint, specifically page 81.

Not sure if that helps.

Edited by - TheFallenAngel on 06/03/2006 14:58:53
 

andrewpro

New Member
If the first thing you do is setup the interrupt again in the interrupt subroutine, then yes, it will interrupt while it's doing the interrupt subroutine. If you reset the interrupt at the end of the interrupt sub, then no, it will not interrupt while doing the interrupt subroutine. (does that make any sense?)

When you trigger an interrupt, you must reset it or it will not trigger again. In a sense, it's a one shot deal.

--Andy P
 

hippy

Ex-Staff (retired)
Anypro : Are you sure about that ? Have you tested it ?

- SETINT 1,1 ' Interrupt on Pin0 High
- Idle:
- GOTO Idle
-
- Interrupt:
- IF pin0 = 1 THEN Interrupt
- SETINT 1,1
- :
- RETURN

If interrupts are re-enabled after the SETINT within the interrupt handler, there is every possibility that the GOSUB stack would overflow ( as Technical indicated in the other post on this subject ) and the interrupt routine would never return, the program would hang.

Because the interrupt is a faked GOSUB I'm guessing that there is only one SFR/RAM location where the address to return after the interrupt is stored. A second interrupt would overwrite that data and an interrupt within the interrupt handler would prevent the routine from ever returning to the main code.

According to the documentation, it's the combination of SETINT followed by the RETURN which re-enables the interrupt. Logically, that's the only way interrupts could safely work with the PICAXE architecture.
 

Bloody-orc

Senior Member
well i was thinking on trying something like this:
i have a 18X is following a line and waiting for an interrupt to trigger. interrupt is given by a 08M with pulseout command and then it is followed by serial data from it. it is sent to 18X and then it processes it a bit. But now 08M found that he should send some more data to 18X (wich is ok with 18X himself) so will the interrupt be triggered again? or will i have to type a SETINT command in the subroutine?
my code: sry for it being in estonian
<code><pre><font size=2 face='Courier'>
'sisse
symbol karukinnijasees = 10 '+
symbol karukapasjalahti = 20 '+
symbol avatud = 30
symbol suletud = 40
symbol karukadunud = 80 '+
symbol valmis = 100
symbol karuonees = 120
'v&#228;lja
symbol kapplahti = 50 '+
symbol kappkinni = 60 '+
symbol confirmed = 70 '+
symbol error = 90
symbol ootanmidagimuud = 110


'andurid
symbol vasakjoon = 1
symbol paremjoon = 2

'muud pinid
symbol enable = 3
symbol sin = 6
symbol sout = 7

'variabelid
symbol temp = b0
symbol vjoon = b1
symbol pjoon = b2
symbol kiirus = b3
symbol kappinfo = b4

'arvud
symbol anduritevahe = 20
symbol aeglaselt = 900
symbol kiiresti = 1000
symbol tagasi_s = 100
symbol kurv_s = 100

'mootorisuunad
symbol paremale = %00010100 ' &quot;slow&quot; 4 00 0101 00 20
symbol vasemale = %00100010 ' &quot;slow&quot; 32 00 1000 10 34
symbol otse = %00100100 ' 00 1001 00 36
symbol tagasi = %00010010 ' 00 0100 10 18

'eelsetingud
setfreq m8
setint %10000000, %10000000
wait 5
pwmout enable,255, kiiresti


'programm
main:
'debug
readadc vasakjoon, vjoon
readadc paremjoon, pjoon

if vjoon &lt; pjoon then _vjoon
if vjoon &gt; pjoon then _pjoon

_vjoon:
temp = pjoon - vjoon
if temp &gt; anduritevahe then _joonvasakul
goto _otse

_pjoon:
temp = vjoon - pjoon
if temp &gt; anduritevahe then _joonparemal
goto _otse

_joonvasakul:
b13 = tagasi
PEEK $30,b12
pins = b12 &amp; %00001000 | b13
pause tagasi_s

b13 = vasemale
PEEK $30,b12
pins = b12 &amp; %00001000 | b13
pause kurv_s

kiirus = 0
pwmout enable,255, aeglaselt
goto main

_joonparemal:
b13 = tagasi
PEEK $30,b12
pins = b12 &amp; %00001000 | b13
pause tagasi_s

b13 = paremale
PEEK $30,b12
pins = b12 &amp; %00001000 | b13
pause kurv_s

kiirus = 0
pwmout enable,255, aeglaselt
goto main

_otse:
if kiirus &lt; 100 then _aeglaselt
pwmout enable,255, kiiresti
_aeglaselt:
b13 = otse
PEEK $30,b12
pins = b12 &amp; %00001000 | b13
kiirus = kiirus + 1
goto main

interrupt:
pins = 0
pwmout enable,0,0
serout sout, T2400, (&quot;kapp&quot;, valmis)
pause 10
serin sin, T2400, (&quot;kapp&quot;),kappinfo
if kappinfo = karuonees then _karuonees
if kappinfo = karukinnijasees then _karukinnijasees
if kappinfo = karukapasjalahti then _karukapasjalahti
if kappinfo = avatud then _avatud
if kappinfo = suletud then _suletud
if kappinfo = karukadunud then _karuotsing
if kappinfo = valmis then _valmis
serout sout, T2400, (&quot;kapp&quot;,error)


_karuonees:
pins= 0
serout sout, T2400, (&quot;kapp&quot;, confirmed)
pause 50
pins= vasemale
pause 500

_pooran:
readadc vasakjoon, vjoon
readadc paremjoon, pjoon
if vjoon &lt; pjoon then _kohal
goto _pooran

_kohal:
pins= tagasi
wait 15
end

_karukapasjalahti:
serout sout, T2400, (&quot;kapp&quot;, confirmed)
pause 10
serin sin, T2400, (&quot;kapp&quot;), kappinfo
if kappinfo = karukinnijasees then _karukinnijasees
serout sout, T2400, (&quot;kapp&quot;,ootanmidagimuud)
pause 10
goto _karukapasjalahti

_karuotsing:
pins = 0
serout sout, T2400, (&quot;kapp&quot;, confirmed)
pause 10
serout sout, T2400, (&quot;kapp&quot;, kapplahti)
wait 10
_avatud:
pins = tagasi
wait 10
return


_karukinnijasees:
serout sout, T2400, (&quot;kapp&quot;, confirmed)
return 'return


_valmis:

_suletud:

</font></pre></code>

 

andrewpro

New Member
Hippy: Yes, I have done it. It works two ways:

1) the same interrupt at the beginning of an interrupt sub would cause things to get completely wonky. I've done this, and it aint pretty. It's an endless loop until whatever caused the interrupt to ocurr is cleared.

2) Using, in the interrupt sub, more gosubs depending on the nature of the task works fine. I used it in a data collection routine to act as a start/stop switch. Essentially it checks a bit that I use as a boolean indiciator, and if it's true, do one thing, if it's false, do another.

The confusing part can be getting everyhting to return properly. You have to be careful to keep track of the flow, otherwise it does strange and wonderous thigns, usually ending up in a uselessly locked program requiring a hard reset and reprogramming to fix it.

--Andy P
 

hippy

Ex-Staff (retired)
I've just tested an 08M and that doesn't seem to allow nested interrupts ...

- SETINT 0,%01000 ' Interrupt when Pin 3 Low
- Idle:
- SERTXD(&quot;---&quot;,CR,LF)
- PAUSE 1000
- GOTO Idle
-
- Interrupt:
- SERTXD(&quot;INTERRUPT&quot;,CR,LF)
- WaitForPin3High:
- IF pin3 = 0 THEN WaitForPin3High
- SERTXD(&quot;READY&quot;,CR,LF)
- SETINT 0,%01000 ' Interrupt when Pin 3 Low
- PAUSE 5000
- PAUSE 5000
- SERTXD(&quot;RETURN&quot;,CR,LF)
- RETURN

Pressing a button on Pin 3 causes the interrupt and when released it re-enables interrupts on Pin 3. There's a ten second delay after that so the button can be pushed during then and a nested interrupt should occur when the PAUSE completes.

The program ignores the interupt until after the RETURN when it immediately cause the interrupt to occur. Interestingly pressing the button does truncate both PAUSE's ...<code><pre><font size=2 face='Courier'>---
---
INTERRUPT
READY
&lt;-- Button Pushed here --&gt;
RETURN
INTERRUPT
READY
&lt;-- Button Pushed here --&gt;
RETURN
INTERRUPT
READY
RETURN
---
--- </font></pre></code>
 

hippy

Ex-Staff (retired)
I did another test to try out a theory I'd concocted a while ago but never tested; can interrupts be re-enabled by any RETURN within an interrupt handler. The answer is no ...

- Interrupt:
- SERTXD(&quot;INTERRUPT&quot;,CR,LF)
- WaitForPin3High:
- IF pin3 = 0 THEN WaitForPin3High
- SERTXD(&quot;READY&quot;,CR,LF)
- GOSUB EnableInterrupts
- PAUSE 5000
- PAUSE 5000
- SERTXD(&quot;RETURN&quot;,CR,LF)
- RETURN
-
- EnableInterrupts:
- SETINT 0,%01000 ' Interrupt when Pin 3 Low
- RETURN
 

Bloody-orc

Senior Member
thanks a bunch. it has really saved me a lot of time not finding it out when i need to use the soft allredy. now when i get back to historyclasses i start rewriting the software.
 
Top