Waiting untill a certain time without using waitcnt, What am I doin wrong here??
Jorge P
Posts: 385
In the following code I am trying to mark a point in time, then use a variable to mark 1 second past that point. i loop untill I reach the 1 second mark and increment TickCount. But It stops updating TickCount every few iterations, for a while, then continues. So what am I doing wrong, if not everything. Also what is the purpose of WMin in Clock.Spin (in obex)
My goal is to wait to do something until I reach a certain point in time without using waitcnt. I cant stop the cog.
EDIT: Solution is in Post #8 of this thread! Thanks Stefan.
My goal is to wait to do something until I reach a certain point in time without using waitcnt. I cant stop the cog.
EDIT: Solution is in Post #8 of this thread! Thanks Stefan.
{{ Continue through a loop until a certain amount of time has passed without pausing or stopping the cog using waitcnt. using code samples from "Clock.spin V1.1" by Jeff Martin in obex ----- }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 WMin = 381 ' in Clock.spin ?? What is this for? OBJ ' T : "Clock" Debug : "Parallax Serial Terminal" VAR long Now, StartPoint, EndPoint, SyncPoint, LoopNum byte TickNum, HitMark PUB Main Debug.start(115200) Now := 0 ' the current point StartPoint := 0 ' EndPoint := 0 ' the point equal to 1 second past SyncPoint SyncPoint := 0 ' stores the point to sync to LoopNum := 0 ' stores the number of time we have looped so far TickNum := 0 ' stores how many times we hit the EndPoint HitMark := 0 ' stores 0 or 1 to indicate if we hit the mark repeat LoopNum++ if SyncPoint == 0 ' were at the beginning of the program MarkSync ' sets SyncPoint StartPoint := GetSync EndPoint := StartPoint + (clkfreq * 1) #> WMin '??? one second from now?????? Now := cnt else ' were in progress if Now => EndPoint ' reset values and update the tickNum Now := 0 StartPoint := 0 EndPoint := 0 SyncPoint := 0 TickNum++ HitMark := 1 else HitMark := 0 Now := cnt SendIt PUB SendIt NewLine Seperator NewLine Debug.Str(String("StartPoint is: ")) Debug.Dec(StartPoint) NewLine Debug.Str(String("EndPoint is: ")) Debug.Dec(EndPoint) NewLine Debug.Str(String("Now is: ")) Debug.Dec(Now) NewLine Debug.Str(String("LoopNum is: ")) Debug.Dec(LoopNum) NewLine Debug.Str(String("TickNum is: ")) Debug.Dec(TickNum) NewLine Debug.Str(String("HitMark is: ")) Debug.Dec(HitMark) PUB NewLine Debug.NewLine PUB Seperator Debug.Chars($2D, 25) ' print 25 hyphens PUB MarkSync {{Mark reference time for synchronized-delay time windows. Use one of the WaitSync methods to sync to start of next time window. }} SyncPoint := cnt PUB GetSync return SyncPoint PUB WaitSyncSec(Width) {{Sync to start of next second-based time window. Must call MarkSync before calling WaitSyncSec the first time. PARAMETERS: Width = size of time window in seconds. }} SyncPoint += (clkfreq * Width) #> WMin
Comments
So should I shift right all negative values? Will that correct it or introduce some other error? I will play around with it a bit more, I'm just a bit bugged out on this, no puns intended.
cnt is an unsigned int but the => and <= work on signed numbers. You need to subtract the current time from the start time and then compare that to the timeout time. This subtraction will "convert" your unsigned cnt values to a signed result. You'll need to do something like this to avoid the problem with negative numbers. This still has the 53 second limit that was mentioned earlier. I'm writing this with a 1 year old on my lap (who isn't very happy by the way). It's the right idea but might need some tweaking. The problem is it may not keep you synced. You can change the until line so that it exits the repeat loop once it is within some small amount of time of the timeout value. For example test to see if you are within 10milleseconds of the timeout. If you are DON'T repeat; exit at that point into a waitcnt where you wait for the exact timeout value. If you do this be sure the code you call when you have not timed out executes in less time than your window. In my example it would have to be less than 10 milliseconds, otherwise you could miss your timeout window and end up back in the loop where you don't want to be.
My project link - http://forums.parallax.com/showthread.php?134537-PPDB-Using-the-full-PPDB-Updated-Code-Version-1.4
every 200 msec or every 10 seconds etc. I use this code that is attached to this posting.
The method is called elapsed_time_msec it just needs one long per timer and if timeevent has occured a line of code
CntSnapShot := CntSnapShot + WaitTimeTicks
to "start" timer again
The method takes care of the systemtimer-rollover from max to zero and sign-changing through that
see comment inside method elapsed_time_msec. The waiting-period can go up to 26 seconds.
For longer waitingperiods I would set up a counter variable that is counting seconds.
keep the questions coming
best regards
Stefan
I will check it out later tonight. I'm off to to catch some z's. I'll post updates and mark this thread solved then if I get it working.
Thanks again for your pointers, tips, and samples.
This is exactly what I was trying to do, I will mark this thread as solved! I would like to add credits in the project I use this in for the person who wrote the code, is it yours Stefan?
Anyways, this will help me reduce the led flicker of the display, in my above stated project, by helping me skip the RTC reads wile updating the display. I am sure it will, when I get that far, help me with reading a GPS, connected to a uM-FPU V3.1 over I2C, every few seconds or at the push of a button on the 4x4 Matrix keypad.
This is very helpful to me!
hmmm, Should I revert to unsolved until I test this more thoroughly? Or Should I continue with my own messy code and try shifting right negative values? Or, how, in my code, can I unsign the values, I'll take a look at some more math objects to see if I can find something....
P.S. Why do people say CNT is an unsigned quantity? Clearly when used in in Spin (in comparisons) it can only ever be signed. Perhaps it's just counting in an odd order.
very compact solution.
question: why do you not add examples with concrete numbers to show how it works?
maybe then I would have remembered it from the last time.
It will still work for what I need, If I need to keep track of lets say 1 minute with Stefan's code, I can just add an additional variable to store a count of when I hit the 20 second mark 3 times. Shouldn't that solve the ~53 second hiccup too?
Thank you for pointing out this information, without it I may have not realized it later when I least expect it! Maybe once FirstSpin.tv gets to discussing code timing later in their discussions, they can point out these things to their listeners.
Can someone explain in more of a lengthy detail as to why/how this all happens?
-- http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/prop/col/nvp7.pdf