timing of main progam loop - pulse counter

jsmanson

Member
Hello gang again, I have a quick question for the experts here. I have a progam loop that is intended to run in a tight loop, checking 6 different flow pulses (the pulses come in at 330 per liter of water pumped) I am trying to determine if the program loop is 'quick' enough to catch the one channel that flows the highest, about 16 US Gal/min. I figure this is about 350 pulses per second, 3 ms per pulse cycle (say 1.5 ms between a 'high' and a 'low' signal). The other flows are much less, about 4 gpm, so maybe I'd suggest halving the 1.5 ms to 0.75ms to allow the program to count any one of the 6 channels. So can the program loop swing around in say 750us?

The main program loop does the main counting, every 2 seconds or so it does other things, so it will miss some counts while it is doing secondary tasks, but I can slow that to say every 10 seconds by increasing the loop counter trigger.

Not sure how to actually measure the time between program loops, is it the timer command? How do I measure the time without affecting the actual loop time?

Any usggestions on how I can optimse the code to run more eficianetly, other than offloading counting to another picaxe?

Thanks in advance! John
 

Attachments

inglewoodpete

Senior Member
I've had a look at your code. It's very difficult for someone to come in cold an understand what you're trying to do. I would need more comments in the code and better chosen variable names before I could understand.

I can offer one code improvement:
Code:
[color=Blue]let [/color][color=Black]inputs [/color][color=DarkCyan]= [/color][color=Purple]pinsb  [/color][color=Green]'this updates b1 (Variable "inputs") to the current value of the digital inputs on port B
'now we have to blank out pinb.0 and pinb.7 which are not used for digital inputs.[/color]
[color=Black]inputs [/color][color=DarkCyan]= NOT [/color][color=Black]inputs
inputs [/color][color=DarkCyan]= [/color][color=Black]inputs [/color][color=DarkCyan]OR [/color][color=Navy]%10000001[/color]
[color=Black]inputs [/color][color=DarkCyan]= NOT [/color][color=Black]inputs [/color]
Could be replaced with:
Code:
[color=Purple]inputs [/color][color=DarkCyan]= [/color][color=Purple]pinsb [/color][color=DarkCyan]AND [/color][color=Navy]%01111110  [/color][color=Green]'Copy states of B.1 to B.6[/color]
 

lbenson

Senior Member
To time a loop without (very much) altering it, try placing HIGH SOMEPIN at the beginning, and LOW SOMEPIN at the end. Tie that pin and 0V to another picaxe, e.g., 08M2, and use the pulsin command to measure the time taken in 10us units, up to 0.65535s.

[bpowell's idea below of a toggle is better because it includes the loop mechanism timing. Start the pulsin when SOMEPIN goes low--then pulsin will give you the duration of the next loop.]
 

bpowell

Senior Member
To get an idea how long your loop takes to run, toggle an io line at the top of the loop, next time through, it gets toggled again, etc... Then take a look at the signal on a scope and see what the on-time is ... Or off-time... That's one loop.
 

lbenson

Senior Member
Something like this on the 08M2 should work.
Code:
#picaxe 08m2

pause 1000 ' or however long it takes master to start looping

main: ' this should give timing for most loops
      ' might miss some loops because of the time sertxd takes
      ' but should give a good idea of master loop time in 10*uS
      ' --good for loops taking less than .65 seconds
  do
    do while pinC.3 = 1 loop ' wait until master has toggled low
    pulsin C.3,1,w13
    sertxd(#w13," times 10 microseconds",cr,lf)
  loop
 
Last edited:

hippy

Technical Support
Staff member
Another trick for timing loops if one doesn't have a scope is to put the loop within a FOR-NEXT and execute that say 50000 times. Put that in a DO-LOOP with a SOUND command before the FOR-NEXT then use a stop watch to time between beeps -

Code:
Do
  Sound ...
  For w27 = 1 To 50000
     ... code to be timed here
  Next
Loop
There's an overhead in the FOR-NEXT but it should give a reasonable ballpark figure.

For handling multiple counters I would probably start with something like this, 8 counters, one for each C.x pin -

Code:
Symbol new    = b0   ; new must be b0
Symbol now    = b1
Symbol was    = b2

Symbol count0 = w10
Symbol count1 = w11
Symbol count2 = w12
Symbol count3 = w13
Symbol count4 = w14
Symbol count5 = w15
Symbol count6 = w16
Symbol count7 = w17

now = pinsC
Do
  Do
    was = now
    now = pinsC
    new = now ^ was & now
  Loop Until new <> 0
  count0 = count0 + bit0
  count1 = count1 + bit1
  count2 = count2 + bit2
  count3 = count3 + bit3
  count4 = count4 + bit4
  count5 = count5 + bit5
  count6 = count6 + bit6
  count7 = count7 + bit7
Loop
 

jsmanson

Member
I've had a look at your code. It's very difficult for someone to come in cold an understand what you're trying to do. I would need more comments in the code and better chosen variable names before I could understand.

I can offer one code improvement:
Code:
[color=Blue]let [/color][color=Black]inputs [/color][color=DarkCyan]= [/color][color=Purple]pinsb  [/color][color=Green]'this updates b1 (Variable "inputs") to the current value of the digital inputs on port B
'now we have to blank out pinb.0 and pinb.7 which are not used for digital inputs.[/color]
[color=Black]inputs [/color][color=DarkCyan]= NOT [/color][color=Black]inputs
inputs [/color][color=DarkCyan]= [/color][color=Black]inputs [/color][color=DarkCyan]OR [/color][color=Navy]%10000001[/color]
[color=Black]inputs [/color][color=DarkCyan]= NOT [/color][color=Black]inputs [/color]
Could be replaced with:
Code:
[color=Purple]inputs [/color][color=DarkCyan]= [/color][color=Purple]pinsb [/color][color=DarkCyan]AND [/color][color=Navy]%01111110  [/color][color=Green]'Copy states of B.1 to B.6[/color]

Thank-you - yes that will work better! The program basically counts pulses (using variables x1-x5) till it reaches 330, then increments the daily flow variable (f_xxxx, 5 of these), which is in liters of water, and resets the "x" counter back to 0. As the 330 count is > 256, I have to use word variables for the counters, would probably be faster to use byte variables, and covert the flow to liters (flow = f_variable * 256 / 330), but I didn't think it would be worth it, easier just to use word variables. - J
 

jsmanson

Member
Another trick for timing loops if one doesn't have a scope is to put the loop within a FOR-NEXT and execute that say 50000 times. Put that in a DO-LOOP with a SOUND command before the FOR-NEXT then use a stop watch to time between beeps -

Code:
Do
  Sound ...
  For w27 = 1 To 50000
     ... code to be timed here
  Next
Loop
There's an overhead in the FOR-NEXT but it should give a reasonable ballpark figure.

For handling multiple counters I would probably start with something like this, 8 counters, one for each C.x pin -

Code:
Symbol new    = b0   ; new must be b0
Symbol now    = b1
Symbol was    = b2

Symbol count0 = w10
Symbol count1 = w11
Symbol count2 = w12
Symbol count3 = w13
Symbol count4 = w14
Symbol count5 = w15
Symbol count6 = w16
Symbol count7 = w17

now = pinsC
Do
  Do
    was = now
    now = pinsC
    new = now ^ was & now
  Loop Until new <> 0
  count0 = count0 + bit0
  count1 = count1 + bit1
  count2 = count2 + bit2
  count3 = count3 + bit3
  count4 = count4 + bit4
  count5 = count5 + bit5
  count6 = count6 + bit6
  count7 = count7 + bit7
Loop
Nice - thanks Hippy, that's great, I have a digital scope so for fun I will time my existing code, then make your modification and time it again :)
 
Top