Anyone have any ideas for a millisecond timer / counter?
Don M
Posts: 1,652
In a project I'm working on I had been using jm_softrtc.spin to produce a millisecond and seconds number that I use for data logging. It uses it's own cog and does work great.
Unfortunately I want to add new features to my project and I have run out of cogs so I'm looking for areas that I can squeeze together and eliminate a cog launch or 2 if possible.
So I was wondering if there might be another way of keeping track of milliseconds and seconds. All I need to be able to do is reset it to 0 and get milliseconds and seconds.
Unfortunately I want to add new features to my project and I have run out of cogs so I'm looking for areas that I can squeeze together and eliminate a cog launch or 2 if possible.
So I was wondering if there might be another way of keeping track of milliseconds and seconds. All I need to be able to do is reset it to 0 and get milliseconds and seconds.
Comments
I was looking for for .1 sec and 1 sec counts and this worked better then I thought it would.
I've used this method to see if a second has gone by. It wouldn't be hard to modify it to check for a millisecond, if the loop that checks the time takes less than a millisecond to complete.
It's been a while since I've used the above code. I'm not sure it's bug free.
Is there any chance you can free up some cogs by temporarily shutting down their functions, use the freed cogs for other purposes, then revert to their original functions as needed? Just because you launch a cog doesn't mean it's stuck forever doing just that one thing.
Assuming you are checking this at least every 53 seconds (53.6879.. @80MHz) you could just use the 32-bit system counter that is clocked from the system oscillator. Instead of resetting to zero you simply capture the current count and use that. It would be best to update your internal "RTC" at least every 53 seconds but use the CNT for all the fine stuff. BTW, there is always some slack time in any cog that could be used to do this.
Thanks for this suggestion. I had thought of doing that and there is one cog I could shut down to make my new feature work and it does work to do so but if I could somehow eliminate another cog that would be even better.
Expanding on this idea, if you can tolerate binary time-stamps, you can run the CNT plus a SW extension, and if you test the MSB of CNT, and sync that with the LSB of Upper , then you have an aperture effect test, and get a 63 bit counter.
(ie you have traded-off one bit of range, for better checking )
You manage manage the 63 bit, via a simple poll and INC if CNT.31 <> Upper.0, and that needs to be faster than 53/2 - usually do this is the fastest cog loop.
All other cogs can read 63 bits and if they see (CNT.31 <> Upper.0) they read again. (or fix-up locally) as it means the INC loop 'has not quite gotten around to' the inc.
A 63 bit stamp, is unique for the life of the product.
Alternatively, if you are storing logs more frequently than 53/2 seconds, you can simply store the 32 bit CNT as a stamp, and do this upper extension in the reader SW as you scan-in all the data.
That's what I'm doing with my current software. The main downside to this approach is that each datapoint is no longer independent: it depends on what came before, and how many rollovers there have been since the start of logging.
I've never messed with the system counter before but I envision assigning some variable to cnt and at the point in my code where the RTC.RESET is and that becomes my "zero"? and then somehow divide up the cnt timer value to be in milliseconds and seconds and store those values when called in the loop and stored to the buffer. I'm also thinking from some of your comments above that there would be a second variable that would increment every time cnt reaches it's 53'rd second in order to keep on counting up into minutes etc?
I'm gonna need some good advice or examples here....
Andy
Andy I like the simplicity of this. I made this to try and understand it myself. I must be doing something wrong here.
It prints out the time rather quickly. I think there is some scaling off somewhere because what should be 50.xxxx seconds on the terminal only took a blink of the eye to print out.
Here's the screen capture:
This time I have tested it and it works for me. Andy
If your data logging can have pauses of more than a second you can change the code to:
This should work up to ~27 seconds intervalls (then the counter rollover will make problems).
Andy
Let me know if you see something wrong about it.
Thanks a lot for your help!
In the code above if the millis is less than 3 digits this:
just prints leading zeros to pad the number. But what if I want to store it in a buffer- how do I "build" the number with any leading zeros before storing into the buffer?
Great idea SLRM.
Thanks for the feedback.