Shop OBEX P1 Docs P2 Docs Learn Events
Don't want to WAIT(CNT) around! — Parallax Forums

Don't want to WAIT(CNT) around!

markaericmarkaeric Posts: 282
edited 2011-06-28 21:22 in Propeller 1
Using waitcnt is generally a good way to control the timing of events, but what happens when you don't want to hold up execution, but instead just need to periodically check to see if a certain amount of time has elapsed and if so, execute some code?

In my naivety, I assumed comparing a previous system counter value + offset, with the current value of the counter, and checking if it was even or greater would do the trick.. After much weeping and gnashing of teeth, I realized I was wrong on so many levels (though I know some reasons *still* aren't realized). I'm sure that for most of you, the mistakes with such a method are obvious and trivial, but for me they were not... to say the least.

In my case, I "fixed" it by using a variable that I increment and test every loop cycle. This works fine, and I assume is the way this is normally implemented. But what if you don't want to use something as abstract as loop cycles, but rather something that is more flexible and recognizable such as seconds or milliseconds?

I slowly realized that when comparing a calculated value to the system counter, two aspects that have to be accounted for is rollover of the system counter, and that (in the case of spin) all integers are considered signed. Since the counter would just be periodically checked, it's not possible to simply check if the counter is greater than the target since the counter might have changed signs, which makes comparing them a lot trickier.

I haven't tried implementing anything, though if I did, it would probably be a whole bunch of ifs ands or buts. So, I ask you, esteemed and seasoned programmers, is there a simple and elegant solution to the problem? Math is not one of my strong points, so I'm prepared to feel stupid.

Comments

  • Mike GMike G Posts: 2,702
    edited 2011-06-25 19:22
    Have one process update memory locations (count) at a consistent rate (PASM) while another process reads memory from time to time. You'll need to implement memory locking so you don't get dirty reads.

    Think of it as turning on a timer while an observer watches the timer. The observer can reset the timer.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-06-25 19:28
    When checking to see if the elapsed time exceeds a certain value, do it this way:
    [color=darkgreen]
    if ([b]cnt[/b] - prevcnt > limit)
    [/color]
    

    NOT
    [color=red]
    if ([b]cnt[/b] > prevcnt + limit)
    [/color]
    

    -Phil
  • markaericmarkaeric Posts: 282
    edited 2011-06-25 19:44
    Looks so simple - but I'm still trying to visualize it.. Wouldn't you want to compare the absolute value of (cnt - prevcnt) with limit, though?
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-06-25 19:58
    Think of it this way:

    5 - (-1) == 6 (i.e. $0000_0005 - $ffff_ffff == $0000_0006)

    -Phil
  • Mike GMike G Posts: 2,702
    edited 2011-06-25 20:05
    @markaeric,I might be missing the mark but here's a count down timer. RelayTimer.spin When the timer runs out a pin goes high (24-27).
  • Mark_TMark_T Posts: 1,981
    edited 2011-06-28 21:22
    markaeric wrote: »
    Looks so simple - but I'm still trying to visualize it.. Wouldn't you want to compare the absolute value of (cnt - prevcnt) with limit, though?

    No, the difference is a time-difference and taking absolute value would confuse past and future. The time difference will have the correct sign whatever the value of cnt, so long as the difference is < 2^31. Typically the difference is your delay time which is small and thus never overflows.
Sign In or Register to comment.