Loop duration

oracacle

Senior Member
Currently banging my head against a bit of a wall, I need to listen to a pin for a period of time, the time is variable.
the best way I have come up with so far is a do loop with 2 exit option.

Code:
[color=Blue]do while [/color][color=Purple]loopnumber [/color][color=DarkCyan]< [/color][color=Purple]time_out
                                          [/color][color=Green]'listen to next sensor
                                          [/color][color=Blue]if [/color][color=Purple]casin [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]then exit
                                          inc [/color][color=Purple]loopnumber
                                          [/color][color=Blue]pause [/color][color=Navy]1                       [/color][color=Green]'0.25ms @16mhz
                                    [/color][color=Blue]loop[/color]
this will run a 08m2 @16mhz (I may bump it to 32 in the future but not sure about that yet)
any idea approximately how long this loop will take per cycle
the other route I was thinking about taking is using a serin with timeout as the input is coming from another picaxe.
the timeout doesn't have to be super accurate but the timeout maybe several seconds. max would be around 16s due to word variable limitations and affects of increased clock speed.
 

BESQUEUT

Senior Member
Currently banging my head against a bit of a wall, I need to listen to a pin for a period of time, the time is variable.
the best way I have come up with so far is a do loop with 2 exit option.

this will run a 08m2 @16mhz (I may bump it to 32 in the future but not sure about that yet)
any idea approximately how long this loop will take per cycle
the other route I was thinking about taking is using a serin with timeout as the input is coming from another picaxe.
the timeout doesn't have to be super accurate but the timeout maybe several seconds. max would be around 16s due to word variable limitations and affects of increased clock speed.
Why not simply using the Time special variable ?
Code:
[color=Navy]#Picaxe [/color][color=Black]08M2[/color]
[color=Blue]symbol time_out[/color][color=DarkCyan]=[/color][color=Navy]16[/color]
[color=Blue]symbol [/color][color=Purple]casin[/color][color=DarkCyan]=[/color][color=Purple]pin1[/color]

[color=Blue]do
      do while [/color][color=Purple]Time [/color][color=DarkCyan]< [/color][color=Blue]time_out
            if [/color][color=Purple]casin[/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]then
                        [/color][color=Green]' do what you want...
            [/color][color=Blue]endif
      loop
      [/color][color=Purple]Time[/color][color=DarkCyan]=[/color][color=Navy]0[/color]
[color=Blue]loop[/color]
 

AllyCat

Senior Member
Hi,

A problem with a DO... loop is that it's not certain how the PE will convert that to code. However, the delays of IF... THENs is well documented:

An IF... <false> THEN ... (i.e. a "fall through") takes about 800 us at 4 MHz clock (as does a simple GOTO). An IF..<true> THEN ... (i.e. a jump or goto) takes about 1.2 ms. INC loopnumber also takes about 800 us, but the PAUSE seems unnecessary (and won't necessarily take 1 ms ! ).

You basically need one "true" IF (to loop back to the start) and one "false" IF (to normally stay in the loop and jump out when required), so the total loop at 4 MHz should be about 2.8 ms at 4 MHz (or 700 us at 16 MHz) excluding the PAUSE.

Cheers, Alan.
 

hippy

Technical Support
Staff member
I would probably use -

Code:
loopnumber = 0
do while loopnumber < time_out and casin = 0
  inc loopnumber
  pause 1
loop
if casin = 1 then
  ; whatever
end if
And perhaps use the 'time' variable as BESQUEUT suggests if appropriate which it could well be.

If using a loop as above, I wouldn't worry so much how long the loop takes but wrap it in a HIGH and LOW, measure that pulse, then tweak the PAUSE time and time_out to get the time period I wanted.
 

oracacle

Senior Member
besqueut, would the time = 0 not have to go before the loop, my understanding is that the time variable increases from the moment that the picaxe is supplied power unless disable time command is given.

I had forgotten about a programme I had written for looking at the use of loops but for just holding for a given time with no need to check a pin as well.

Code:
[color=Navy]#picaxe [/color][color=Black]08m2[/color]
[color=Green]'to be used with high accuracy timer project
'c.4 and c.1 used to activate and de-activate timer[/color]

[color=Blue]setfreq m16
let [/color][color=Purple]w1 [/color][color=DarkCyan]= [/color][color=Navy]1000                             [/color][color=Green]'set holding loop star value[/color]
[color=Blue]pause [/color][color=Navy]10000                               [/color][color=Green]'allow timer to start[/color]
[color=Black]main:
      [/color][color=Blue]pause [/color][color=Navy]1000                          [/color][color=Green]'allow timer to reset
      [/color][color=Blue]high c.4                            [/color][color=Green]'start timer
      [/color][color=Blue]do
            inc [/color][color=Purple]w0                        [/color][color=Green]'increment loop counter
            [/color][color=Blue]if [/color][color=Purple]w0 [/color][color=DarkCyan]= [/color][color=Purple]w1 [/color][color=Blue]then exit          [/color][color=Green]'check for loop exit criterea
            [/color][color=Blue]pause [/color][color=Navy]1
      [/color][color=Blue]loop
      high c.1                            [/color][color=Green]'stop timer
      [/color][color=Blue]debug                               [/color][color=Green]'send loop number to debug
      [/color][color=Blue]pause [/color][color=Navy]500                           [/color][color=Green]'allow timer time to detect input
      [/color][color=Blue]low c.4                             [/color][color=Green]'set ouptuts to timer to low
      [/color][color=Blue]low c.1
      [/color][color=Purple]w1 [/color][color=DarkCyan]= [/color][color=Purple]w1 [/color][color=DarkCyan]+ [/color][color=Navy]100                       [/color][color=Green]'set next loop quantity
      [/color][color=Blue]let [/color][color=Purple]w0 [/color][color=DarkCyan]= [/color][color=Navy]0                          [/color][color=Green]'reset loop counter
      [/color][color=Blue]goto [/color][color=Black]main[/color]
I will modify this to give results more akin to the required one, however this programme is designed to run with the 08m2 connected to a timer based on hippys timer from a while back.
some testing I did back may give some insight. I dug out the spread sheet with the results. 1000 loops with no pause takes 0.58786285s, but with pause 1 in there 0.8468769s. I tested at 100 loop intervals up to 4000 loops.
by dividing the total time by the number of loops to get single loop time, the pause 1 seems to give more consistent results with the no pause showing it took less time for each loop on the larger number of loops - this it could be a function of increased resolution. in both cases the time added by adding 100 loops add fluctuated by about 0.01s (no pause 0.05-0.06s per 100 loops added, pause 1 0.08-0.09s per 100 loops added)
 

Attachments

BESQUEUT

Senior Member
besqueut, would the time = 0 not have to go before the loop, my understanding is that the time variable increases from the moment that the picaxe is supplied power unless disable time command is given.
YES you can...
Note that as it is, my program will also work because Time=0 at start.
As you said that the timeout doesn't have to be super accurate, I do not understand why you are not using a so simple solution ?
 

oracacle

Senior Member
Flexibility, I am not sure what the final application of the timeout will be. It may not use whole seconds, unless more than one solution is found there is no way of telling what is the best as there is nothing for comparison.
Hopefully tomorrow I will get to compare a few of the options with timing each option.
 

AllyCat

Senior Member
Hi,

Sadly, time never ticks at a 1/4 second rate but 2 seconds, or even 16, 32, 64 or 128 seconds at lower clock frequencies.

The graph in #5 suggests that PAUSE 1 actually adds about a 1.2 ms delay at 4 MHz.

If you want to tweak the loop to a convenient timescale, then simply drop in a PAUSEUS. IIRC a PAUSEUS 1 delays by about 700 us (@ 4 MHz), but then increases in 10 us intervals. So a PAUSEUS 30 should give about 1 ms, or a PAUSEUS 50 pad out the 16 MHz, two-exit loop to increment the loopnumber in approximately 1 ms intervals.

Cheers, Alan.
 

oracacle

Senior Member
I have just spent the last hours or so playing with different pauseus times. Using the timer and polling the output on the picaxe I have managed to get the loop to average 0.001001s which is reasonably accurate. average difference in the loops looks to be -8.99E-8, so more than accurate enough.

code I ended up testing
Code:
[color=Navy]#picaxe [/color][color=Black]08m2[/color]
[color=Green]'to be used with high accuracy timer project
'c.4 and c.1 used to activate and de-activate timer[/color]

[color=Blue]setfreq m16
let [/color][color=Purple]w1 [/color][color=DarkCyan]= [/color][color=Navy]1000                             [/color][color=Green]'set holding loop star value[/color]
[color=Blue]pause [/color][color=Navy]10000                               [/color][color=Green]'allow timer to start[/color]
[color=Black]main:
      [/color][color=Blue]pause [/color][color=Navy]1000                          [/color][color=Green]'allow timer to reset
      [/color][color=Blue]high c.4                            [/color][color=Green]'start timer
      [/color][color=Blue]do while [/color][color=Purple]w0 [/color][color=DarkCyan]< [/color][color=Purple]w1 [/color][color=DarkCyan]and [/color][color=Purple]pinc.3 [/color][color=DarkCyan]= [/color][color=Navy]1
            [/color][color=Blue]inc [/color][color=Purple]w0                        [/color][color=Green]'increment loop counter
            [/color][color=Blue]pauseus [/color][color=Navy]102
      [/color][color=Blue]loop
      high c.1                            [/color][color=Green]'stop timer
      [/color][color=Blue]debug                               [/color][color=Green]'send loop number to debug
      [/color][color=Blue]pause [/color][color=Navy]500                           [/color][color=Green]'allow timer time to detect input
      [/color][color=Blue]low c.4                             [/color][color=Green]'set ouptuts to timer to low
      [/color][color=Blue]low c.1
      [/color][color=Purple]w1 [/color][color=DarkCyan]= [/color][color=Purple]w1 [/color][color=DarkCyan]+ [/color][color=Navy]100                       [/color][color=Green]'set next loop quantity
      [/color][color=Blue]let [/color][color=Purple]w0 [/color][color=DarkCyan]= [/color][color=Navy]0                          [/color][color=Green]'reset loop counter
      [/color][color=Blue]goto [/color][color=Black]main[/color]
 
Last edited:
Top