2

time.time() :

Return the time in seconds since the epoch as a floating point number. Note that even though the time is always returned as a floating point number, not all systems provide time with a better precision than 1 second. While this function normally returns non-decreasing values, it can return a lower value than a previous call if the system clock has been set back between the two calls.

I want to ask about the function of time.time() when used on Raspberry Pi. I am working on a code where I have to organize a system with a perfect timing [ e.g, do something exactly every 5 seconds, not a second more or less! For ever!]. However, I noticed that the second increments when the decimal value of time.time() is somewhere between .95-.05, instead of incrementing when the decimal value is .00

Example: if the time 1439286302.64, then according to the decimal values, it will increment by 1 second when it reaches ~1439286302.9x. Does anyone know what's the exact boundary at which it will increment by 1 second? Because I have been testing and this seems to be random, and I couldn't find an answer online.

I appreciate all help.

Maciej Lach
  • 1,622
  • 3
  • 20
  • 27
Ahmed Al-haddad
  • 805
  • 2
  • 16
  • 41
  • 4
    I'd say that if you have a *hard realtime* requirement, you might be using the wrong platform and environment. – deceze Aug 18 '15 at 09:29
  • try using `time.clock`, it can be better – Assem Aug 18 '15 at 09:32
  • At the moment I have deployed my code on two Raspberry Pies both connected to the same server. One of them has been exactly what I want for 5 days now. The other snapped and was incremented by 1 second After 4 days. Tbh I am really pissed why the other snapped, and it makes me think it is the randomness of the boundary. Any idea, sir @deceze? – Ahmed Al-haddad Aug 18 '15 at 09:33
  • 1
    The raspberry pi is NOT a realtime system. If you wanted this sort of thing, you might want to try a realtime platform. Even then, your still limited by the hardware side of things – muddyfish Aug 18 '15 at 09:41
  • Awesome suggestion, sir @bigOTHER. But I need to stamp the real (current) time with the server. While time.clock() depends on the processor time and when the function was called. Can I extract the current time from time.clock()? – Ahmed Al-haddad Aug 18 '15 at 09:42
  • 1
    As far as I am aware raspberry pi does not have realtime clock. If you are not switching it off i should not make a difference. Are delays in code around your calling the function not causing the delay post more complete code pls. – Joop Aug 18 '15 at 09:43
  • 1
    also Raspberry pi gets its time update from NTP server. if updates happen frequently it might cause some jitter in your times. http://raspberrypi.stackexchange.com/questions/4370/where-does-the-raspberry-pi-get-the-time-from – Joop Aug 18 '15 at 09:46
  • 1
    sorry for repeated comments. updates from ntp server can casue the jitter that you are observing: http://www.ntp.org/ntpfaq/NTP-s-algo.htm#Q-ACCURATE-CLOCK – Joop Aug 18 '15 at 09:48
  • @Joop I will check the links you shared shortly. As of the delays within each loop, I took precautions so that they are all compensated for. Meaning that the time for each loop should never be more or less than 5 seconds, theoretically. However, I have found that each loop takes something around 5.009 instead of exactly 5.000 seconds, which is why the increment happens, which is why I am doing all this :/ – Ahmed Al-haddad Aug 18 '15 at 10:03
  • maybe you should change your code to check if interval from start time is less than t n*5 from start time. in that way any delays in loops will be compensated for and you will stay globally stay inside the 5 second budget without jitter in each iteration accumulating. Sorry for awkward wording. E.g. keep record of next int for time.time() that would necesitate action and check against that to trigger – Joop Aug 18 '15 at 10:15
  • @Joop Oh, now I get it. This could be a valid reason. Hmm, so how do I limit these updates? Or How do I stop them completely after only one update and leave it to the processor to update itself? – Ahmed Al-haddad Aug 18 '15 at 10:16
  • A multi-process system like a common CPU running a Linux distribution can make absolutely no guarantees about timing. "Every 5 seconds" will only ever be *approximately* every 5 seconds. What exactly are you doing here that requires such precise timing? – deceze Aug 18 '15 at 10:17
  • I am collecting data every _x_ seconds in order to examine them. To examine them however, I need exact timing between them (approximately exact, it is acceptable as long as it is in milliseconds!) Atm after 5 days of running non-stop, an error of 1/(345600) seconds came up and 1 second was incremented. Although theoretically it is not supposed to come up. So I am just trying to eliminate the error, sir @deceze – Ahmed Al-haddad Aug 18 '15 at 10:25
  • could you provide [mcve]? Something like [`while True: do_something_that_takes_less_than_5_seconds(); time.sleep(5 - time.time() % 5)` should be enough in your case](http://stackoverflow.com/a/26609843/4279). – jfs Aug 19 '15 at 06:07
  • I have been running tests on my code after minor fixes and it looks promising. It seems to be some NTP and hardware random delays. Thanks a lot for help. @J.F.Sebastian – Ahmed Al-haddad Aug 20 '15 at 07:21

1 Answers1

1

Some Pseudo Code that should at least keep you at average every 5 seconds and not compound jitter

time_started = time.time()
next_action_time = int(time_started) + 5
while True:
    if next_action_time < time.time():
        do_action!!!!!
        next_action_time += 5
    else:
        waste_some_time()

make sure that your other processes fit in your time budget. Can also have your so_actions sampling record the actual time that measurement was done. In that way you can confirm that jitter is in check.

Joop
  • 7,840
  • 9
  • 43
  • 58
  • Hm, I understand what you mean, but how is that related to jitter? Is jitter caused whenever I use time.time()? – Ahmed Al-haddad Aug 18 '15 at 10:27
  • jitter could be caused by time taken by your code to reach the point of execution. Could also be caused by Pi updating its clock from NTP server (I dont know exact nature of that). code above should hower try and do the sample at 5 second intervals. might be milli seconds late with varying delays, but delays will at least not compound – Joop Aug 18 '15 at 10:30
  • Hmm, you are very smart, sir @Joop. I am still thinking about your answer, but before implementing this I will need to test it for maybe a week first. Will this timing mechanism increment the time after for example 10k of loops based on your experience or caused any kind of errors?! – Ahmed Al-haddad Aug 18 '15 at 10:43
  • time.time() Return the current time in seconds since the Epoch. not sure when its float will go out of range, but I am sure that it should last a long time. there is post addressing this. http://stackoverflow.com/questions/15733544/time-time-overflow-rollover I hope my code does not last that long! – Joop Aug 18 '15 at 12:11
  • Haha, it would be good if your code lasts that many years! I have read in the NTP page and I quote, "The typical accuracy on the Internet ranges from about 5ms to 100ms, possibly varying with network delays. A recent survey[2] suggests that 90% of the NTP servers have network delays below 100ms" Which is very acceptable to my kind of code. So does mean that it might have snapped by itself randomly? Still wondering. – Ahmed Al-haddad Aug 18 '15 at 12:48
  • 1
    Without digging into details i would suspect that the pi has some update mechanism that automatically get new time updates from NTP server. If that happens frequently it could quite possibly be the cause of the behaviour that you saw. – Joop Aug 18 '15 at 14:02
  • I have been running tests on my code after minor fixes and it looks promising. It might be due to NTP and hardware random delays as you suggested before. Thanks a lot for help. @Joop – Ahmed Al-haddad Aug 20 '15 at 07:19