2017-10-16 16 views
0

私は3つのシリアルポートから同時にpyserialを使用してデータを読み取り、このデータをpythonで3つのタイムスタンプ付きテキストファイルに記録しています。ただし、しばらくしてから(約5分以内)、テキストファイルに書き込まれたデータは正しく印刷されません。正確なデータのpythonを使用した3つのシリアルポートからの一貫性のないデータロギング。

例:

2017年10月16日10時41分27秒

センサー読み取り平均読み取り/平均TOPLEFT:1
7.00 0.14 midLeft:2 8.00 0.25 botLeft。 3 9.00 0.33 topRight:4 10.00
0.40 midRight:5 11.00 0.45 botRight:不正確なデータの6 12.00 0.50

例:

2017年10月16日十時55分11秒

センサReadin 3グラム読み出し/平均TOPLEFT:1
7.00 0.14 midLeft:2 8.00 0.25 botLeft:3 9.00 00.50 HT:4 10.00 0.40 midRight:5 11.00
0.45 botRight:6 12.00 0.50 0.45 botRight:

:6 12.00 0.50

ここでは、私が使用しているコードです。

# to use microseconds, delete ".replace(microsecond = 0)" 

## includes 
from __future__ import print_function 
import threading, serial, time, io, datetime 
from serial import Serial 

device1 = "_base_station" ## device name used for filename 
addr1 = "COM39" ## edit serial port here 

device2 = "_collector" ## device name used for filename 
addr2 = "COM40" ## edit serial port here 

device3 = "_receiver" ## device name used for filename 
addr3 = "COM42" ## edit serial port here 

baud = 57600 ## edit baud rate here 

## function for initializing serial ports 
def init_port(addr, baud): 
    return serial.Serial(
     port = addr,\ 
     baudrate = baud,\ 
     parity=serial.PARITY_NONE,\ 
     stopbits=serial.STOPBITS_ONE,\ 
     bytesize=serial.EIGHTBITS,\ 
     timeout=.01) 

## initialize serial ports 
ser1 = init_port(addr1, baud) 
ser2 = init_port(addr2, baud) 
ser3 = init_port(addr3, baud) 

## print port numbers so the user knows the script is working 
print("Collecting data from port: " + ser1.portstr + "\r\n") ## give status update 
print("Collecting data from port: " + ser2.portstr + "\r\n") ## give status update 
print("Collecting data from port: " + ser3.portstr + "\r\n") ## give status update 

def handle_data(ser, device): 
    while True: 
     line = ser.readline() ## get line from serial port 
     filename = datetime.datetime.now().strftime("%Y-%m-%d-%H") + device + ".txt" ## create filename based on device and time. updates at midnight. 
     filehandle = open(filename, 'a') ## append data to file. 

     if str(line) == "#\r\n": ## logging delimiter 
      filehandle.write("\r\n" + str(datetime.datetime.now().replace(microsecond = 0)) + "\r\n") ## start each data entry with a timestamp 
     else: 
      filehandle.write(str(line)[:-1]) ## log line (strip off extra line, data is already being parsed by line) 
      filehandle.flush() 

     filehandle.close() ## close file 
    ser.close() ## close serial port 

## create threads 
thread1 = threading.Thread(target = handle_data, args = [ser1, device1]) 
thread2 = threading.Thread(target = handle_data, args = [ser2, device2]) 
thread3 = threading.Thread(target = handle_data, args = [ser3, device3]) 

## start threads 
thread1.start() 
thread2.start() 
thread3.start() 

スレッドを使わずに複数のスクリプトを試してみましたが、同じ問題が引き続き発生します。

これはなぜ起こっているのですか?どんな解決策ですか?

ありがとうございます。

+0

マルチスレッドを使用するか、それはイディオムを使用することは非常に良い考えですマルチプロセッシング: '場合__name__ ==「__main __」:' – Aaron

+0

あなたは、同時に任意の同期せずに、同じファイルへの書き込みをしているように見えます。しかし、このために複数のプロセスやスレッドを起動することは過度のようです。このようなことができます。https://stackoverflow.com/questions/16255807/pyserial-is-there-a-way-to-select-on-multiple-ポートアットワンス – pvg

+0

ありがとうpvg。これは、同じファイルへの書き込みのようですが、デバイス名がスレッド引数からファイル名に渡されています。確かめます。 また、Aaronに感謝します。私はPythonにはまったく新しいものなので、すべての助けを歓迎します。 –

答えて

0

タイムアウトが疑わしく速く見えますが、私はシリアルポートでタイムアウトを延長します。私はあなたが得ている断片化されたデータがタイムアウトが入ってくるデータを打ち負かすときからであると思う。あなたは.readlineを()を使用している

def init_port(addr, baud): 
    return serial.Serial(
     port = addr,\ 
     baudrate = baud,\ 
     parity=serial.PARITY_NONE,\ 
     stopbits=serial.STOPBITS_ONE,\ 
     bytesize=serial.EIGHTBITS,\ 
     timeout=1.0) 

、それは「\ n」の終了を探してされますが、タイムアウトを超過した場合には早期に終了します。

関連する問題