5

whileループでシリアルデータを読み取っています。ただし、サンプルレートを制御することはできません。

コード自体の実行には0.2秒かかるようですので、それより速く実行することはできません。しかし、私はサンプリングがどれだけ遅いかを正確に制御できるようにしたいと思います。

'sleep'を使用してそれを行うことができるように感じますが、問題は、さまざまなポイントでループ自体の読み取りに時間がかかる可能性があることです(シリアルデータを介して送信されているものによって異なります)。バランスをとるために。

たとえば、1秒ごとにサンプリングしたいとします。ループの実行には、0.2秒から0.3秒かかります。私のコードは、0.8秒(ループが0.2秒かかる場合)または0.7秒(ループが0.3秒かかる場合)スリープするのに十分スマートである必要があります。

import serial
import csv
import time

#open serial stream
    while True:

        #read and print a line
        sample_value=ser.readline()
        sample_time=time.time()-zero
        sample_line=str(sample_time)+','+str(sample_value)
        outfile.write(sample_line)
        print 'time: ',sample_time,', value: ',sample_value
4

3 に答える 3

11

コードを実行してループのすべての反復にかかる時間を測定するだけで、次のようになりますsleep

import time

while True:
    now = time.time()            # get the time
    do_something()               # do your stuff
    elapsed = time.time() - now  # how long was it running?
    time.sleep(1.-elapsed)       # sleep accordingly so the full iteration takes 1 second

もちろん、100% 完璧というわけではありません (時々 1 ミリ秒または別のミリ秒ずれることもあります) が、それで十分だと思います。


もう 1 つの優れたアプローチは、 twisted を使用することですLoopingCall

from twisted.internet import task
from twisted.internet import reactor

def do_something():
    pass # do your work here

task.LoopingCall(do_something).start(1.0)
reactor.run()
于 2012-11-02T15:06:25.530 に答える
2

かなり洗練された方法は、UNIX で作業している場合です。シグナル ライブラリを使用します。

コード :

import signal


def _handle_timeout():
    print "timeout hit" # Do nothing here

def second(count):
    signal.signal(signal.SIGALRM, _handle_timeout)
    signal.alarm(1)
    try:
        count += 1 # put your function here
        signal.pause()

    finally:
        signal.alarm(0)
        return count


if __name__ == '__main__':

    count = 0
    count = second(count)
    count = second(count)
    count = second(count)
    count = second(count)
    count = second(count)

    print count

そしてタイミング:

 georgesl@cleese:~/Bureau$ time python timer.py
 5

 real   0m5.081s
 user   0m0.068s
 sys    0m0.004s

ただし、2 つの注意点があります。* nix でのみ動作し、マルチスレッドセーフではありません。

于 2012-11-02T16:35:50.023 に答える
0

ループの開始時に、適切な時間が経過したかどうかを確認します。そうでない場合は、sleep.

# Set up initial conditions for sample_time outside the loop
sample_period = ???
next_min_time = 0
while True:
    sample_time = time.time() - zero
    if sample_time < next_min_time:
        time.sleep(next_min_time - sample_time)
        continue
    # read and print a line
    sample_value = ser.readline()
    sample_line = str(sample_time)+','+str(sample_value)
    outfile.write(sample_line)
    print 'time: {}, value: {}'.format(sample_time, sample_value)
    next_min_time = sample_time + sample_period
于 2012-11-02T15:01:26.980 に答える