Pyserial readline() 在不读取串行数据的情况下永远挂起程序
Pyserial readline() hangs the program forever without reading serial data
调用 pyserial.readline() 函数时我的程序挂起。我运行在程序上跟踪了一下,最下面的循环一直在重复
transport.py(47): self.sensor_data = self.serif.readline()
--- modulename: serialposix, funcname: read
serialposix.py(477): if not self.is_open:
serialposix.py(479): read = bytearray()
serialposix.py(480): timeout = Timeout(self._timeout)
--- modulename: serialutil, funcname: __init__
serialutil.py(125): self.is_infinite = (duration is None)
serialutil.py(126): self.is_non_blocking = (duration == 0)
serialutil.py(127): self.duration = duration
serialutil.py(128): if duration is not None:
serialutil.py(129): self.target_time = self.TIME() + duration
serialposix.py(481): while len(read) < size:
serialposix.py(482): try:
serialposix.py(483): ready, _, _ = select.select([self.fd, self.pipe_abort_read_r], [], [], timeout.time_left())
--- modulename: serialutil, funcname: time_left
serialutil.py(139): if self.is_non_blocking:
serialutil.py(141): elif self.is_infinite:
serialutil.py(144): delta = self.target_time - self.TIME()
serialutil.py(145): if delta > self.duration:
serialutil.py(150): return max(0, delta)
serialposix.py(484): if self.pipe_abort_read_r in ready:
serialposix.py(491): if not ready:
serialposix.py(493): buf = os.read(self.fd, size - len(read))
serialposix.py(496): if not buf:
serialposix.py(503): read.extend(buf)
serialposix.py(516): if timeout.expired():
--- modulename: serialutil, funcname: expired
serialutil.py(135): return self.target_time is not None and self.time_left() <= 0
--- modulename: serialutil, funcname: time_left
serialutil.py(139): if self.is_non_blocking:
serialutil.py(141): elif self.is_infinite:
serialutil.py(144): delta = self.target_time - self.TIME()
serialutil.py(145): if delta > self.duration:
serialutil.py(150): return max(0, delta)
serialposix.py(481): while len(read) < size:
serialposix.py(518): return bytes(read)
我驱动我定义为"serif"的接口的串口设置如下。
self.serif = serial.Serial('/dev/ttyS1', 9600)
self.serif.bytesize = serial.EIGHTBITS
self.serif.parity = serial.PARITY_NONE
self.serif.stopbits = serial.STOPBITS_ONE
self.serif.timeout = 0.3
我尝试在开始读取功能之前添加功能 self.serif.reset_input_buffer()
,但这似乎让事情变得更糟。
这里是 readline()
函数之前的相关函数的副本。
def rcv_data(self):
"""Receives data, cleans it and returns it to main()"""
# CHECKS FOR DATA IN BUFFER
serial_buffer = self.serif.inWaiting()
if serial_buffer > 0:
cnt = 0
print("serial_buffer = %i" % serial_buffer)
while self.serif.read().encode('hex') != '02':
cnt += 1
serial_buffer -= 1
print("Eliminated %i peices of garbage" % (cnt))
# Reads data from the buffer
self.sensor_data = self.serif.readline()
我不明白为什么这段代码似乎卡在 serialposix.py 循环中。如果有人能帮助我,我将不胜感激!
谢谢,如果我需要发送更多信息,请告诉我。
编辑
为什么我之前让它工作不再是一个谜。我为我的设备和 RS485 电路 pull-up/pull-down 电阻供电的电源不稳定。因此,我在我的 SOF 或 EOF 应该在的地方收到了噪音,所以程序会一直继续读取。话虽这么说,但我仍然保留了以下解决方法,因为它更清楚我在做什么(虽然时间更长...)
此外,我在下面的答案中添加了一个中断,以防在一定数量的读取周期内找不到 SOF 或 EOF。
EDIT_END
不是特别的答案,而是一种解决方法。我将从强调以下内容开始。
- readline() 正在循环,因为它期望 EOF 为
\n
(十六进制的 0x11
)我和我的串行数据从未提供过这个。为什么我之前让它工作是个谜。
- 我仍然不知道为什么这在设置的超时后不停止循环。
我的变通方法主要涉及在某种意义上创建我自己的 readline() 函数,并指定我自己的 EOF。我使用以下代码来执行此操作。
def readline(self):
SOF = '02'
EOF = '03'
# FIND START OF FRAME
while serif.read().encode('hex') != SOF:
continue
# RECORD UNTIL END OF FRAME
while True:
temp = serif.read()
if temp.encode('hex') == EOF:
break
else:
sensor_data += temp
我原来的函数现在看起来像这样。
def rcv_data(self):
"""Receives data cleans it and returns it to main()"""
# CHECKS FOR DATA IN BUFFER
if serif.inWaiting() > 0:
readline()
return sensor_data
调用 pyserial.readline() 函数时我的程序挂起。我运行在程序上跟踪了一下,最下面的循环一直在重复
transport.py(47): self.sensor_data = self.serif.readline()
--- modulename: serialposix, funcname: read
serialposix.py(477): if not self.is_open:
serialposix.py(479): read = bytearray()
serialposix.py(480): timeout = Timeout(self._timeout)
--- modulename: serialutil, funcname: __init__
serialutil.py(125): self.is_infinite = (duration is None)
serialutil.py(126): self.is_non_blocking = (duration == 0)
serialutil.py(127): self.duration = duration
serialutil.py(128): if duration is not None:
serialutil.py(129): self.target_time = self.TIME() + duration
serialposix.py(481): while len(read) < size:
serialposix.py(482): try:
serialposix.py(483): ready, _, _ = select.select([self.fd, self.pipe_abort_read_r], [], [], timeout.time_left())
--- modulename: serialutil, funcname: time_left
serialutil.py(139): if self.is_non_blocking:
serialutil.py(141): elif self.is_infinite:
serialutil.py(144): delta = self.target_time - self.TIME()
serialutil.py(145): if delta > self.duration:
serialutil.py(150): return max(0, delta)
serialposix.py(484): if self.pipe_abort_read_r in ready:
serialposix.py(491): if not ready:
serialposix.py(493): buf = os.read(self.fd, size - len(read))
serialposix.py(496): if not buf:
serialposix.py(503): read.extend(buf)
serialposix.py(516): if timeout.expired():
--- modulename: serialutil, funcname: expired
serialutil.py(135): return self.target_time is not None and self.time_left() <= 0
--- modulename: serialutil, funcname: time_left
serialutil.py(139): if self.is_non_blocking:
serialutil.py(141): elif self.is_infinite:
serialutil.py(144): delta = self.target_time - self.TIME()
serialutil.py(145): if delta > self.duration:
serialutil.py(150): return max(0, delta)
serialposix.py(481): while len(read) < size:
serialposix.py(518): return bytes(read)
我驱动我定义为"serif"的接口的串口设置如下。
self.serif = serial.Serial('/dev/ttyS1', 9600)
self.serif.bytesize = serial.EIGHTBITS
self.serif.parity = serial.PARITY_NONE
self.serif.stopbits = serial.STOPBITS_ONE
self.serif.timeout = 0.3
我尝试在开始读取功能之前添加功能 self.serif.reset_input_buffer()
,但这似乎让事情变得更糟。
这里是 readline()
函数之前的相关函数的副本。
def rcv_data(self):
"""Receives data, cleans it and returns it to main()"""
# CHECKS FOR DATA IN BUFFER
serial_buffer = self.serif.inWaiting()
if serial_buffer > 0:
cnt = 0
print("serial_buffer = %i" % serial_buffer)
while self.serif.read().encode('hex') != '02':
cnt += 1
serial_buffer -= 1
print("Eliminated %i peices of garbage" % (cnt))
# Reads data from the buffer
self.sensor_data = self.serif.readline()
我不明白为什么这段代码似乎卡在 serialposix.py 循环中。如果有人能帮助我,我将不胜感激!
谢谢,如果我需要发送更多信息,请告诉我。
编辑
为什么我之前让它工作不再是一个谜。我为我的设备和 RS485 电路 pull-up/pull-down 电阻供电的电源不稳定。因此,我在我的 SOF 或 EOF 应该在的地方收到了噪音,所以程序会一直继续读取。话虽这么说,但我仍然保留了以下解决方法,因为它更清楚我在做什么(虽然时间更长...)
此外,我在下面的答案中添加了一个中断,以防在一定数量的读取周期内找不到 SOF 或 EOF。
EDIT_END
不是特别的答案,而是一种解决方法。我将从强调以下内容开始。
- readline() 正在循环,因为它期望 EOF 为
\n
(十六进制的0x11
)我和我的串行数据从未提供过这个。为什么我之前让它工作是个谜。 - 我仍然不知道为什么这在设置的超时后不停止循环。
我的变通方法主要涉及在某种意义上创建我自己的 readline() 函数,并指定我自己的 EOF。我使用以下代码来执行此操作。
def readline(self):
SOF = '02'
EOF = '03'
# FIND START OF FRAME
while serif.read().encode('hex') != SOF:
continue
# RECORD UNTIL END OF FRAME
while True:
temp = serif.read()
if temp.encode('hex') == EOF:
break
else:
sensor_data += temp
我原来的函数现在看起来像这样。
def rcv_data(self):
"""Receives data cleans it and returns it to main()"""
# CHECKS FOR DATA IN BUFFER
if serif.inWaiting() > 0:
readline()
return sensor_data