PySerialを使用してコマンドをEddieに送信しています。 readlineで改行を指定する必要がありますが、pySerial 2.6はそれを取り除きました...回避策はありますか?
こちらが Eddieコマンドセット で、このPDFの2ページ目と3ページ目に記載されています。 PDFにアクセスできない場合の 代替画像 を以下に示します。
Input: <cmd>[<WS><param1>...<WS><paramN>]<CR>
Response (Success): [<param1>...<WS><paramN>]<CR>
Response (Failure): ERROR[<SP>-<SP><verbose_reason>]<CR>
ご覧のとおり、すべての応答は\r
で終わります。 pySerialを停止するように指示する必要があります。
def sendAndReceive(self, content):
logger.info('Sending {0}'.format(content))
self.ser.write(content + '\r')
self.ser.flush();
response = self.ser.readline() # Currently stops reading on timeout...
if self.isErr(response):
logger.error(response)
return None
else:
return response
私は同じ問題を抱えており、pyserialパッケージにあるserialutil.pyファイルからコピーして変更した独自のreadline()関数を実装しています。
シリアル接続は、この関数が属するクラスの一部であり、属性 'self.ser'に保存されます
def _readline(self):
eol = b'\r'
leneol = len(eol)
line = bytearray()
while True:
c = self.ser.read(1)
if c:
line += c
if line[-leneol:] == eol:
break
else:
break
return bytes(line)
これは、タイムアウトを待つよりも安全で便利で高速なオプションです。
編集:io.TextIOWrapperメソッドを機能させようとしたときに this 投稿に遭遇しました(ありがとう zmo )。したがって、上記のようにカスタムreadline関数を使用する代わりに、以下を使用できます。
self.ser = serial.Serial(port=self.port,
baudrate=9600,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=1)
self.ser_io = io.TextIOWrapper(io.BufferedRWPair(self.ser, self.ser, 1),
newline = '\r',
line_buffering = True)
self.ser_io.write("ID\r")
self_id = self.ser_io.readline()
引数1
をBufferedRWPair
に送信します。そうしないと、バイトごとにデータがTextIOWrapperに渡されず、シリアル接続が再びタイムアウトします。
設定時line_buffering
からTrue
への書き込みごとにflush
関数を呼び出す必要がなくなりました(書き込みが改行文字で終了している場合)。
編集:TextIOWrapperメソッドはsmallコマンド文字列に対して実際に機能しますが、その動作は定義されておらず、送信時に errors につながる可能性があります数バイト以上。実際に最も安全なことは、独自のバージョンのreadline
を実装することです。
pyserialの ドキュメント から:
(シック)
注意:
readline()
のeol
パラメーターは、pySerialがモジュールio
が使用可能な新しいPythonバージョン(V2.6 +)で実行されている場合、サポートされなくなりました。EOL
readline()
にEOL
文字を指定するか、ユニバーサル改行モードを使用するには、io.TextIOWrapper
を使用することをお勧めします。
import serial
import io
ser = serial.serial_for_url('loop://', timeout=1)
sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser))
sio.write(unicode("hello\n"))
sio.flush() # it is buffering. required to get the data out *now*
hello = sio.readline()
print hello == unicode("hello\n")
ボードレート38400でポート3から10個のデータを読み取ります。着信データに入ると、データは\ n文字で区切られます
import serial as self
ser=self.Serial("COM3", 38400)
buffer = []
count = 0.0
c = "\0"
while count < 10:
c = "\0"
if ser.inWaiting():
while True:
val = ser.read(1)
if "\n" in val:
break
else:
c += val
buffer.append(c) # stores all data received into a list
count += 1
print buffer
Pyserial 3.2.1以降(デフォルトはdebian Stretchから)read_untilが利用可能です。カートリッジをデフォルト( '\ n')から '\ r'に変更するには、次のようにします。
import serial
ser=serial.Serial('COM5',9600)
ser.write('command\r') # sending command
ser.read_until('\r') # read until '\r' appears
'\ r'は、カートリッジとして使用するものに変更できます。