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:
# 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()