Shop OBEX P1 Docs P2 Docs Learn Events
Is there a more efficient way of doing this code? — Parallax Forums

Is there a more efficient way of doing this code?

iQuitiQuit Posts: 78
edited 2010-04-28 03:42 in Propeller 1
Here is a method I created so that I could time stuff, but also be able to reset the timer mid timing if needed. It runs in another cog, and stops that cog when finished.
It also has a time out flag that goes to 1 when the timer is done. This can be monitored within the main object that started the cog.
I'm new to spin, so this took me two hours (should I admit that?). It works, but it seems a little kludgy to me. Any ideas as to how it could be done more efficiently?
clock settings and other stuff were left out for brevity.
VAR
 long TimerStack[noparse][[/noparse]30]   
 long reset_secs, TimeOutFlag

PUB Main    
  
 cognew(Timer(10), @TimerStack) 'call to Timer method with input_secs of 10
.
 check TimeOutFlag  'see if timer has run out
.
 reset_secs := 20   'reset Timer at any time by giving reset_secs a new value, 20 here     
.
.

PUB Timer(input_secs)|t, start_secs

 TimeOutFlag := 0
 reset_secs := input_secs
 start_secs := input_secs
 t := cnt

 repeat while input_secs > 0
  waitcnt(t += clkfreq)
   if reset_secs <> start_secs
    input_secs := reset_secs
    start_secs := reset_secs
  input_secs -= 1       

 TimeOutFlag := 1
 cogstop(cogID)




Dan := thanks smilewinkgrin.gif

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"She may not be very pretty now, but she was somebody's baby once." Bugs Bunny

Post Edited (iQuit) : 4/27/2010 5:35:38 AM GMT

Comments

  • MagIO2MagIO2 Posts: 2,243
    edited 2010-04-27 11:47
    It looks like it's not 100% working. If you want to reset the timer to the value it originally had it won't do the reset. Know what I mean?

    You start the function with Timer(10). Now you do some stuff for a while and then say: reset_secs := 10 . In this case the timer would not be resetted!

    Wanna think about it by yourself? The solution will also lead to a version which needs one variable less.

    As far as I know cogstop is not needed. If the function called by cognew ends, the COG is stopped automatically.
  • iQuitiQuit Posts: 78
    edited 2010-04-27 15:14
    You are correct on both accounts, I'll look at it and see what I can come up with.
    But maybe a clue first?

    Dan := thanks smilewinkgrin.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "She may not be very pretty now, but she was somebody's baby once." Bugs Bunny

    Post Edited (iQuit) : 4/27/2010 3:31:56 PM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-04-27 18:50
    I'd do it like parameter passing to PASM code works most times. It does not really make sense to reset the timer to 0, as then you'll end up in a very long running loop. Can you see it? So you can change the if reset_secs <> input_secs to .....

    Enough for a hint ;o)
  • iQuitiQuit Posts: 78
    edited 2010-04-28 00:16
    Okay. I've changed things up a bit. Decided to make it an object. Sorry MagIO2, but I don't know anything about ASM, so it's got to be spin for now. Maybe I'll pick that
    one up later.

    I haven't tried this yet, but it looks as though it'll work. I check for zero and negative values coming in. I think that this will work! I'll try this as soon as I have time.

    Made some changes; added a run status variable.

    {{TimerObject.spin, Ver .1
     Re-setable timer that counts by seconds; Pause, Resume, Reset, Stop and Status calls allow control of the timer from the main object.}}
    
    VAR
     long TimerStack[noparse][[/noparse]50]   
     long input_time, reset_time, TimeOutFlag, reset, pause, TimerID, runStatus
    
    '----------------PUB methods-------------------------
    PUB Init
     runStatus := 0  'may not need this at all
    
    PUB Start(input_time)
     if input_time > 0 AND runStatus == 0
      TimerID := cognew(Timer(input_time), @TimerStack)
     else return 0
    
    PUB Reset(reset_time)
     if reset_time > 0 AND runStatus == 1
      reset := 1
     else return 0
    
    PUB Pause
     Pause := 1
    
    PUB Resume
     Pause := 0
    
    PUB Stop
     if runStatus == 1
      runStatus := 0
      TimeOutFlag := 0
      stopcog(TimerID)
     else return 0
    
    PUB Status
     return  TimeOutFlag
    
    '------------------PRI methods-----------------------
    PRI Timer(input_time)|t
     runStatus := 1
     TimeOutFlag := 0
     t := cnt
     
     repeat while input_time > 0
      waitcnt(t += clkfreq)
       if reset
        input_time := reset_time
        reset := 0
      repeat while pause
       waitcnt(t += clkfreq)
      input_time -= 1
    
     TimeOutFlag := 1
     Cleanup
     cogstop(cogID)
    
    PRI Cleanup
     runsStatus := 0
     reset := 0
     pause := 0
    
    



    Using:

    OBJ
    Timer : "TimerObject"

    Timer.Start(60)

    Timer.pause

    Timer.Reset(45)
    etc. etc.

    All criticism welcomed.
    Dan == Thanks

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "She may not be very pretty now, but she was somebody's baby once." Bugs Bunny

    Post Edited (iQuit) : 4/28/2010 3:55:52 AM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-04-28 03:42
    Bad idea to do a COGSTOP anytime. You will kill your main COG if you call stop without starting before. That's why all code doing a COGNEW looks like that:

    TimerID:=cognew(...) + 1

    Then you know, if TimerID==0 no timer has been started before. If you want to stop the COG you'd say:

    cogstop( TimerID-1 )

    Variable reset is not needed ... Your loop looks the same as before, so reset_time == 0 is not valid. So, why not check if reset_time<>0 for takeover of the new time?
Sign In or Register to comment.