2016-09-27 25 views
0

私はPythonで複数のシリアルポートから読み取ろうとしています。しかし、thisスレッドとは逆に、ポート数を動的に変更できるようにしたい(コマンドラインオプションで読む)。python複数のシリアルポートを読み取る

私の考えは、ポートをファイル "ports"に入れ、このファイルを読んで、開いているシリアルポートを "ports"の行数に従ってリストに入れました。私の最小限の例:

import numpy as np 
import serial 

p = np.genfromtxt('ports',delimiter=',',dtype=None) 
nser = p.size 

ser = [serial.Serial(port=p[i][0], baudrate=p[i][1]) for i in xrange(nser)] 

(現時点では)次のように見える "ポート":

'/dev/ttyUSB0',4800 

エラー:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IndexError: 0-d arrays can't be indexed 

どうやらファイルが正しく配列に読まれていません、私は既にさまざまな方法と方法を試しています(pythons独自のメソッドやnp.loadtxtを使用しています)。

誰かがa)正しい方法でファイルを読み込み、b)複数のポートの問題を有効な方法で解決する方法がありますか?前もって感謝します。

答えて

2

設定ファイルの形式は非常に簡単で、numpyなしで簡単に解析できます。単純な文字列分割を使用して、各ポート定義をロードすることができます。

serial_ports = [] 
with open('ports') as f: 
    for line in f: 
     port, baud = line.split(',') 
     serial_ports.append(serial.Serial(port, int(baud))) 

それともcsvモジュールを使用することができます:あなたは、シリアルポートの読者はどのように処理するかについて多くの詳細を提供していないので、あなたの質問の2番目の部分はより困難である


import csv 

with open('ports') as f: 
    serial_ports = [serial.Serial(port, int(baud)) for port, baud in csv.reader(f)] 
ポートを介して受信されたデータ。

アプリケーションがI/Oバウンドの場合(ほとんどの場合)、シリアルポートに読み込むデータがあると非同期で確認し、必要に応じて読み込みます。これはselect()モジュールで、またはPython> = 3.4の場合はselectorsモジュールを使って行うことができます。これを行うには複数のプロセスを必要としません。

アプリケーションがCPUバインドの場合は、mutiprocessing.Process()またはsubprocess.Popen()を使用できます。親のシリアルポートを開く代わりに、シリアルポートパラメータを子関数/プロセスへの引数/コマンドライン引数として子に渡し、子プロセスにポートを開いてデータを処理させ、ポートを閉じるようにします。

N.B.テストされていない - これがシリアルポートで動作するかどうかわかりません。親のポートを開く必要がある場合は、サブプロセスのstdinをシリアルポートに接続します。親と子がお互いにブロックされているプロセスをデッドロックするのは簡単だから、これに注意する必要があります。

from subprocess import Popen, PIPE 

s = serial.Serial(port, baud) 
p = Popen(['python', 'port_reader.py'], stdin=s, stdout=PIPE, stderr=PIPE) 
p.communicate() 

multiprocessingを使用する場合は、オープンシリアルポートを引数として子に渡すことができます。これはうまくいくかもしれない...?

from multiprocessing import Process 

def child(port): 
    while True: 
     line = port.readline() 
     if not line: 
      break 
     print('child(): read line: {!r}'.format(line)) 

port = serial.Serial(port, baud) 
p = Process(target=child, args=(port,)) 
p.start() 
p.join() 
1

私はかなり明確にあなたがやろうとしているが、 場合、私のようなファイル持っていたものを理解しませんでした:

'/dev/ttyUSB0',4800 
'/dev/ttyUSB1',4801,'/dev/ttyUSB3',4803 

をし、リストとして進むべき道をそれと店を読みたいと思います

>>> lines 
'/dev/ttyUSB0',4800,'/dev/ttyUSB1',4801,'/dev/ttyUSB3',4803 

、あなたが分割したい場合:

あなたを与えるだろう
with open('ports.txt') as f: 
    lines = f.read().replace('\n', ',') 
print lines 

:可能整数は、あなたができる:今

>>> l1 = [lines.pop(i) for i,j in enumerate(lines) if type(j)==int ] 
>>> l1 
[4800, 4801, 4803] 
>>> lines 
['/dev/ttyUSB0', '/dev/ttyUSB1', '/dev/ttyUSB3'] 

をあなたは「np.loadtxt」は機能しなかったことを言ったので、numpyのアレイにPythonのリストに変換する方法は次のとおりです。

>>> lines = ['/dev/ttyUSB0',4800,'/dev/ttyUSB1',4801,'/dev/ttyUSB3',4803] 
>>> 
>>> import numpy as np 
>>> np.asarray(lines) 
array(['/dev/ttyUSB0', '4800', '/dev/ttyUSB1', '4801', '/dev/ttyUSB3', 
     '4803'], 
     dtype='|S12') 

しかし、再び私はそれがあなたが探しているものならば分かりません。

関連する問題