Shop OBEX P1 Docs P2 Docs Learn Events
Calculating milliseconds with CNT — Parallax Forums

Calculating milliseconds with CNT

eagletalontimeagletalontim Posts: 1,399
edited 2012-10-04 12:43 in Propeller 1
Not sure if I am doing this correctly or not, but I just want to verify the best way to count milliseconds using CNT :
PUB MillisecondsInASecond | cnt1, cnt2
  repeat
    cnt1 := cnt
    waitcnt(clkfreq / 1000 * 10 + cnt)
    cnt2 := cnt
    milliseconds := cnt2 - cnt1

Comments

  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-09-30 19:25
    I may have answered my own question, but I would like to verify it as well...

    The milliseconds := cnt2 - cnt1 should be :

    milliseconds := (cnt2 - cnt1) / (clkfreq / 100)
  • kwinnkwinn Posts: 8,697
    edited 2012-09-30 20:06
    I may have answered my own question, but I would like to verify it as well...

    The milliseconds := cnt2 - cnt1 should be :

    milliseconds := (cnt2 - cnt1) / (clkfreq / 100)

    That would be deciseconds (1/100 seconds). Milliseconds would be (cnt2 - cnt1) / (clkfreq / 1000)
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-09-30 20:18
    Ok, thanks :) I am trying to get the timing as accurate as possible and so far it appears to be pretty close....
    PUB PulseCounter | updated, cnt1, cnt2
      count1 := 0
      repeat
        updated := 0  
        dira[LED]~~
        repeat while ina[Sensor] == 1
          if updated == 0
            cnt2 := cnt
            pulseCount++
            updated := 1
          outa[LED] := 1
          waitcnt(clkfreq / 1000 * 10 + cnt)
          if count1 > 0
            pulsewidth := (cnt2 - cnt1) / (clkfreq / 10000) 
          count1 := 0
        if updated == 1
          cnt1 := cnt
        count1++
        outa[LED] := 0
    
  • SRLMSRLM Posts: 5,045
    edited 2012-09-30 22:23
    Ok, thanks :) I am trying to get the timing as accurate as possible and so far it appears to be pretty close....
    PUB PulseCounter | updated, cnt1, cnt2
      count1 := 0
      repeat
        updated := 0  
        dira[LED]~~
        repeat while ina[Sensor] == 1
          if updated == 0
            cnt2 := cnt
            pulseCount++
            updated := 1
          outa[LED] := 1
          waitcnt(clkfreq / 1000 * 10 + cnt)
          if count1 > 0
            pulsewidth := (cnt2 - cnt1) / (clkfreq / 10000) 
          count1 := 0
        if updated == 1
          cnt1 := cnt
        count1++
        outa[LED] := 0
    

    It appears that your spacing is being lost while posting. The line "count1 := 0" is at the same indentation level as the "if updated == 0", and the "count++" is at the repeat level, among other things. I assume everything below the repeat is supposed to be part of the repeat block.
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-10-01 06:41
    waitcnt(clkfreq / 1000 * 10 + cnt)

    SPIN is really calculating this during runtime, so you could better say:
    waitcnt( constant(clkfeq / 1000 * 10) + cnt )

    This way the calculation of clkfreq / 1000 * 10 is done by the compiler.

    Same is true for the pulsewidth! (clkfreq / 10000) won't change during runtime, so make it a constant(clkfreq / 10000).
  • pgbpsupgbpsu Posts: 460
    edited 2012-10-01 06:47
    MagIO2 makes a good point about the run-time calculation, however, I don't think constant(clkfreq) is allowed. clkfreq MAY change during runtime (using the clkset functions) so I don't believe this cast to constant is allowed. You could short circuit this if you know the clock frequency and KNOW IT WON'T CHANGE. If so you could hardwire your expected clock frequency in here and use the constant, compile time construction. If you change the system clock without updating this it would cause problems.
  • lonesocklonesock Posts: 917
    edited 2012-10-01 07:54
    pgbpsu wrote: »
    MagIO2 makes a good point about the run-time calculation, however, I don't think constant(clkfreq) is allowed. clkfreq MAY change during runtime (using the clkset functions) so I don't believe this cast to constant is allowed. You could short circuit this if you know the clock frequency and KNOW IT WON'T CHANGE. If so you could hardwire your expected clock frequency in here and use the constant, compile time construction. If you change the system clock without updating this it would cause problems.
    Along these lines, it would be easy enough to add a runtime check like "if clkfreq <> const_clkfreq".

    Jonathan
  • ypapelisypapelis Posts: 99
    edited 2012-10-01 17:46
    I use || in front of ( t2-t1 ) for when the counter rolls over
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-10-02 22:40
    ypapelis wrote: »
    I use || in front of ( t2-t1 ) for when the counter rolls over

    The "||" isn't needed. The signed 32-bit math takes care of it for you.
  • JonnyMacJonnyMac Posts: 9,108
    edited 2012-10-04 12:43
    There's always going to be a bit of overhead in Spin, and you can account for it by doing this:
    elapsed := -cnt
      ' code you're timing goes here
      elapsed += cnt - 544
    


    If you had no code between the two lines you would end up with 0 -- what you want. The value in elapsed is in system ticks. You can convert to milliseconds by dividing by clkfreq/1000. There's a cleaner way, I believe, so long as you're not changing clock speed on-the-fly. I have this CON block in all my programs.
    con
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000                                          ' use 5MHz crystal
    
      CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq
      MS_001   = CLK_FREQ / 1_000
      US_001   = CLK_FREQ / 1_000_000
    


    It provides constants for the clock frequency (80MHz in my case) and the number of ticks in a millisecond and microsecond. If you're not changing clock speed on-the-fly then using these constants will help you improve the speed of your program by eliminating some inline calculations.

    In your case you *might* do something like this:
    waitpne(|< Sensor, |< Sensor, 0)
      elapsed := -cnt
      waitpeq(|< Sensor, |< Sensor, 0)
      elapsed := cnt - 544
      elapsed /= MS_001
    


    Of course, another thing you can do is arm a counter for positive input and let it accumulate the ticks for you. Converting ticks to milliseconds is the same.
Sign In or Register to comment.