2

PySerial を集積回路基板 (ICB) と組み合わせて使用​​し、いくつかの赤外線 (IR) エミッター/センサー ユニットの状態を継続的に監視しています (つまり、IR ビームが壊れているかクリアしているかを確認します)。約1日後にコンピュータのメモリ。これは PySerial と関係があると思われますが、確かではありません。

プロジェクトの背景: 1、2、および 3 とラベル付けされた 3 つの IR エミッター/センサー ユニットがあります。どのビームも壊れていない場合、ICB はシリアル接続を介して文字列「0」を出力します。ユニット 1 のビームが壊れている場合は、文字列 '1' が出力され、ユニット 2 の場合は '2' というように出力されます。任意の時点で 1 つのビームのみを遮断できると想定しても問題ありません。1/10 秒ごとに 1 つの文字列値 (0、1、2、または 3) を出力するように ICB をプログラムしました。

次のコードを使用して、PySerial を使用して ICB 出力を読み取り、PyGame を使用して各ビームが遮断された時間を最大時間 (すべて Python 2.7 で) 記録します。

import pygame, serial

def breakLoop(cumulative_break_time, max_cumulative_break_time, ser, is_beam_broken_org):
    elapsed_break_time = 0.
    clock.tick() #Start clock.
    while (cumulative_break_time + elapsed_break_time < max_cumulative_break_time):
        ser.flushInput()
        is_beam_broken = int(ser.read(1))
        if is_beam_broken == is_beam_broken_org:
            elapsed_break_time += clock.tick()/1000.
        else:
            break
    cumulative_break_time += elapsed_break_time
    return cumulative_break_time, elapsed_break_time

#Initialize objects and constants
ser = serial.Serial()
ser.baudrate = 115200
ser.port = 'COM3'
ser.open()
clock = pygame.time.Clock()
max_cumulative_break_time = 900. 
cumulative_break_time = 0.
out_file = open('test.csv','w')

while cumulative_break_time < max_cumulative_break_time: #Enter main event loop.
    ser.flushInput()
    is_beam_broken = int(ser.read(1))
    if is_beam_broken:
        print 'Beam %s broken.' % is_beam_broken
        cumulative_break_time, elapsed_break_time = breakLoop(cumulative_break_time, max_cumulative_break_time, ser, is_beam_broken)
        print 'Beam %s un-broken.' % is_beam_broken
        print 'Elapsed break time was: ', elapsed_break_time, ' s'
        print 'Cumulative break time is now: ', cumulative_break_time, ' s'
        print''
        out_file.write(','.join([str(is_beam_broken),str(elapsed_break_time)]) + '\n')
        out_file.flush()
out_file.close()
ser.close()
print '\n\nDone! Press any key to quit.'
raw_input('')

これで、コードは正常に機能しますが、これを 1 日ほど実行すると、「メモリ不足」エラーが発生します。私は継続的に ICB から入力を読み取っているため、これは PySerial と関係があると推測しています...おそらく、常にシリアル バッファをフラッシュしているためでしょうか? メモリの内容をフラッシュすると、同じメモリが使用できなくなるとは思いませんでした...

また、PySerial のドキュメントを読んで、次の行に出くわしました。

まだ実装されていません/実装に問題がある可能性があります: クライアントとサーバー間の RFC 2217 フロー制御 (オブジェクトの内部バッファーは、読み取られない場合にすべてのメモリを消費する可能性があります)。

RFC 2217 が何であるかはわかりませんが、何らかの形でメモリ リークが発生していることはわかっています。

ご意見をお寄せいただければ幸いです。私は正しい軌道に乗っていますか?または、スクリプトの過剰なメモリ使用量の原因が他にある可能性はありますか?

もちろん、私を助けるのに役立つ場合は、詳細をさらに説明させていただきます:)

4

0 に答える 0