WKPT Interrupt freezing

Hi guys,

I am having a little problem with the WKPT Interrupt. It is stopping the program just fine but it dosnt do the handler routine or resume. I am sure Its something stupid that I dont know how to do. The BAP Manual is missing the info on pmr5, iegr2, and pucr5 but I found it in another post after a few hours of frustration. There must be somthing else I am missing.

Can someone take a look and give me some pointers?

[code]
enablehservo2
enablehserial
sethserial h9600,h8databits,hnoparity,h1stopbits

oninterrupt wkpint_0, inthandler
PMR5.bit0 = 1 ;enables pin as WKP interrupt instead of normal I/O
IEGR2.bit0 = 0 ;0 = Pin will interrupt on a falling edge, 1 to interrupt on a rising edge.
PUCR5.bit0 = 1 ;turn on the internal pull up resistor
enable wkpint_0
enable ;

main
hservo [p8\0,p9\0]
pause 2000
hservo [p8\16000\150,p9\16000\150]
hservowait [p8]

hservo [p8\0\150,p9\0\150]
hservowait [p8]

hservo [p8-16000\150,p9-16000\150]
hservowait [p8]
hservo [p8\0\150,p9\0\150]
hservowait [p8]
hserout “no interrupt”,13,13]
goto main

inthandler
hserout “interrupt”,13,13]
pause 2000
resume[/code]

Smitty

Hi Smitty, Not sure what the system will do with a 2 second pause in the interrupt handler, especially since you are using HSEROUT function within it. The HSEROUT interrupts will not be able to be processed, so nothing will output…

Also I am not sure if it will help or not, but you may want to put a master enable in your code. That is put a line that just says "enable "after your line the enables your interrupt. Probably HSERIAL or HSERVO2 will do this for you, but…

Note: I will put your code in a code block and show the enable command…

Kurt

Thanks Kurte,
Ill give it a try but after some thought I might not be using the right command for what I need to do. I basically want to stop the servos when a switch is closed even if they are in a hservowait routine, and go to a new label but NOT resume where the switch was closed. From what I understand now, interrupts HAVE to be resumed. Maybe I shouldnt be using hservowait but instead use while/wend with servopos. That way I could have a button command in there.

Smitty

Hi Smitty,

Nathan(AcidTech) would be better to answer this. I am also interested in this as I may try to use something similar to this later…

[code]fIntHappened var bit

enablehservo2
enablehserial
sethserial h9600,h8databits,hnoparity,h1stopbits

oninterrupt wkpint_0, inthandler
PMR5.bit0 = 1 ;enables pin as WKP interrupt instead of normal I/O
IEGR2.bit0 = 0 ;0 = Pin will interrupt on a falling edge, 1 to interrupt on a rising edge.
PUCR5.bit0 = 1 ;turn on the internal pull up resistor
enable wkpint_0
enable ;

main:
fIntHappened = 0
hservo [p8\0,p9\0]
pause 2000
hservo [p8\16000\150,p9\16000\150]
hservowait [p8]
if fIntHappened then IntHappened

hservo [p8\0\150,p9\0\150]
hservowait [p8]
if fIntHappened then IntHappened

hservo [p8\-16000\150,p9\-16000\150]
hservowait [p8]
if fIntHappened then IntHappened

hservo [p8\0\150,p9\0\150]
hservowait [p8]
if fIntHappened then IntHappened

hserout "no interrupt",13,13]
goto main

IntHappened:
hserout “interrupt”,13,13]
pause 2000
goto main

inthandler:
; now sure if this hservo will work or not to stop p8 in its track and to exit hservowait?
hservo [p8\hservopos(p8)\0]
fIntHappened = 1
resume[/code]

However if all you are going to do is still in an HSERVOWAIT until it completes or until an input changes state like a button pressed, you could do this much simplier with simply looping probably calling HSERVOIDLE and checking the state of your input line.

That is you could do something like:

main:
	hservo [p8\0,p9\0]
	pause 2000
	hservo [p8\16000\150,p9\16000\150]
	gosub WaitForP8
	hservo [p8\0\150,p9\0\150]
	gosub WaitForP8
...
WaitForP8:
	while not hservoidle(p8)
		if in19 then	; could be any testing you want...
			exception IntHappened
		endif
	wend
	return	

I hope that makes a little sense…

Kurt

Kurte,

I kinda understand what you are saying. I tried the first code you posted and nothing happens at all, the program freezes before any servos move. These inturrupts are touchy arnt they? :slight_smile:

Smitty

Yep they are.

You might try removing the HSERVO command from the interrupt handler and move it into IntHappened to see if it likes that better.

Also you might try adding an ENABLE command as the first line of the interrupt handler. This tells the system it is ok to process other interrupts while processing yours…

Kurt

Kurte,

I was able to get it working by using button and servopos. hservoidle wont work for me because the servos never become idle, they are always moving except at the pause in the beginning. Below is what I came up with.

[code]count1 var byte
delay var byte
rate var byte
delay = 80
rate = 40
enablehservo2
enablehserial
sethserial h9600,h8databits,hnoparity,h1stopbits

main
hservo [p8\0,p9\0]
pause 2000

hservo [p8\16000\150,p9\16000\150]
while(hservopos(p8)<>16000)
button P19,1,delay,rate,count1,1,indistop
wend

hservo [p8\0\150,p9\0\150]
while(hservopos(p8)<>0)
button P19,1,delay,rate,count1,1,indistop
wend

hservo [p8-16000\150,p9-16000\150]
while(hservopos(p8)<>-16000)
button P19,1,delay,rate,count1,1,indistop
wend

hservo [p8\0\150,p9\0\150]
while(hservopos(p8)<>0)
button P19,1,delay,rate,count1,1,indistop
wend

hserout “no button pressed”,13,13]
goto main

indistop
hservo [p8\0\250,p9\0\250]
hserout “button pressed”,13,13]
[/code]

You can use an interrupt to change the movment of a servo(including turning the servo off or telling it to stop moving). HSERVO commadns only modify variables. They do not directly effect the servo pulses. Howeveer you must be carefull and keep your interrupts short or enable interrupt while in your interrupt handler because the hservo system needs its interrupts to keep firing.

On a WKP interrupt you can tell a servo to stop by a command such as this:

hservo [p0\hservopos(p0)]

This will immediately stop the servo(at least within the next 20ms) while you can go off and do other things.

Thanks Nathan, that is what I thought. But when he tried it, he said it hung…

So maybe I did something wrong in my quick and dirty editing of his program…

Kurt

I went back and tried your code again and double checked everything, still nothing. I also tried it with the enable in the inthandler and still nothing.

Smitty

I found the problem. I was anding the IWPR flags with IEGR2 bits. So unless you use a rising edge on the WKP int it will never execute and the interrupt flag will not be cleared causing an infinite loop. I’ve fixed this but its going to be a couple days until I have a new release because I’m in the middle of several other additions to Studio. For now you can use WKP only when using the rising edge setting.

Nice, glad you were able to find the problem.

Smitty