2

私は現在、センサーからデータを取得するために 10ms ごとに関数を呼び出そうとしています。

基本的に、gpio 割り込みからコールバックをトリガーしていましたが、センサーを変更しましたが、現在使用しているセンサーには、コールバックを駆動するための INT ピンがありません。

したがって、私の目標は、同じ動作をすることですが、タイマーによって内部割り込みが生成されることです。

このトピックからこれを試しました

import threading

def work (): 
  threading.Timer(0.25, work).start ()
  print(time.time())
  print "stackoverflow"

work ()

しかし、実行すると、タイマーが実際には正確ではなく、時間の経過とともに派生していることがわかります。

1494418413.1584847
stackoverflow
1494418413.1686869
stackoverflow
1494418413.1788757
stackoverflow
1494418413.1890721
stackoverflow
1494418413.1992736
stackoverflow
1494418413.2094712
stackoverflow
1494418413.2196639
stackoverflow
1494418413.2298684
stackoverflow
1494418413.2400634
stackoverflow
1494418413.2502584
stackoverflow
1494418413.2604961
stackoverflow
1494418413.270702
stackoverflow
1494418413.2808678
stackoverflow
1494418413.2910736
stackoverflow
1494418413.301277
stackoverflow

そのため、タイマーは 10 ミリ秒ごとに 0.2 ミリ秒ずつ派生しており、数秒後にはかなり大きなバイアスになります。

Python は実際には「リアルタイム」向けに作られていないことは知っていますが、それを行う方法があるはずだと思います。

誰かがすでに Python で時間の制約を処理しなければならない場合は、アドバイスをいただければ幸いです。

ありがとう。

4

2 に答える 2

2

このコードは私のラップトップで動作します - 目標時間と実際の時間の間の差分をログに記録します - 主なことは、work() 関数で行われることを最小限にすることです。

重要なことは、その呼び出しが行われた時間とターゲットの時間の差に基づいて、次のタイマーを開始することです。

間隔を 0.1 秒に遅くしたので、私の Win7 x64 では 10 ミリ秒を超える可能性があるジッターが見やすくなり、Timer() 呼び出しに負の値を渡すと問題が発生します:-o

これにより、100 個のサンプルがログに記録され、それらが出力されます。.csv ファイルにリダイレクトすると、Excel に読み込んでグラフを表示できます。

from multiprocessing import Queue
import threading
import time

# this accumulates record of the difference between the target and actual times
actualdeltas = []

INTERVAL = 0.1

def work(queue, target):
    # first thing to do is record the jitter - the difference between target and actual time
    actualdeltas.append(time.clock()-target+INTERVAL)
#    t0 = time.clock()
#    print("Current time\t" + str(time.clock()))
#    print("Target\t" + str(target))
#    print("Delay\t" + str(target - time.clock()))
#    print()
#    t0 = time.clock()
    if len(actualdeltas) > 100:
        # print the accumulated deltas then exit
        for d in actualdeltas:
            print d
        return
    threading.Timer(target - time.clock(), work, [queue, target+INTERVAL]).start()

myQueue = Queue()

target = time.clock() + INTERVAL
work(myQueue, target)

典型的な出力 (つまり、Python で Windows のミリ秒のタイミングに依存しないでください):

0.00947008617187
0.0029628920052
0.0121824719378
0.00582923077099
0.00131316206917
0.0105631524709
0.00437298744466
-0.000251418553351
0.00897956530515
0.0028528821332
0.0118192949105
0.00546301269675
0.0145723546788
0.00910063698529
于 2017-05-12T10:02:41.710 に答える