OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Repeat python function with precise time stamp

  • Thread starter Thread starter Arsen Norman
  • Start date Start date
A

Arsen Norman

Guest
I have a task to communicate with a hardware with reasonably high precision (1pps) to simulate telemetry data collection. Based on StackOverflow and other sources I was able to come up with the following code. The code works good enough, however it has a runoff with about 1 msec. I.E., the beginning every execution is late by about 1 millisecond. If left running overnight, the runoff increases to several dozen millisec. The real hardware host has a GPS source for 1pps, but I need to test my hardware with simulation from the PC. The printout chart is the best way to understand the problem. The plotting is optional, but it shows the problem visually.

Questions: What is the source of the constant delay? Is there a way to force synchronize Time to NTP? Is there a way to access the System clock instead of Python Time? All good critique is welcome!

Here is the code:

Code:
# 1pps Project
# IVR Labs, Inc.
#____V0.54_______
import threading
from datetime import *
import time
from tkinter import *

global last_time
Xpos = 10
Xposl = 10
Yposl = 255


class Timer(threading.Thread):
    def __init__(self):
        self._timer_runs = threading.Event()
        self._timer_runs.set()
        super().__init__()

    def run(self):
        while self._timer_runs.is_set():
            self.my_timer()
            time.sleep(_1PPS.interval)

    def stop(self):
        self._timer_runs.clear()

    def my_timer(self):
        pass


class _1PPS(Timer):
    interval = 1   # Interval in seconds.

    # Function to be executed.
    def my_timer(self):
        global last_time
        global Xpos, Xposl, Yposl
        timestamp = datetime.now(timezone.utc)  # - timestamp
        usec = timestamp.microsecond
        time_delta = usec-last_time.microsecond
        # plotvalue = datetime.now(timezone.utc).microsecond - timestamp.microsecond
        print(timestamp, (timestamp-last_time), time_delta)
        last_time = timestamp
        if Xpos >= 1280:
            Xpos = 10
        else:
            Xpos = Xpos + 1
        Ypos = time_delta/10
        if Ypos > 480:
            Ypos = 255
        plot.create_rectangle(Xpos, 11, Xpos+2, 489, width=0, fill='white smoke')
        plot.create_line(Xposl, Yposl, Xpos, Ypos, fill='red')
        Xposl = Xpos
        Yposl = Ypos


win = Tk()
win.geometry('1280x520')
plot = Canvas(win, width=1280, height=500)
plot.grid(column=0, row=1, sticky="ne")
plot.create_line(9, 9, 9, 1270, fill='blue')
plot.create_line(0, 490, 1270, 490, fill='blue')

_1PPS = _1PPS()
last_time = datetime.now(timezone.utc)
_1PPS.start()

win.mainloop()

_1PPS.stop()

Time delay plot
<p>I have a task to communicate with a hardware with reasonably high precision (1pps) to simulate telemetry data collection. Based on <a href="https://stackoverflow.com/questions/3393612/run-certain-code-every-n-seconds">StackOverflow</a> and <a href="https://pythonassets.com/posts/executing-code-every-certain-time/" rel="nofollow noreferrer">other sources</a> I was able to come up with the following code.
The code works good enough, however it has a runoff with about 1 msec. I.E., the beginning every execution is late by about 1 millisecond. If left running overnight, the runoff increases to several dozen millisec. The real hardware host has a GPS source for 1pps, but I need to test my hardware with simulation from the PC.
The printout chart is the best way to understand the problem.
The plotting is optional, but it shows the problem visually.</p>
<p>Questions:
What is the source of the constant delay?
Is there a way to force synchronize Time to NTP?
Is there a way to access the System clock instead of Python Time?
All good critique is welcome!</p>
<p>Here is the code:</p>
<pre><code># 1pps Project
# IVR Labs, Inc.
#____V0.54_______
import threading
from datetime import *
import time
from tkinter import *

global last_time
Xpos = 10
Xposl = 10
Yposl = 255


class Timer(threading.Thread):
def __init__(self):
self._timer_runs = threading.Event()
self._timer_runs.set()
super().__init__()

def run(self):
while self._timer_runs.is_set():
self.my_timer()
time.sleep(_1PPS.interval)

def stop(self):
self._timer_runs.clear()

def my_timer(self):
pass


class _1PPS(Timer):
interval = 1 # Interval in seconds.

# Function to be executed.
def my_timer(self):
global last_time
global Xpos, Xposl, Yposl
timestamp = datetime.now(timezone.utc) # - timestamp
usec = timestamp.microsecond
time_delta = usec-last_time.microsecond
# plotvalue = datetime.now(timezone.utc).microsecond - timestamp.microsecond
print(timestamp, (timestamp-last_time), time_delta)
last_time = timestamp
if Xpos >= 1280:
Xpos = 10
else:
Xpos = Xpos + 1
Ypos = time_delta/10
if Ypos > 480:
Ypos = 255
plot.create_rectangle(Xpos, 11, Xpos+2, 489, width=0, fill='white smoke')
plot.create_line(Xposl, Yposl, Xpos, Ypos, fill='red')
Xposl = Xpos
Yposl = Ypos


win = Tk()
win.geometry('1280x520')
plot = Canvas(win, width=1280, height=500)
plot.grid(column=0, row=1, sticky="ne")
plot.create_line(9, 9, 9, 1270, fill='blue')
plot.create_line(0, 490, 1270, 490, fill='blue')

_1PPS = _1PPS()
last_time = datetime.now(timezone.utc)
_1PPS.start()

win.mainloop()

_1PPS.stop()

</code></pre>
<p><a href="https://i.sstatic.net/4h9ja63L.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/4h9ja63L.png" alt="Time delay plot" /></a></p>
 

Latest posts

J
Replies
0
Views
1
jbowerbir
J
Top