Python serial (pySerial) 使用 EOL \r 而不是 \n 读取行
Python serial (pySerial) Reading lines with EOL \r instead of \n
我正在通过 RS232 电缆与 SR830 锁相放大器通信。读取数据时如下代码:
import serial
def main():
ser = serial.Serial(
port='COM6',
baudrate=19200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
ser.timeout=1
ser.write("OUTP? 1 \r\n".encode()) #Asks the Lock-in for x-value
ser.write("++read\r\n".encode())
x=ser.readline()
print (x)
if __name__ == '__main__': main()
我得到一个像 b'-3.7486e-008\r'
这样的字节串。但是 ser.readline()
函数无法将 \r 识别为 EOL。所以我每次读取数据都要等待超时,这样会很麻烦,因为我想尽可能快地取很多点。而且数字的长度变化很大,所以我不能只使用 ser.read(12)
例如。我试过使用 io.TextIOWrapper 但我不清楚如何实现它。这是我的尝试:
import serial
import io
def main():
ser = serial.Serial(
port='COM6',
baudrate=19200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
ser.timeout=1
sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser))
sio.write("OUTP? 1 \r\n") #Asks the Lock-in for x-value
sio.write("++read\r\n")
x=sio.readline()
print (x)
if __name__ == '__main__': main()
它只打印一个空白 space。任何帮助将不胜感激,谢谢。
编辑:
这是我在回答后的工作代码,使用循环:
import serial
def main():
ser = serial.Serial(
port='COM6',
baudrate=19200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
ser.timeout=5
ser.write("OUTP? 1 \r\n".encode()) #Asks the Lock-in for x-value
ser.write("++read\r\n".encode())
buffer = ""
while True:
oneByte = ser.read(1)
if oneByte == b"\r": #method should returns bytes
print (buffer)
break
else:
buffer += oneByte.decode()
if __name__ == '__main__': main()
使用简单的循环阅读怎么样?
def readData():
buffer = ""
while True:
oneByte = ser.read(1)
if oneByte == b"\r": #method should returns bytes
return buffer
else:
buffer += oneByte.decode("ascii")
你可以查看 Pyserial 包中的 serialutil.py 文件,它们使用相同的方式实现方法 read_until
。
The line terminator is always b'\n'
for binary files; for text files, the newline
argument to open()
can be used to select the line terminator(s) recognized.
当然,这里不能用open
。但是你可以做的是使用 io.TextIOWrapper
将字节流转换为文本流:
ser_text = io.TextIOWrapper(ser, newline='\r')
ser_text.readline()
改用read_until():
ser.read_until(b'\r')
小心,别忘了b。否则即使它读取 '\r' 函数也不会 return 直到达到端口上设置的超时。
我正在通过 RS232 电缆与 SR830 锁相放大器通信。读取数据时如下代码:
import serial
def main():
ser = serial.Serial(
port='COM6',
baudrate=19200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
ser.timeout=1
ser.write("OUTP? 1 \r\n".encode()) #Asks the Lock-in for x-value
ser.write("++read\r\n".encode())
x=ser.readline()
print (x)
if __name__ == '__main__': main()
我得到一个像 b'-3.7486e-008\r'
这样的字节串。但是 ser.readline()
函数无法将 \r 识别为 EOL。所以我每次读取数据都要等待超时,这样会很麻烦,因为我想尽可能快地取很多点。而且数字的长度变化很大,所以我不能只使用 ser.read(12)
例如。我试过使用 io.TextIOWrapper 但我不清楚如何实现它。这是我的尝试:
import serial
import io
def main():
ser = serial.Serial(
port='COM6',
baudrate=19200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
ser.timeout=1
sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser))
sio.write("OUTP? 1 \r\n") #Asks the Lock-in for x-value
sio.write("++read\r\n")
x=sio.readline()
print (x)
if __name__ == '__main__': main()
它只打印一个空白 space。任何帮助将不胜感激,谢谢。
编辑: 这是我在回答后的工作代码,使用循环:
import serial
def main():
ser = serial.Serial(
port='COM6',
baudrate=19200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
ser.timeout=5
ser.write("OUTP? 1 \r\n".encode()) #Asks the Lock-in for x-value
ser.write("++read\r\n".encode())
buffer = ""
while True:
oneByte = ser.read(1)
if oneByte == b"\r": #method should returns bytes
print (buffer)
break
else:
buffer += oneByte.decode()
if __name__ == '__main__': main()
使用简单的循环阅读怎么样?
def readData():
buffer = ""
while True:
oneByte = ser.read(1)
if oneByte == b"\r": #method should returns bytes
return buffer
else:
buffer += oneByte.decode("ascii")
你可以查看 Pyserial 包中的 serialutil.py 文件,它们使用相同的方式实现方法 read_until
。
The line terminator is always
b'\n'
for binary files; for text files, thenewline
argument toopen()
can be used to select the line terminator(s) recognized.
当然,这里不能用open
。但是你可以做的是使用 io.TextIOWrapper
将字节流转换为文本流:
ser_text = io.TextIOWrapper(ser, newline='\r')
ser_text.readline()
改用read_until():
ser.read_until(b'\r')
小心,别忘了b。否则即使它读取 '\r' 函数也不会 return 直到达到端口上设置的超时。