Shop OBEX P1 Docs P2 Docs Learn Events
Counting time while doing other things — Parallax Forums

Counting time while doing other things

Sniper KingSniper King Posts: 221
edited 2008-10-07 19:49 in Propeller 1
Is there a good way to count off say 30 seconds while doing other things.· This is what I came up with but this device comes with a caveot that lives are on the line so, i want the forums opinion.

' this is what I have come up with....
Pub Control Loop
 
 
  Tm:=CNT+(30*80_000_000)
 
 repeat
 
  GetGPSReady ' Wait for GPS Fix
    CheckTimeDisp(Tm)
    GetCoords          ' Get GPS Coordinates
    CheckTimeDisp(Tm)
    KillGPSComms       ' Stop GPS Cog
    KillGPSPower       'Turn off GPS
    CheckTimeDisp(Tm)
    MaxPwr(1)          'Turn on Commo
    SendFix            'Send GPS Position info
    CheckTimeDisp(Tm)
    KillComms          ' Stop Comms Cog
    MaxPwr(0)          'Turn off Commo
    Sleep(2)
 
Pub CheckTimeDisp(x)
   If (Tm<Cnt)
     'Turn off display
 
      
 
pub Sleep(x)
 
' Sleep for x Minutes
  Repeat i from 1 to x
    
      Repeat j From 1 to 60
          Waitcnt(80_000_000+cnt)
          checkTimeDisp(tm)
 
 
 
 
 

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·- Ouch, thats not suppose to be hot!··


Michael King
Application Engineer
R&D
Digital Technology Group

Comments

  • hippyhippy Posts: 1,981
    edited 2008-09-12 17:40
    You need to change "If (Tm<Cnt)" to something like "if (Tm-Cnt) < 0". Not sure if that's right but there have been previous forum posts on this.

    Also, rather than use 80_000_000 as hard-wired operating speed, using CLKFREQ makes it far more portable; "Waitcnt(CLKFREQ+cnt)" will wait one second regardless of operating speed. Likewise "Tm:=CNT+(30*CLKFREQ)".
  • PhilldapillPhilldapill Posts: 1,283
    edited 2008-09-12 18:03
    I've often wondered this too... I've needed a clock for the propeller but didn't want to devote an entire cog to it. What I came up with is some code that garraunteed to execute under 1 second. Basically, I would set CycleTime to cnt + 1 second, then do my CPU intensive code that I knew would only take like 0.9 seconds, then call a waitcnt(Time). This would repeat the cycle exactly 1 second apart. This way, I get my code for something else(in this case some ADC's), and my clock all in one cog. I gotta run, but I hope you get the idea without actual code. Btw, sniperking, are you millitary? If so, what do you do that has live's on the line?(If you can't talk about it, no problem.)
  • Sniper KingSniper King Posts: 221
    edited 2008-09-12 18:11
    This Device is 11 years in the making. Design,and concept to 10 as we waited for the technology to come around.

    I am former military (Army (Nat Guard) 11B (Infantry)) I was a sniper and sniper deployment NCO for 4 years.

    This device is a tracking device. It gets GPS coordinates (Thank you Paul Hubner for the clever GPS parser!) and sends them wirelessly to a LAN enabled receiver and then onto a SQL server to record all the data from the different trackers. It also navigates by way of navigation packets sent back to the device and an uOLED display to show a compass and other text data.

    The boards are done. The PC based software is done. The Server is done. The Tracker software is not.

    The military is telling me to hurry up. Dept. of Homeland security is saying hurry up. Blackwater is saying hurry up.

    So anyway, this is a huge project for me.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·- Ouch, thats not suppose to be hot!··


    Michael King
    Application Engineer
    R&D
    Digital Technology Group
  • SethSeth Posts: 61
    edited 2008-09-12 23:51
    Wow! Cool project!
    I have looked a little into tracking devices, but never got far.
    Plus I am a huge fan of Blackwater, so I am very impressed.
    Let us know how it goes.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    The pessimist is never disappointed.
  • evanhevanh Posts: 15,545
    edited 2008-09-13 06:46
    Be careful with your working range (Dynamic range). There is only about +-26 seconds at 80 MHz count rate. Better idea is to make a timer system that is built around, say, a millisecond counter. This gives almost 25 days.

    It is possible to double the dynamic range by using unsigned arithmetic but it requires a little more juggling of code. If you can access the carry flag then unsigned becomes quite effective. But, that would still only be 52 seconds.


    Evan
  • hippyhippy Posts: 1,981
    edited 2008-09-13 16:07
    Sniper King said...
    The military is telling me to hurry up. Dept. of Homeland security is saying hurry up. Blackwater is saying hurry up. So anyway, this is a huge project for me.

    There's no way of saying this without causing some offence but it surprises me that the "US military complex" has such a project in the hands of a company which has no proven track record or demonstration of competence in the components being used.

    Don't get me wrong, I wish you every success in the project, but if I were an over-seeing project manager on what seems to be such an important project I'd be a bit concerned that those developing it were having to ask how to do the basics. For something mission critical and perhaps life-critical I'd want to see all sorts of competence proofs before having confidence in what was being developed and deployed.

    Maybe it's a 'different culture' thing. When I worked for a CMM Level 3 company there was more work ( and money made ) in defining the project, agreeing and providing proof of concept and demonstrating functionality and deliverables than in actually doing any 'real work'.
  • Sniper KingSniper King Posts: 221
    edited 2008-09-14 01:04
    The idea here is a proof of concept for funding. While you are correct about my programming of the propeller, the idea is show them it can be done. This is not rocket science either. It is easy to get a GPS string, parse it, create a formated packet and send it out serially. On the receive end it is easy to receive a packet, parse it, and display the results. The hard part I was having was the great circle math and going from string to float and getting enough digits after the decimal point to have accuracy.

    While I ask alot of questions about the basics, it is regarding the spin language. I have been a programmer for over 20 years. Java, C, VB and now I am learning spin. If I could write this in my native languages I would but spin is what I have to use here. So the learning curve attached to this project included spin.

    One more thing. Never in my life have I said I could do a project if I knew I couldn't. As of last night, everything works and works well. The last thing is to add the display which will arrive on monday and put the compass on it which has already been written and tested (broke the last one).

    The military didn't ask us to do this. We went head to head with L3, Lucent, and Motorola. I personally felt very small when we showed up at 29 palms for a demo. We watched all of them fail except Lucent whos tracker was about 10x6x1.5 with a 21 inch antenna on it. It worked flawlessly. We watched their engineers laugh at us with our 3 components (2 trackers and a node). Except ours worked flawlessly too. Our batteries lasted 2.7x as long as lucent and all the military brass on hand got to stay inside their air conditioned offices and watch it as our software polled our server in AZ and updated the locations of our trackers. When it was over they asked me to put a display on it that would handle simple text messages. I said sure and added we can give them the ability to navigate as well. They loved it and said go.

    So while we are not a giant company, the proof was in the (propeller, the size (2x6.5x1) and the battery life) pudding.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·- Ouch, thats not suppose to be hot!··


    Michael King
    Application Engineer
    R&D
    Digital Technology Group
  • grasshoppergrasshopper Posts: 438
    edited 2008-09-14 05:04
    Back to the topic, I would love to see something like this done. I also have been trying to make some cog keep track of time and up date my main code that is ready. It seems easy enough but i am struggling.
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-09-14 07:03
    Hello Computerguy,

    maybe you have not seen my posting from yesterday

    So i post the code right here

    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
      
    VAR
      long timer1
      long eTime1
    
      long timer2
      long timer3
    
    PUB Main
      'the FIRST PUB-Method inside a spinfile is ALWAYS the startpoint where the program starts to run    
    
      timer1 := cnt 'make inital snapshot of systemcounter 
      timer2 := cnt 'make inital snapshot of systemcounter 
      timer3 := cnt 'make inital snapshot of systemcounter 
    
      repeat
        'do whatever you like inside this loop
        'and what should be done with almost no delay
        
        'the method elapsed_time_msec calculates the time that has gone since
        'variable timer1 has set to the (former) value of systemcounter
        eTime1 := elapsed_time_msec(timer1) 
    
        if eTime1 => 100 '<== this is the TimePeriod of millisecs that were "waited" 'before the code below is executed 
          timer1 := cnt 'make new snapshot of systemcouner to set new startvalue
            ' code here what should be executed after the TimePeriod definded in the if condition above   
    
        if elapsed_time_msec(timer2) => 200 
          timer2 := cnt 'make new snapshot of systemcouner to set new startvalue
          'toggle LED2 or what ever    
    
        if elapsed_time_msec(timer3) => 400
          timer3 := cnt 'make new snapshot of systemcouner to set new startvalue
          'toggle LED3 or what ever    
    
    
          
    PUB elapsed_time_msec(p_TimeVar) | RightNow, ClockTicks
    
      RightNow := cnt
    
      if RightNow < p_TimeVar                          
        ClockTicks := ||($FFFFFFFF - RightNow + p_TimeVar)  
      else
        ClockTicks := ||(RightNow - p_TimeVar)
    
      result := ClockTicks / (clkfreq / 1_000) 'calculate milliseconds
    
    
      '################################################################################
      'explanation how it works
      ' SPIN treats longs as SIGNED longs this means bit-No 32 represents the sign "+-"
      ' the systemcounter thinks of the 32bits as UNsigned meaning bit 32 is
      ' just another bit of the number and NOT a sign "+-" 
      ' if one or both values are negative it could happen
      ' that the result is negative too
      ' the command "||" calculates the absolute value of the SIGNED longs
    
      'even if the systemcounter has wrapped around since the snapshot of
      'systemcounter (value of parameter p_TimeVar),
      'this method calculates the timedifference in the right way
      
      'wrap-around example with easy numbers: counter maxvalue 1000
      'p_TimeVar containing value 980
      'time goes on counter wraps around from 1000 to 0
      'time goes on 
      'RightNow containing 300. This means 20 ticks until maximum 1000 and 300 ticks
      'since wrapping from 1000 to 0 in summary 320 ticks of time has gone
      'this is calculated by MaxCounter - p_TimeVar + RightNow
      'in numbers              1000     -   980     +   300     = 320
      'the real systemcounter has 32bits max value 2^32 -1 = 4294967295
      'hexadecimal $FFFFFFFF
      '################################################################################
     
    'end of PUB elapsed_time_msec(p_TimeVar) | RightNow, ClockTicks
    
    



    I think with this code-template it is easy for you to adapt it to your project

    If you have any questions feel free to ask me.

    I have a question too:

    how do you implement new parts of code into your project ?
    Do you insert it right away or do make tests in a SEPARATE small program ?

    best regards

    Stefan
  • Sniper KingSniper King Posts: 221
    edited 2008-09-14 23:23
    Ok i figured it out.· Though the latest post is good and I will probably use it.· what i did is create a method tha I call often in my loop.· Nothing in my loop takes very long so I can call it hundred of times a second.· I send a method call when i want to start counting (CheckTime(1))·) The (1) indicates reset the counter variable.· Next, inside the loop I call If CheckTime(0)==0.· The (0) indicates that we are checking CNT against the counter variable.· The statement i use for setting the counter variable is...

    TMR:=((2*clkfreq)+cnt)
    ·This gives me a 2 second window to check into.

    If the cnt>TMR then I pass back a 1

    This has worked flawlessly for my project so far.· Though the timing isn't super accurate,· i am well within a second and I can easily count of 30 seconds without a problem

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·- Ouch, thats not suppose to be hot!··


    Michael King
    Application Engineer
    R&D
    Digital Technology Group
  • unebonnevieunebonnevie Posts: 20
    edited 2008-09-15 05:07
    Sniper King, I think I played Halo with you online once in a while...smile.gif
  • hippyhippy Posts: 1,981
    edited 2008-09-15 13:12
    "CNT > tmr"

    I think you've been lucky that this has worked as well as it has. This is a signed comparison and
    CNT runs 0..+big, -big..-1, 0..+big. There are all sorts of issues with values which are across the
    transition points.

    As I say, I cannot remember the exact code but it's "if (tmr-CNT) > 0" or similar; check previous
    forum posts where this has been discussed in detail.
  • Sniper KingSniper King Posts: 221
    edited 2008-09-15 15:37
    I think i understand what you are saying Hippy.· However my timing doesnt have to be perfect,· it needs to finish at or around 30 seconds.· Though perfect timing would be cool, this is more than enough for my application and actually helps in a way with bandwidth issues.· If 100 people turn on their trackers at exactly the same time, perfect timing would cause packet collisions to occur.· with this "imperfection" thown in,· there is a little bit of random that will cause them to space out their transmissions.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·- Ouch, thats not suppose to be hot!··


    Michael King
    Application Engineer
    R&D
    Digital Technology Group
  • Mike GreenMike Green Posts: 23,101
    edited 2008-09-15 15:44
    This is not about "perfect timing". If you're using a signed comparison to compare two values from the CNT register as less than or greater than, it simply won't work properly during half of the roughly 50 second time period.
  • grasshoppergrasshopper Posts: 438
    edited 2008-09-15 17:42
    StefanL38 said...
    Hello Computerguy,

    maybe you have not seen my posting from yesterday

    So i post the code right here

    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
      
    VAR
      long timer1
      long eTime1
    
      long timer2
      long timer3
    
    PUB Main
      'the FIRST PUB-Method inside a spinfile is ALWAYS the startpoint where the program starts to run    
    
      timer1 := cnt 'make inital snapshot of systemcounter 
      timer2 := cnt 'make inital snapshot of systemcounter 
      timer3 := cnt 'make inital snapshot of systemcounter 
    
      repeat
        'do whatever you like inside this loop
        'and what should be done with almost no delay
        
        'the method elapsed_time_msec calculates the time that has gone since
        'variable timer1 has set to the (former) value of systemcounter
        eTime1 := elapsed_time_msec(timer1) 
    
        if eTime1 => 100 '<== this is the TimePeriod of millisecs that were "waited" 'before the code below is executed 
          timer1 := cnt 'make new snapshot of systemcouner to set new startvalue
            ' code here what should be executed after the TimePeriod definded in the if condition above   
    
        if elapsed_time_msec(timer2) => 200 
          timer2 := cnt 'make new snapshot of systemcouner to set new startvalue
          'toggle LED2 or what ever    
    
        if elapsed_time_msec(timer3) => 400
          timer3 := cnt 'make new snapshot of systemcouner to set new startvalue
          'toggle LED3 or what ever    
    
    
          
    PUB elapsed_time_msec(p_TimeVar) | RightNow, ClockTicks
    
      RightNow := cnt
    
      if RightNow < p_TimeVar                          
        ClockTicks := ||($FFFFFFFF - RightNow + p_TimeVar)  
      else
        ClockTicks := ||(RightNow - p_TimeVar)
    
      result := ClockTicks / (clkfreq / 1_000) 'calculate milliseconds
    
    
      '################################################################################
      'explanation how it works
      ' SPIN treats longs as SIGNED longs this means bit-No 32 represents the sign "+-"
      ' the systemcounter thinks of the 32bits as UNsigned meaning bit 32 is
      ' just another bit of the number and NOT a sign "+-" 
      ' if one or both values are negative it could happen
      ' that the result is negative too
      ' the command "||" calculates the absolute value of the SIGNED longs
    
      'even if the systemcounter has wrapped around since the snapshot of
      'systemcounter (value of parameter p_TimeVar),
      'this method calculates the timedifference in the right way
      
      'wrap-around example with easy numbers: counter maxvalue 1000
      'p_TimeVar containing value 980
      'time goes on counter wraps around from 1000 to 0
      'time goes on 
      'RightNow containing 300. This means 20 ticks until maximum 1000 and 300 ticks
      'since wrapping from 1000 to 0 in summary 320 ticks of time has gone
      'this is calculated by MaxCounter - p_TimeVar + RightNow
      'in numbers              1000     -   980     +   300     = 320
      'the real systemcounter has 32bits max value 2^32 -1 = 4294967295
      'hexadecimal $FFFFFFFF
      '################################################################################
     
    'end of PUB elapsed_time_msec(p_TimeVar) | RightNow, ClockTicks
    
    



    I think with this code-template it is easy for you to adapt it to your project

    If you have any questions feel free to ask me.

    I have a question too:

    how do you implement new parts of code into your project ?
    Do you insert it right away or do make tests in a SEPARATE small program ?

    best regards

    Stefan

    Man this look great for my intentions. I am still trying it out but so far so good. Thanks
  • Sniper KingSniper King Posts: 221
    edited 2008-09-16 21:55
    How many milliseconds will this count to?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·- Ouch, thats not suppose to be hot!··


    Michael King
    Application Engineer
    R&D
    Digital Technology Group
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-09-16 23:23
    hello Michael,

    somehow this is a very general question. So for me it is hard to understand what you mean exactly.

    This is easy to calculate
    The systemcounter has 32 bits 2^32 = 4294967296
    At a systemclock of 80 MHz the systemcounter will wrap around after

    4.294.967.296 / 80.000.000 = 53,687 seconds. In milliseconds 53687

    For longer timeperiods you could use a nested if-condition with a countervariable

    
    If elapsed_time (TimeVar) => 1000 '1 second
      CountSeconds++
      if CountSeconds => 31536000 ' 3600 * 24 * 365 = no of seconds within a YEAR
        PlayBirthdaySong
    
    
    





    best regards

    Stefan
  • simonlsimonl Posts: 866
    edited 2008-09-17 12:45
    Not sure if I'm correct, but I think => should be >= in spin wink.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheers,
    Simon

    www.norfolkhelicopterclub.com

    You'll always have as many take-offs as landings, the trick is to be sure you can take-off again wink.gif
    BTW: I type as I'm thinking, so please don't take any offence at my writing style smile.gif
  • grasshoppergrasshopper Posts: 438
    edited 2008-09-17 13:16
    simonl said...
    Not sure if I'm correct, but I think => should be >= in spin wink.gif

    No the correct way to present it in spin is
    =>
    



    Page 250 of the Propeller manual

    burger.gif
  • Paul BakerPaul Baker Posts: 6,351
    edited 2008-09-17 17:49
    Simon, the easiest way to remember which way it is, is to remember the C notation +=. Spin takes this template and expands it across almost every operator, so any operator followed by = is an assignment operator. Therefore the comparision operators are the reverse, so the = sign always comes first when it is in a comparision.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • Sniper KingSniper King Posts: 221
    edited 2008-09-18 07:22
    StefanL38,
    You are my hero today!· Your counter is perfect! A few minor changes to fit my code and I am working flawlessly.· The forum was right about my method... It was completely unreliable.· Yours counts every time right on the money!· thank you!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·- Ouch, thats not suppose to be hot!··


    Michael King
    Application Engineer
    R&D

    Check out Project: PSAV Persistent Sailing Autonomous Vehicle
  • evanhevanh Posts: 15,545
    edited 2008-09-18 10:02
    Thanks Paul. Good info. [noparse]:)[/noparse]
  • Paul_HPaul_H Posts: 85
    edited 2008-10-07 19:49
    Hi Mike,

    I'm glad (and surprised!!) anything I've done was of help. On the Shoulders of Giants eh?

    This a dumb solution - but why not use the clock from the GPS? Thats what we us in telecom, and even if you don't go for stratum-1 (ie a best level of timing accuracy) the clock is still certainly accurate at the 'about 30 seconds' resolution smile.gif

    Paul
Sign In or Register to comment.