PythonでSerialからのデータを受信する場合、SerialPortを指定する必要がありますが、Serialが1つのみでボーレートもわかっている場合は
from serial.tools import list_ports
import serial
ports = list_ports.comports()
ser = serial.Serial(ports[0].device,9600,timeout=0.1)
のようにしてポートを開くことができます。
これではあまりにも乱暴だという場合は、シリアルのボーレートと送られてくるデータのフォーマットが既知であれば、利用可能なポート全について流れてくるデータのフォーマットをチェックしてポートを開くことができます。
例えばPCに繋いだArduinoから9600bpsで定期的に
test:data=***
のようなデータが送られてくる場合は
from datetime import datetime as dt
from serial.tools import list_ports
import serial
import re
# ---------------------------
def ReceiveSerial(_ser):
_dataStr = ""
if(_ser!=None):
_data = _ser.readline()
if(len(_data)>0):
try:
tmpDataStr = _data.decode('utf-8') # 'temp,24.5,hum,50.0'
except:
pass
else:
_dataStr = re.sub(r'\r|\n|','',tmpDataStr)
return _dataStr
# ---------------------------
def ScanUsingSerialPortName(_reg="^", _baudrate = 115200):
devName = ""
ckSer = serial.Serial()
ckSer.baudrate = _baudrate
ckSer.timeout = 0.1
ports = list_ports.comports()
print("find " + str(len(ports))+"ports")
if len(ports) > 0:
deviceNames = []
for info in ports:
deviceNames.append(info.device) # ポートの名前を取得
isReady = SerialPortCheck(ckSer,info.device,_reg)
if (isReady):
devName = info.device
break;
return devName
def SerialPortCheck(_serial, _portName, _reg):
ret = False
_serial.port = _portName # ポートを指定
try:
_serial.open()
except:
pass
else:
print("SerialPortCheck " + _serial.port )
startDt = dt.now()
while True:
# 1行読み込む
s = ReceiveSerial(_serial)
if(len(s)>0):
print(">" + s)
matchOB = re.match(_reg,s)
if matchOB:
print("match")
ret = True
break
tickTime = (dt.now() - startDt).seconds
if ((_serial.is_open==False) or (tickTime > 3)):
print("TimeOut" + s)
break
_serial.close()
return ret
# ---------------------------
def SetSerial(_serial, _reg="^", _baudrate=115200):
if((_serial!=None)and(_serial.is_open)):
_serial.close()
tmpSer = None
usingPortName = ScanUsingSerialPortName(_reg,_baudrate)
if(usingPortName!=""):
tmpSer = serial.Serial()
tmpSer.baudrate = _baudrate
tmpSer.timeout = 0.1
tmpSer.port = usingPortName # ポートを指定
try:
tmpSer.open()
except:
tmpSer = None
else:
print("SetSerialOK")
return tmpSer
# ---------------------------
ser =SetSerial(ser,"^"+"test:data=",9600)
のようにすることでポートを特定できます。