14M2 Multitasking & interrupts

GrahamGo

Senior Member
A week into really working with PicAxe - and pleasantly surprised. Not the sub microseconds results that I am accustomed to using ARM. But perfect for quite a few ideas that I want to pursue. I am tending to use Logicator to learn the structure and then copy/paste/edit into PICAXE.

I have a requirement to generate 20hz, 860hz, 3.12kh/z and 5kh/z. The PWM is perfect except for the 20hz. (I did find that I can get the 20hz frequency if I change the PIC clock to 1mh/z).

So the next thought, Ok on port C.0 use the standard PWM to output the higher frequencies, then use a second PWM, divide it and switch port C.0 into toggle mode when needed to get the 20hz. With this in mind I have linked Port pins C.1 to C.2 ( C.2 fixed output at 320hz, C.1 interrupt input)

So far, so good - it works well.

Next I activated the multitasker, I find that the pin B.2 outputs a perfect 500ms toggle only if I comment out the setint line at [NOTE1]. If I allow the interrupt the pin B.2 toggles at a jiggly 9 - 12 ms period. (I don't understand why).

I don't know if I have made a code error. I don't really understand where I have gone wrong. I thought multitasking might introduce some jitter. But no, the 20hz is perfect. However the little routine Spin: gets all out of wack. Below is the code as of now. I would appreciate any comments.

Note. I found that the Multitasking mode switches the PIC clock to 16mh/z, and that Setfreq is not allowed.

Code:
symbol varA = b0
let dirsB = %11111111


main:		CALIBFREQ -1
		setint %00000000,%00000010 'enable int input c.1, low [NOTE1]
		pwmout pwmdiv64, C.2, 194, 391 ' PWM 320hz output on C.2
spin:		pause 1000
		goto spin

interrupt: ; if pinC.1 = 0 then interrupt 'needed to debug using push switch
		let varA = varA + 1		
		if varA = 16 then ResetCnt	
		
ExitInt: '	debug
		setint %00000000,%00000010
		return				'Return 

ResetCnt:	let varA = 0  			
		toggle C.0				' 20hz output on B.1
		goto ExitInt
		
start1:
Spin2:	pause 500				' 500 ms
		toggle B.2				' toggle speed measured @ 9-12ms!
		goto Spin2		


#no_data	'reduce download
 
Last edited:

GrahamGo

Senior Member
Try replacing the 'pause' command beside spin 2: with 'pause_int'

See the revision history here:
http://www.picaxe.com/Hardware/PICAXE-Chips/PICAXE-14M2-microcontroller/
Thanks, I tried it, and the "Jitter" seems to be cured. But the problem persists. See attached:-

Set1.jpg I disabled the interrupt (line 7) and the 100ms toggle period on Ch2 is perfect, (CH0 is the 320hz signal)
Set2.jpg I enable the interrupt (line7) and Ch1 starts up and is 20hz, but Ch2 period changes to about 40ms or 24.8hz

set1.JPG Set2.JPG
 
Last edited:

Technical

Technical Support
Staff member
Unfortunately we don't think you will be able to do what you are trying to do using interrupts. But your test program could work perfectly well by just checking the input manually in the first task loop, no need to use interrupts.

When an interrupt occurs it 'suspends' the main task(s) so that the interrupt can process. When it later returns to the task(s) it returns to the next command in each task. This means that if the interrupt occurs half way through a 'pause', in any task, that pause command is effectively 'terminated' as soon as the interrupt occurs. As your second task is pausing most of the time, the pauses within this task will be regularly shortened every time the interupt fires.
 

GrahamGo

Senior Member
Unfortunately we don't think you will be able to do what you are trying to do using interrupts. But your test program could work perfectly well by just checking the input manually in the first task loop, no need to use interrupts.

When an interrupt occurs it 'suspends' the main task(s) so that the interrupt can process. When it later returns to the task(s) it returns to the next command in each task. This means that if the interrupt occurs half way through a 'pause', in any task, that pause command is effectively 'terminated' as soon as the interrupt occurs. As your second task is pausing most of the time, the pauses within this task will be regularly shortened every time the interupt fires.
Thank you for the explanation - it makes sense. This is my first foray into this product and its all learning, no previous experience!.... I have tried to do what you suggested. but this doesn't work either. With the divide set to 16, I get a resultant output of 14.5hz to 16hz, not the expected 20hz. See the attached capture, this is using a divide of 2. You can see sometimes it catches the 2nd count and sometimes the 3rd one (Ch1 is the 320hz, Ch2 is the 20hz). So it look like the multitasking isn't quick enough. But perhaps there is a better way of writing this routine?

It appears that I have two choices.

1. Forget the multitasking and create a main loop and add 1 or 2 interrupt routines for the couple of tasks that I need - This also has the advantage that I can select a different Setfreq.

2. Stay with the multitasker ( which fixes the clock to 16mh/z?) and perhaps play with lowering the PWM period, until it works.

My original thinking was that the 20hz could be generated happily in the background and that the multitasker would co-exist. In fact it can if I don't need any special 'pause' type timing - right?

20hz not.JPG
 

hippy

Ex-Staff (retired)
There's a third option; use an additional PICAXE ( an 08M2 would suffice ) to generate the PWM which is controlled by the master PICAXE. The PWM generator can drop to 1MHz to generate the 20Hz while the main program can run at any speed it wants to. It would also solve a number of other potential issues which could arise in trying to do it all in one PICAXE.
 

GrahamGo

Senior Member
There's a third option; use an additional PICAXE ( an 08M2 would suffice ) to generate the PWM which is controlled by the master PICAXE. The PWM generator can drop to 1MHz to generate the 20Hz while the main program can run at any speed it wants to. It would also solve a number of other potential issues which could arise in trying to do it all in one PICAXE.
That's a neat idea. But I took the idea by 'Technical' and thought. What if reduce the time that a task can spend looking for the 320hz pulse? So I changed the PWM duty cycle to a low value (line 7). Viola, a working program. The timing is good.

I may have missed it, but I think the manual needs to say somewhere that interrupts and multitasking are mutually exclusive or something to that effect. Its ironic that my first software adventure here was into no mans land. Would it not be possible in the future to make it so that interupts can co-exist, or is it a stack problem?

I tried doing the same fix to the original interrupt version - but no joy....

20hz works1.JPG
 
Top