Shop OBEX P1 Docs P2 Docs Learn Events
How to Measure Elapsed Time if Longer Than System Clock Loop — Parallax Forums

How to Measure Elapsed Time if Longer Than System Clock Loop

coryco2coryco2 Posts: 107
edited 2013-04-18 12:20 in Propeller 1
I am trying to set up a central "elapsed time" counter which methods in multiple cogs can all refer to. Easy enough, just write cnt to a global variable at the start and have the methods compare the current cnt at any given time to that value. But then how to handle when the system counter reaches its maximum value and loops around? I vaguely remember something to do with shifting bits to track a change like this, but the concept has escaped me. Can anyone point me in the right direction, please?

Comments

  • lonesocklonesock Posts: 917
    edited 2013-04-16 09:18
    I do this:
    ''  Timing
    DAT
    mstimer_ms    long      0
    mstimer_last  long      0
    PUB msUpdate : delta_ms | ms_clocks
      ms_clocks := (clkfreq + 500) / 1000
      delta_ms := (cnt - mstimer_last) / ms_clocks
      mstimer_ms += delta_ms
      mstimer_last += delta_ms * ms_clocks
    
    Some main loop somewhere can call msUpdate repeatedly, and anyone can read the 'mstimer_ms' long. If you want the update function to be callable from multiple cogs, there is a lock version here.

    Jonathan
  • coryco2coryco2 Posts: 107
    edited 2013-04-16 09:19
    Ok, I think I figured out a way using the POSX constant:.

       IF cnt < time
          time := (POSX - time)+ cnt
    
    
  • Dave HeinDave Hein Posts: 6,347
    edited 2013-04-16 10:39
    If your elapsed time is less than 2^31 cycles you can just do (cnt - start_cycles) to compute the elapsed time. This works even when CNT wraps. If your elapsed time can be more than 2^31 cycles, and msec resolution is OK then I would use lonesock's routine.
  • coryco2coryco2 Posts: 107
    edited 2013-04-18 11:25
    @lonesock

    Why are you adding 500 in this line?

    ms_clocks := (clkfreq + 500) / 1000
  • lonesocklonesock Posts: 917
    edited 2013-04-18 12:20
    I call it pre-rounding. Integer division will just truncate the fractional part. If wanted to round to the nearest integer, you would typically say something like this (in C notation):
    i = (int)( float_a / float_b + 0.5 )
    
    Since 0.5 can be re-written as 0.5 * float_b / float_b, that means you can combine terms and say
    float_a / float_b + 0.5 = (float_a + 0.5 * float_b) / float_b
    
    So adding half of the denominator to the numerator before the division is the same as adding 0.5 after the division, and it can be done with only integers.

    Does that make sense?
    Jonathan
Sign In or Register to comment.