Weird Parallel Task Problem with the Pause Command

I've been experimenting with a simple parallel task program, and I get some strange results with the pause command. For example, I've been using an 08M2 breadboard circuit with an LED and current-limiting resistor on pin C.4, and a logic analyzer to observe the duty cycle of the output wave in a simple two-task program:

Code:
symbol abit = 1

start0:
  do
    high C.4
    pause abit
    low C.4
  loop

start1:              'just to have a second task              
  do
    for b0 = 0 to 99
      b1 = b0 / 10
      b2 = b0 //10
    next b0
  loop
If the "abit" constant has a value anywhere between 1 and 19 inclusive, the duty cycle remains fairly constant around 50%. However, if abit = 20, the duty cycle jumps to 94%! If I replace the pause statement with a pauseus statement, and gradually increase abit in multiples of 10, the duty cycle also gradually increases, as expected.

So, I'm wondering if there's a problem with pause statements in parallel task programs, or am I missing something?

Thanks… Ron
 

JoeFromOzarks

Senior Member
I noticed the same thing without running it in tasks, 19 and 20 being some magical break point. I can look up my "fix" if you wish but I first wanted to state that many of my problems went away, including output ports initializing "high" when they aren't supposed to (such as START 0 defined "port.output LOW") by placing a PAUSE 0 as the first command of each task:

Code:
START 1:
[COLOR="#0000FF"][B]PAUSE 0[/B][/COLOR]
[I]move something[/I]
...
START 2:
[COLOR="#0000FF"][B]PAUSE 0[/B][/COLOR]
[I]blink something[/I]
...
etc.
:) joe
 

nick12ab

Senior Member
If I replace the pause statement with a pauseus statement, and gradually increase abit in multiples of 10, the duty cycle also gradually increases, as expected.

So, I'm wondering if there's a problem with pause statements in parallel task programs, or am I missing something?
  • There's more than 10 microseconds in a millisecond
  • There's no proper delay between the pin going low and high, except for the delay caused by the slow interpreter. This should work fine. However if the duty cycle suddenly increases at a particular value, that shows that JoeFromOzarks is right and there's a problem with the pause.
 
I just tried that, but it's still doing the same thing. So far, replacing pause with pauseus is the only thing I have found that works for me. If you can find your fix, that would be great.

Thanks... Ron
 
nick12ab said:
There's more than 10 microseconds in a millisecond


Yes, I do know there's 1000 microseconds in a millisecond. :) I just meant that gradually increasing the duration of a
pauseus statement does gradually increase the duty cycle, but gradually increasing the duration of a pause statement does not. The duty cycle just jumps abruptly at "pause 20."
 

JoeFromOzarks

Senior Member
I agree, the issue is:
Code:
The duty cycle just jumps abruptly at "pause 20."


I'm handicrapped and had a bad pain week so I can't research it now, but if memory serves I did something like this:
Code:
...
PAUSE 0
PAUSE abit
PAUSE abit
...
where abit was actually abit / 2 but that doesn't help you 'cause abit = 1 in your example. 'Course, nothing I do really demands extreme accuracy but the oscope and the result fit my needs perfectly. :)

I didn't know this (thank you Technical!)
Code:
During M2 part multi task programs the accuracy of pause is reduced due to the parallel processing. 
The minimum resolution is around 20ms in multi task programs. For greater accuracy use single task mode.
I should more time reading the on-line documentation!! (Right after I feel better!) {If I felt better I'd use the "quote" function too, sorry, just not up to it.}


:) joe
 
Thanks Joe - I'll give that a try. And thanks Technical - I was so focused on the parallel task documentation in Section 1 of the manual, that I didn't think to check the pause documentation!

In any case, it's interesting that "pauseus" seems to work better than "pause." Also, for my purpose, using an extra "dummy" instruction works even better. For example, the following code produces a stable 48% duty cycle, which is close enough for me:

Code:
start0:
do
  high C.4
  high C.4  'just to balance timing
  low  C.4
loop

start1:  'just to have a second task
do
    for b0 = 0 to 99
    b1 = b0 / 10
    b2 = b0 //10
  next b
 loop
 

Technical

Technical Support
Staff member
pause is non-blocking, so other tasks can process whilst the long pause is in process. Otherwise you could end up with very long glitches in the other tasks.
pauseus is blocking, it finishes completely before the processor rotates to the next task.
 

Haku

Senior Member
I tried the parallel-tasking capability of the M2 chips for the first time a few days ago as I needed a Picaxe to 'rub its belly' and 'pat its head' at the same time, remembering that the pause command was affected I tried using it to see what was up and also discovered that it doesn't work so great, so I used this as a simple alternative for small pauses:

for temp=0 to 17:next temp
 
Thanks Technical - that explains why pauseus behaves so differently.

Haku said:
I used this as a simple alternative for small pauses: for temp=0 to 17:next temp

I've been using that too, but sometimes even "
for delay = 1 to 1:next delay" is a little too long. so I've also been using faster "dummy" statements, like "delay = 1" (very fast) or " delay = 1 * 1" (slightly slower).
 

JoeFromOzarks

Senior Member
I apologize for the delay in a response, a horrible side effect of a debilitating back injury. I talked with my girlfriend’s daughter this evening about this topic and she instantly reminded me of something I once said, it’s a shame I don’t remember saying it: “reasonable expectation of programming predictability.” She wrote it down, well, in her phone, replacing “reasonable” with “precision.“

When she and I first started playing with multi-task programming we couldn’t precisely predict the timing of a series of events in a parallel task. In order to wobble the timing a bit, we wrote garbage to a WORD (not a BYTE) variable, wTemp1 = 1000 and wTemp2 = 1000 and (possibly, she doesn’t remember either) wTemp3 = 1000. In any event, storing those useless values gave us the delay we wanted.

She said she’d hunt for the program(s) we were tinkering with, she doesn’t recall either.

:) joe
 

AllyCat

Senior Member
Hi Joe,

You'll probably find much of the information (and a method to measure more at #12) in this thread. Note that the M2 series (in particular) execute significantly slower than previous devices (at the same clock frequency).

In my measurements, the High, Low, etc, instructions have the lowest delay, then Pause 0, with Pauseus 0 taking slightly longer! The mathematical instructions take progressively longer (multiple variables and * / operators all extending the delay) with jumps (particularly return) and the higher level instructions often taking much longer.

Cheers, Alan.
 

JoeFromOzarks

Senior Member
@Alan,

Thank you for the information.

I hope I didn't sound unhappy regarding the M2's performance, I'm not. In fact, I love 'em! My g/f's daughter simply wanted a parallel task to operate a little more predictable as far as event timing is concerned and the wTemp = 1000 execution patch put us right on it.

Me personally? I'd rather not run a program using multi-tasking, personal preference only. But I don't like fruit on my breakfast cereal either. :) My g/f’s daughter agrees with me on both points.

Having the PAUSE 0 on the first line of a multi-task routine fixed a initialization issue with output pins not booting as we desired (HIGH or LOW) and wTemp = 1000 or a HIGH / LOW as the first statement didn't fix it either.

I hope Ron found a solution.

:) joe
 
Top