0

I have a python code that runs when the Raspberry Pi boots up using crontab. It is something like this:

import time
while True: 
   # beginning of the loop
   loop_start_time = time.time()
   # to print the time in the shown format
   print time.strftime("%Y-%m-%d %H:%M:%S")
   # do a few things that may take some time, but not more than 10 seconds

   # control the delay
   if time.time()>10: pass
   else: time.sleep(10 - (time.time() - loop_start_time))

If I run the same code on PC, it will give me the exact timing and a perfect increment of 10 seconds for every loop : e.g I will get 10:24:04 when I start the program. If I come back next day at exactly the same time it will still give me the same without changing to 10:24:05 for example.

However, when I implemented this on Raspberry Pi, I found that the seconds increment every around 20 mins, e.g 10:24:04 -> 10:44:05. How should I deal with this? What is the reason and how do I eliminate this problem? I want it to be show perfect timing.

  • 2
    How many cores at what frequency does your PC have? And which model of pi is this? How many times have you repeated both experiments? Have you looked at the fraction from time.time() when you do this? What do you think might happen if it is .994? Why don't you use the return value of the first time.time() call in the .strftime() call? Those are now two different times, and may easily be 1-10 milliseconds different; at least one system call is required under the hood. – goldilocks Aug 10 '15 at 12:24
2

I'm not sure about your application (due to lack of details), but in the Unix StackExchange there is this answer that talks about a solution using Perl. You might try this as a test.

(In)famously, the Raspberry Pi does not provide a real-time clock. Several third-party solutions are available, which is left as an exercise.

Assuming your Pi is hooked up to a network, you might try using NTP to check every 10 minutes to see how far your Pi's clock has drifted from their time servers. If there is a big drift in such a short period of time, that might point to a hardware problem on the Pi.

If the clock is running fine, you may look at having your program only run for a one minute interval (i.e. six cycles) and then expect to shut itself down. Then, in your crontab, you can launch the same program again once every minute. However, cron is not guaranteed to run at the minute boundary. It may (due to kernel scheduling) run a second or more later.

In short, you're asking a non real-time operating system to behave like a real-time operating system. So, there are tradeoffs.

Even so, there are plenty of options here, limited only by your imagination as to how to solve it. I'm sure there are umpteen other ways to make this more time accurate, but you have to first figure out if it's the Pi or the software.

  • In short, you're asking a non real-time operating system to behave like a real-time operating system. So, there are tradeoffs. – Ahmed Al-haddad Aug 11 '15 at 9:20
  • I had to add more to the code to make it perfectly stable. Now it is been running for a day with the same initial second :). – Ahmed Al-haddad Aug 12 '15 at 8:40
2

The script as written will accumulate errors.

You also haven't said whether wall time or real time is important.

The following script will not accumulate errors.

#!/usr/bin/env python

# timed loop

import time

PERIOD=1.0

next = time.time() + PERIOD

while True:

   print("{:.2f}".format(time.time()))

   # do some work

   delay = -1.0
   missed = 0

   while delay < 0.0:

      delay = next - time.time()

      next += PERIOD

      missed += 1

   if missed > 1:
      print("missed {} appointments.".format(missed - 1))

   time.sleep(delay)
  • You did the footwork I wasn't willing to go do with his code. Good on you :) – WineSoaked Aug 11 '15 at 0:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.