Let's Make Robots!

IF / OR Interrupt? Picaxe...

Hey guys,

I am playing with a 40x2 and the hintsetup and hserinsetup commands also with the flags commands... I would like to interrupt on either a hint signal OR a hserin input NOT both at the same time. It seems that with the various flags conditions, you can stack-up a bunch of stuff that has to be true to interrupt, but there is no "OR" --just a bunch of ANDS


Basically, "if hint1=1 and hint2=1 then inturrupt" but not "if hint1=1 OR hint2=1 then interrupt"...

anyone got any thoughts?


--I should add to this:

I would like to interrupt on many different conditions and then when the code zaps down to the interrupt sub-routine, I would then like to use something like: if flags=%00000100 then... if flags=%01000000 then...

Comment viewing options

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

This new info is needed again!

Quality work, rik.

Maybe I don't understand, but Chris mentioned using a 40X2 PICAXE... The M2, X1 and X2 parts all allow:

 SETINT OR input, mask

as well as the SETINT NOT one.

Here is proof of concept that you can detect serial data happening by hardwiring hserin to hint2 (or 1 or 0). Take a look at lots'o'code:

symbol command = b1

hsersetup B38400_8, %111  ' inverted signals and auto background serial comms
hintsetup %01000100       ' setup rising edge trigger on hint2/B.2 hardwired to hserin/C.7
hserout 0, ("===== RESET =====", cr)
gosub interrupt

  toggle B.5 ' invisibly fast blinking LED
goto main ' how fast is that!

  hserout 0, ("triggered with flags=", #flags, cr)

 ' notice how hserflag was raised by the picaxe, but it never triggered any interrupting
 ' because I did not setintflags for it
  if hserflag = 1 then 
    hserout 0, ("32.hserflag = serial data received and stored", cr)
    do while ptr != hserptr ' BTW: ptr and hserptr loop around nicely when they reach the max (1023 on a 28X2)
      command = @ptr
      hserout 0,("cmd(", #ptr, "): ", command, " decimal: ", #command, cr)
      inc ptr
    hserflag = 0

  if flag3 = 1 then
    ' there was an interrupt on one or more of the three pins
    hserout 0, (" 8.flag3 = any pin", cr)
    if flag2 = 1 then
      ' there was an interrupt caused by an edge on B.2
      hserout 0, (" 4.flag2 = hardwire hserin", cr)
      flag2 = 0
    flag3 = 0

  hserout 0, ("exiting with flags=", #flags, cr, cr)
  ' NOTICE how I am NOT setting bit5 or hserflag in this byte:
  setintflags %00001000, %00001000 ' interrupt for flag3 only = portB-triggers (any one of 0, 1, 2)
' [end of program]'

This program does not yet combine with the other triggers (bumper switches), but that seems trivial now. Below is the feedback from all the debugging code. After booting, I entered a capital U (aka the binary 01010101 aka "readyfreddyareyousteadyyesyouarebecausenowyouarewarmedup"). Sending multiple bytes "all at once" is not a problem, the background receiving continues to process and store them. But then the main loop will stay untouched for that much longer. This may or may not be bad for your robot.

===== RESET =====
triggered with flags=0
exiting with flags=0
triggered with flags=44
32.hserflag = serial data received and stored
cmd(0): U decimal: 85
8.flag3 = any pin
4.flag2 = hardwire hserin
exiting with flags=0

Flags = 44 corresponds beautifully with %00101100: hserflag, hint3flag and hint2flag. Notice how the sub was called at boot time. The flags were all zero. The routine did nothing but set the desired interrupt mask.

Chris' story is nothing like mine. He just wanted to check ordinary interrupts from pins (10 months ago now). No serial whatsoever. Just for the record: that is the easy part. If you are using an X2 picaxe.

There are four hardware interrupt flags in total:
flag0 aka hint0flag: corresponds with hint0/B.0
flag1 aka hint1flag: corresponds with hint1/B.1
flag2 aka hint2flag: corresponds with hint2/B.2
flag3 aka hint3flag: corresponds with hint 0 OR 1 OR 2: any one (or more) of them!

So you set up your watchdog to look after flag3. Whatever happens, this will make you "gosub interrupt". Then in that sub routine, check what happened and respond accordingly.

  if flag0 = 1 then
  if flag1 = 1 then
  flags = 0
  setintflags = %00001000  ' reset your watchdog

BTW, I am now in the habit of using only one setintflags statement in my entire program. At the the top of the code I just include one hard "gosub interrupt".

Yup, Today it's my turn at this problem (aka this problem??). Using a 28X2 with two bumper switches (B.0, B.1) and a serial input on C.7 = hserin.

I already coded proofs of concept: one program that responds to bumpers and another program that responds to serial data coming in. Both programs are running around in the main loop, waiting for stuff to happen.

Check out the different setintflags statements
setintflags %00001000, %00001000 ' this waits for any of the hint0, hint1, hint2 = B.0, B.1, B.2 to call
setintflags %00100000, %00100000 ' this waits for serial data to be received in the background

Now I want to integrate both concepts into one program:
setintflags %00101000, %00101000 ' this breaks the program but still compiles just fine

So, after consulting CtC over Skype, I am considering to hardwire the serial line to B.2. This is an unused input that can trigger a hardware interrupt on a falling or rising edge, just like my two bumpers.

Cross your fingers for me.

Here is a proof of concept that demonstrates that you do not need to listen to interrupts on the serial line, if only you
a) receive your bytes in the background
b) check the memory (pointer) often enough in your main loop
Consider the code below. The hard wire from hserin/C.7 to hin2/B.2 is gone.
This loops around crazy fast, because it has nothing much to do.

symbol command = b1
hsersetup B19200_8, %111  ' inverted signals + auto background

  toggle B.5 ' just an LED blinking faster than the naked eye can see
  do while ptr != hserptr   ' compare pointers, if different then make up for it
    command = @ptr  ' read one byte from scratchpad
    hserout 0,("cmd(", #ptr, "): ", command, cr)  ' report back via hserout
    inc ptr  ' increment pointer
  loop  '  if there are still bytes left unread
goto main

The X1 and X2 both support NOT. 

SETINT NOT  input,mask (X1 parts only) => Picaxe manual 2 : page 178 => setint command 

You can try to negate the conditions where the interrupt shouldn't fire. E.g. if you want pins 3 OR 4 to be high to trigger the interrupt, write it like NOT (pin3=0 AND pin4=0) which is the same as (pin3=1 OR pin4=1).

I'm not sure which options are available for the X2, but I think negation on interrupts should work. 

I think you got something going there... Thanks, friend... I got some test-codeing to do!

Let me know how it works out.

Two hungry babies really eat away all my time so I dont get around to doing any roboting these day. I'm very curious to see if this works as planned. You never know how it goes with those more obscure picaxe commands.

I know there are a couple of other users who faced the same interrupt dilemma. 

HIntSetup %00000111 ' Allow Pin Interrupt Flags 
HSetIntFlags %00001000 ' Interrupt on any Pin Interrupt Flag
Do : Loop

If hint0flag = 1 Then ...
If hint1flag = 1 Then ...
If hint2flag = 1 Then ...


(from picaxeforum.co.uk) i didn't know the existence of interrupt flags until i posted that question on the picaxe forums 3 months ago. Here's s the full page in case you're interested