Python sehr genaue Zeit messen?
Hallo.
Ich möchte, dass mein Programm an diversen Stellen eine gewisse Zeit lang wartet. Und zwar im Mikro-Sekunden-Bereich. Dabei soll die Toleranz sehr gering sein.
Meine Plattform ist ein Raspberry Pi 4B und ein Raspberry Pi Pico (RP2040).
Das Modul "time" ist dabei zu ungenau, oder?
Was sind die Alternativen?
Beste Grüße,
euer EchterNaivling.
2 Antworten
Meine Ansatz wäre vermutlich sowas wie
from datetime import datetime as dt
waittime = 50 #x microseconds
def Micros():
return dt.now().microsecond
release = Micros() + waittime
print(Micros())
while 1:
if Micros()<waittime and release>=1000000:
release-=1000000
if Micros() >= release:
break
print(Micros())
Da ein Funktionsaufruf in Python aber immer seine Zeit dauert und du eine geringe Toleranz haben möchtest, könnte es ggf. besser sein, Micros() durch dt.now().microsecond zu ersetzen und auf die Funktion zu verzichten. Also dann so, wenn auch code-technisch eher unschön
from datetime import datetime as dt
waittime = 50 #x microseconds
release = dt.now().microsecond + waittime
print(dt.now().microsecond)
while 1:
if dt.now().microsecond<waittime and release>=1000000:
release-=1000000
if dt.now().microsecond >= release:
break
print(dt.now().microsecond)
waittime -> Zeit die gewartet werden soll, was sogar noch als Kommentar dahinter steht.
X Microseconds, also die Wartezeit in Mikrosekunden. Eine Microsekunde ist 1/1.000.000 Sekunde. 50 Microsekunden entsprechen also z. B. 0,05 Millisekunden.
Ich persönliche würde den Code in einer Methode hinterlegen, also zum Beispiel so:
from datetime import datetime as dt
def WaitForX(t): #t microseconds
release = dt.now().microsecond + t
#Handle when we hit a new second
if release >= 1000000:
release -= 1000000
while dt.now().microsecond > t:
continue
while 1:
if dt.now().microsecond >= release:
break
WaitForX(250)
Der Funktionsaufruf WaitForX(250) würde also dafür sorgen, dass das Programm an der Stelle rund 0,00025 Sekunden wartet (250 / 1.000.000 von einer Sekunde).
Hier ein kleiner Testlauf um zu zeigen, wie relativ nah die Funktion drankommt:
from datetime import datetime as dt
def WaitForX(t): #t microseconds
release = dt.now().microsecond + t
#Handle when we hit a new second
if release >= 1000000:
release -= 1000000
while dt.now().microsecond > t:
continue
while 1:
if dt.now().microsecond >= release:
break
n = 5000
timecount = 0
for i in range(n):
start = dt.now().microsecond
WaitForX(250)
end = dt.now().microsecond
if end < start:
timecount += (1000000 - start + end)
else:
timecount += end-start
print("Average waittime out of " + str(n) + " setups was " + str(timecount/n) + " microseconds.")
Allerdings finde ich
time.sleep(seconds/1000000.0)
jetzt auch nicht so super ungenau. Musst du selbst entscheiden, welches dir angenehmer erscheint.
Vielen Dank.
Du hast dir den Stern mehr als verdient.
Bevor Du weitermachst, lies bitte erstmal die Manpage zu time:
man 7 time
Und schau Dir mal /proc/timer_list an, ob Du etwas mit ausreichend kleiner Granularität zur Verfügung hast.
Was macht dieser Code jetzt?
Wofür brauche ich "waittime"?