Multiple Interrupts

Joecolo

New Member
newbie here, I would like to interrupt a main servo sequence with several sub sequences. I can only locate instructions for setint for a single action. Is there anyway to have a setint1 goto sub1? And put a setint in sub1 to interrupt sub1 if conditions change?

I have one main or "at rest" and 5 sub programs for a robot that I would like to switch between at will.

Any ideas?

Thanks Joe
 

oracacle

Senior Member
how are you activating each sequence. is it from different buttons or switches? which chip are you using?
there is almost always more than one way to skin a cat.
Only one interrupt is available (well as far as I am aware), however, depending on what you have, and how you want to go about it, you could use a resistor ladder and a comparator interrupt (X2 parts only), or set some switches and press a button would just need to a standard interrupt on the push switch. you may not actually need an interrupt, standard pin scan can be more powerful enough to achieve what you need, specially if the first command in each routine is servopos off
 

Joecolo

New Member
I'm using a 14m2, 3 PIR motion sensors that go high for the inputs and 3 servos. I'm using 3 low inputs for "at rest" sequence. Single and multiple inputs for react to the "environment"

I was thinking of this but I have to wait for each sequence to finish before switch to the next.

main:
if pinC.0 = 1 and pinC.1 = 1 then startd
if pinC.1 = 1 and pinC.2 = 1 then startf
if pinc.0 = 1 then starta
if pin1 = 1 then startb
if pin2 = 1 then startc
goto main
 

eggdweather

Senior Member
You could set a timer interrupt:

When the timer word variable overflows (ie from 65535 to 0) the timer overflow flag (toflag) is set . The toflag is automatically cleared upon the settimer command, but can also be cleared manually via 'let toflag = 0'. If desired an interrupt can be set to detect this overflow by use of the setintflags command.

Such that you get a virtual multiple interrupt routine, by testing for your conditions in the interrupt routine and processing them and returning to the main foreground. Providing there is enough time before the timer goes again, you could do a lot of work in the interrupt routine, or maybe the interrupts are not re-enabled until the interrupt routine completes.

So that achieves what you need and if you do it fast enough it can respond to most real-world / external stimulus such as robot arm movements. Conceptually:

main:
do work as normal
goto main

interrupt: // Doing this every 100mS for example
if servo1 condition has been met then gosub servo1_actions
if servo2 condition has been met then gosub servo2_actions
if servo3 condition has been met then gosub servo3_actions
if servo4 condition has been met then gosub servo4_actions
if servo5 condition has been met then gosub servo5_actions
return from interrupt

servo1_actions:
do some more work
return

You probably would need to complete all of the Servo actions quickly (depends on timer range), but I suspect they don't need to do much work, perhaps set a new servo condition.
 

hippy

Technical Support
Staff member
This works for me with an 08M2 ( real chip and simulation ). Input C.3 when taken high then low stops the existing sequence and starts a new one.

Code:
#Picaxe 08M2

Start0:
  Gosub Interrupt_Enable
  Do
    If b0 <> b1 Then
      Restart 1
    Else
      Pause 1000
    End If
  Loop

Start1:
  Do
    b1 = b0
    Low C.0, C.1
    Select Case b1
      Case 0 : Goto Sequence0
      Case 1 : Goto Sequence1
      Case 2 : Goto Sequence2
      Else   : b0 = 0
    End Select
  Loop

Sequence0:
  ; Red C.0 _-__-__-__-__-__-__-_
  ; Grn C.1 _____________________
  Do
    High C.0 : Pause 100
    Low  C.0 : Pause 100
  Loop
  
Sequence1:
  ; Red C.0 ______________________
  ; Grn C.1 _-__-__________-__-___
  Do
    High C.1 : Pause 100
    Low  C.1 : Pause 100
    High C.1 : Pause 100
    Low  C.1 : Pause 1000
  Loop

Sequence2:
  ; Red C.0 _-___________-_______
  ; Grn C.1 _______-___________-_
  Do
    High C.0 : Pause 100
    Low  C.0 : Pause 1000
    High C.1 : Pause 100
    Low  C.1 : Pause 1000
  Loop

Interrupt:
  Do : Pause 100 : Loop While pinC.3 = 1
  b0 = b0 + 1

Interrupt_Enable:
  SetInt %001000, %001000
  Return
 

inglewoodpete

Senior Member
Hmmmm I have no idea what setintflags command is. it looks like I have some reading to do. Thanks Joe
I think you're being led astray. SetIntFlags is only available on the X1 and X2 series of PICAXEs. The timer on the M2s cannot cause an interrupt.

Although I don't fully understand your application, I don't think using interrupts will be of much benefit to you. Why not just use conditional branching in the main loop?
 

Joecolo

New Member
Why not just use conditional branching in the main loop?[/QUOTE]

My branch loops are long and I was hoping for a quicker response than waiting till the end of the loop. I'm making a robot that hopefully responds by way of PIR sensors to react to its environment.
 

stan74

Senior Member
I'm new to picaxe,about 2 months. My main interest is robots, rebuilding designs that were published 15 years ago but which are new to me. I'd never used an ultra sonic range finder or servo before. The timer overflow interrupt is handy and not as complicated as it appears. I'm trying to write motor speed control for 2 stepper motors for a robot. Hopefully it will run in the background..a bit like the picaxe servo command does. I searched google "picaxe interrupt stepper motor" and found links to the picaxe forum which I didn't find in the forum search box. As said, there's a timer that counts to 65535 then resets to zero and will then run an interrupt routine if one's setup. This timer increments every 64us.If you preload the timer with say 60000 then it will take (65535-60000) x 64 us to trigger the next interrupt. The interrupt code resets the timer to 60000 and re-enables the interrupt so it happens again and does your code. A stepper motor only moves if it's pulsed so an interrupt routine is needed to keep it turning. Good luck with your robot.
 

Joecolo

New Member
Hippy

Thank you for your feed back, I can't recognized what is happening here. Can you add comments? thanks Joe

Start0:
Gosub Interrupt_Enable
Do
If b0 <> b1 Then
Restart 1
Else
Pause 1000
End If
Loop

Start1:
Do
b1 = b0
Low C.0, C.1
Select Case b1
Case 0 : Goto Sequence0
Case 1 : Goto Sequence1
Case 2 : Goto Sequence2
Else : b0 = 0
End Select
Loop
 

inglewoodpete

Senior Member
I'm new to picaxe,about 2 months. My main interest is robots, rebuilding designs that were published 15 years ago but which are new to me. I'd never used an ultra sonic range finder or servo before. The timer overflow interrupt is handy and not as complicated as it appears. I'm trying to write motor speed control for 2 stepper motors for a robot. Hopefully it will run in the background..a bit like the picaxe servo command does. I searched google "picaxe interrupt stepper motor" and found links to the picaxe forum which I didn't find in the forum search box. As said, there's a timer that counts to 65535 then resets to zero and will then run an interrupt routine if one's setup. This timer increments every 64us.If you preload the timer with say 60000 then it will take (65535-60000) x 64 us to trigger the next interrupt. The interrupt code resets the timer to 60000 and re-enables the interrupt so it happens again and does your code. A stepper motor only moves if it's pulsed so an interrupt routine is needed to keep it turning. Good luck with your robot.
Stan74, You are using an X2-series PICAXE, which has programmable timer interrupts. Joecolo is using a 14M2, which is a much simpler beast. The M2-series chips only have a one-second timer, which cannot cause interrupts.
 

hippy

Technical Support
Staff member
Hippy. Thank you for your feed back, I can't recognized what is happening here. Can you add comments? thanks Joe
No problem. The M2 chips can do multi-tasking and can run more than one task simultaneously - though, more correctly, can appear to.

This takes advantage of that to have the Start1 task choosing one of a number of sequences and running those.

The Start0 task runs separately and monitors when an interrupt has changed which task should be running. If it notices a change then it forces the Start1 task to restart from the 'Start1:' label using the RESTART command, then goes back to looking for future changes.

It's a bit like having two separate chips, one looking for button pushes then resetting the other which executes and outputs the desired sequence.
 
Top