time measurements
-
I'm working on some macros where I want to measure time to less than 1 second resolution. I created this command to get me to msec resolution. It may be of use to others.
mod(mod({+state.time},10000),10000) + state.msUpTime/1000
It takes the time in seconds since the datum, strips off all but the last 4 digits and adds the ms portion of uptime to it. Note that the msec portion is not synched to universal time, but synched to the last board boot. Still very good for measuring and accurate duration up to 9999seconds (2.77 hours)
Someone may have a cleaner way to do it than doing mod twice, but it gets the job done.
-
@mikeabuilder said in time measurements:
mod(mod({+state.time},10000),10000) + state.msUpTime/1000
Why the nested 'mod'? This appears to work just as well for me:
mod(+state.time,10000) + state.msUpTime/1000
I think you may have some problems with this, because msUpTime may not roll over at the same time as state.time. I suggest this:
mod(state.upTime,10000) + state.msUpTime/1000
RRF guarantees that if you read state.upTime and state.msUpTime in the same expression, the rollover is synchronised.
-
Thanks @dc42 - You are correct as usual. I should have dome more experiments before wasting your time. And if I had read your post before reconnecting to my duet3 for more experiments, I would not have proved this to myself.
Now I better carefully read your response on my print head dynamics question before I replay there...
-
@dc42 - I guess I'm not quite done here - my lack of in-depth programming experience.
If I'm timing an event, I need to calculate the elapsed time by capturing both the start and end time, then subtract start from end. If I use
mod(state.upTime,10000) + state.msUpTime/1000
The mod function can mess me up if my start time is before a 10000 threshold and my end time is after. So when I calculate my elapsed time, if the result is negative, I need to add 10000 to get the correct result (or I've stumbled onto a time machine).
And if the event I'm timing might exceed 9999sec (2.78 hours), I should give up a digit of ms precision and change to
mod(state.upTime,100000) + state.msUpTime/1000
Happily, I'm not timing long events.
-
@mikeabuilder said in time measurements:
mod(state.upTime,10000) + state.msUpTime/1000
What's the mod for?
This seems to get me what you're looking for:
echo {state.upTime + state.msUpTime/1000}
I think that was a leftover from you using state.time which is the UNIX Epoch time which is a large number.
state.upTime is the number of seconds since boot which is great for what you're doing.
-
@alankilian - I still need the mod to get three places of precision after the decimal point. If the uptime is longer than 9999 seconds, I get one more digit to the left of the decimal and one fewer to the right. Unless the format of an echoed float is restricted to 8 characters, then maybe the value is correct in memory and I'm making unnecessary work because of the output format. It would be good to know.
-
Oh I see.
Maybe do everything in milliseconds then?
echo {state.upTime*1000 + state.msUpTime}
-
@alankilian said in time measurements:
Oh I see.
Maybe do everything in milliseconds then?
echo {state.upTime*1000 + state.msUpTime}
Yes, that will work better, until state.upTime * 1000 exceeds 2^31. This is about 2^21 seconds, which is about 2 million seconds, which is about 24 days.
If the machine might have been left turned on for more than 24 days when you do the timing, but the time you need to measure is a lot less than 24 days, then you still have some possibilities. For example:
var startTime = mod(state.upTime, 1000000) * 1000 + state.msUpTime G4 P4321 ; replace this by what you want to time var endTime = mod(state.upTime, 1000000) * 1000 + state.msUpTime; var elapsedTime = var.endTime - var.startTime if var.elapsedTime < 0 set var.elapsedTime = var.elapsedTime + 1000000 * 1000