Shop OBEX P1 Docs P2 Docs Learn Events
Time Delay in SPIN - Page 2 — Parallax Forums

Time Delay in SPIN

2»

Comments

  • Was I correct in the way that I started the timer with an initial time?
  • Is there a way to calculate how many clock cycles the firing code currently takes?
  • Sure
      elapsedtix := -cnt
    
      ' code to test here
    
      elpasedtix += cnt - 544
    

    I used this bit of code all the time to check the speed of alternative code fragments. The result is in system ticks. The - 544 bit accounts for the overhead in the two lines of Spin required to start and stop timing.

    Another strategy is to start a second cog that is watching the state of a pin. While working on a new product for EFX-TEK I used this strategy to time a background loop that I need to run every millisecond. I removed the timing restriction from the loop and simply toggled the and IO pin. Another cog monitors the pin to tell me how much time the loop is consuming. Doing this allowed me to add features to the loop that I didn't think would fit in 1ms.

    Learning to use the Propeller's cnt register and the ctrx modules for timing is really valuable.
  • This may seem like a dumb question, but how do you look at the value of elapsedtix?
  • I think you will say Parallax serial terminal. I better get studying again.
  • Yes, or any other terminal that works. If you're using Propeller Tool, PST is easiest to use. I prefer to use my variation of FullDuplexSerial for terminal IO, but you might consider using the PST object until you get a handle on things. The PST object does a lot of work for you (which is why I don't like it).
  • Am I correct that if I do my coil firing routine in another cog, that the only time I will lose from my cam timing routine will be the cog launch, and not what is in the other cog?
  • Not even that, if I understand you correctly. Only the newly launched cog gets held up, not the cog that called cognew. Starting a new cog only takes a significant amount of time for the new cog, not the one that started it. The amount of time the cog that started the other cog will take is insignificant in Spin - the equivalent of a small method call.
  • Can you please explain how the waitpeq and waitpne commands that you used, what the particular syntax means. waitpeq(1 << CAM, 1 << CAM, 0) How is this (State,Mask,Port)?
  • Beavis3215 wrote: »
    Can you please explain how the waitpeq and waitpne commands that you used, what the particular syntax means. waitpeq(1 << CAM, 1 << CAM, 0) How is this (State,Mask,Port)?

    The Propeller manual (hint, hint) is the best source of syntax explanations. If you're using Propeller Tool the manual is available from the Help menu. Once it's open press [Ctrl]+[F] to open the Find dialog. The index has links which makes it very easy to navigate.

    Give it a read.

  • What amount of ticks should I subtract from T in the main loops to compensate for the code in the loops. Originally Jon told me I should use waitpeq here, but I'm not trying to pause here. I'm trying to count ticks until CAM goes high. Is there a better way to do this, or am I missing something about waitpeq(1 << CAM, 1 << CAM, 0) in the previous set of code?
  • JonnyMac wrote:
    Also, it takes more work to deal with bytes and words as they need to be extracted from longs (Propeller's normal data size) by the interpreter.
    Are you sure about that, Jon? Spin variables live in the hub, and the rdbyte, wrbyte, etc., instructions operate just as fast as their long counterparts. PASM is different, though, since you do have to shift and mask cog variables to extract and save anything smaller than a long.

    Anyway, I don't mean to contradict, but I can't think of an instance where the Spin interpreter has to do anything special to store and retrieve bytes and longs.

    -Phil
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-10-26 03:41
    It's a general statement, of course, and I'll bet there are exceptions. I had a program once that used a bunch of byte variable and when they were changed to longs, the program actually shrank and ran a little faster. What you're saying makes absolute sense to me, yet I saw something different in an actual application. Maybe *that* program was the exception that proves your rule! :)
  • I have thought this through, If using the waitpeq command to wait for CAM to go high , then cnt will still be accumulating during this waiting period, since the system clock is still running, allowing me to time the event. If this is so then no loop such as repeat until CAM == 1 would even be necessary, and not as efficient.

    Is all of this true?
  • The cnt register is being updated every clock tick, no matter what; there is no way to stop if. This is why using it for timing requires capturing the cnt value at the beginning of the event, and then at the end.
  • Is there a delay between the time a cog is commanded to start and when it does start?
  • ElectrodudeElectrodude Posts: 1,658
    edited 2015-10-26 17:01
    Beavis3215 wrote: »
    Is there a delay between the time a cog is commanded to start and when it does start?

    Yes. I've never measured it but I'd guess it's probably around (496*16 + some) = ~8000 ticks.

    (EDIT: Add another thousand because you're doing it in Spin and it has to set up the stack.)

    (EDIT: Jon measured it, it's ~25000 ticks = ~300us)

    I don't have a prop with me, but something like this should measure it. It's basically Jon's timing code, but the starting cog does the first part and the started cog does the second half and then sets a flag telling the first cog it's ready:
    VAR
    
      long time, flag
    
      long stack[32]
    
    PUB main
    
      flag := 0
    
      time := -cnt
      cognew(cog, @stack)
    
      repeat until flag == 1
    
      '<print out time>
    
    PUB cog
    
      time += cnt - 544
    
      flag := 1
    

    EDIT: fixed "time += cnt - 544" line as Jon said below
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-10-26 15:27
    It actually takes about 25000 ticks (~300us) -- I ran your program.

    Note: The correct timer conclusion line should be:
    time += cnt - 544
    

    (In the listing above you're negating cnt)

  • Jon, can you look at my new post, homebrew EFI project, which has more information about my project. See what you think. I'm starting to get plagued by hard to figure things.
  • JonnyMac wrote:
    I had a program once that used a bunch of byte variable and when they were changed to longs, the program actually shrank and ran a little faster.
    That really intrigues me, Jon. Can you remember whether that program was doing any sign-extension stuff in Spin when used with byte variables -- i.e. stuff that could be eliminated with longs? That might account for the difference.

    -Phil
  • JonnyMac wrote: »
    It actually takes about 25000 ticks (~300us) -- I ran your program.
    Yikes! How? That must be mostly Spin's fault, right?
    JonnyMac wrote: »
    Note: The correct timer conclusion line should be:
    time += cnt - 544
    

    (In the listing above you're negating cnt)
    Thanks, fixed.
Sign In or Register to comment.