Windows 下的 pySerial API 简介
本节主要介绍 pySerial API,参考 pyserial。
1 serialutil.py
serialutil
为 pySerial
提供了支持不同后端的函数和类。
# serial.__init__.py
from serial.serialutil import *
1.1 常量
- 创建控制字节:
serial.XOFF
、serial.XON
- Parity:
PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE = 'N', 'E', 'O', 'M', 'S'
PARITY_NAMES = {
PARITY_NONE: 'None',
PARITY_EVEN: 'Even',
PARITY_ODD: 'Odd',
PARITY_MARK: 'Mark',
PARITY_SPACE: 'Space',
}
- Stop bits:
STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO = (1, 1.5, 2)
请注意,POSIX 不支持1.5个停止位。它将下降到2个停止位。
- Byte size:
FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS = (5, 6, 7, 8)
-
serial.CR
,serial.LF
分别表示b'\r'
,b'\n'
。 - 其他:
serial.VERSION
表示serial
版本
1.2 class Timeout(object)
time.monotonic()
以绝对时间为准,获取的时间为系统重启到现在的时间,更改系统时间对它没有影响。
class Timeout(object):
"""\
Abstraction for timeout operations. Using time.monotonic() if available
or time.time() in all other cases.
The class can also be initialized with 0 or None, in order to support
non-blocking and fully blocking I/O operations. The attributes
is_non_blocking and is_infinite are set accordingly.
"""
if hasattr(time, 'monotonic'):
# Timeout implementation with time.monotonic(). This function is only
# supported by Python 3.3 and above. It returns a time in seconds
# (float) just as time.time(), but is not affected by system clock
# adjustments.
TIME = time.monotonic
else:
# Timeout implementation with time.time(). This is compatible with all
# Python versions but has issues if the clock is adjusted while the
# timeout is running.
TIME = time.time
def __init__(self, duration):
"""Initialize a timeout with given duration"""
self.is_infinite = (duration is None)
self.is_non_blocking = (duration == 0)
self.duration = duration
if duration is not None:
self.target_time = self.TIME() + duration
else:
self.target_time = None
def expired(self):
"""Return a boolean, telling if the timeout has expired"""
return self.target_time is not None and self.time_left() <= 0
def time_left(self):
"""Return how many seconds are left until the timeout expires"""
if self.is_non_blocking:
return 0
elif self.is_infinite:
return None
else:
delta = self.target_time - self.TIME()
if delta > self.duration:
# clock jumped, recalculate
self.target_time = self.TIME() + self.duration
return self.duration
else:
return max(0, delta)
def restart(self, duration):
"""\
Restart a timeout, only supported if a timeout was already set up
before.
"""
self.duration = duration
self.target_time = self.TIME() + duration
1.3 serialutil.SerialBase
serialutil.SerialBase
是 Serial 端口的基类,提供了 __init__
函数和端口属性的 get
/set
功能。
类别属性默认值:
BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
9600, 19200, 38400, 57600, 115200, 230400, 460800, 500000,
576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000,
3000000, 3500000, 4000000)
BYTESIZES = (FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS)
PARITIES = (PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE)
STOPBITS = (STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO)
初始化函数:
def __init__(self,
port=None,
baudrate=9600,
bytesize=EIGHTBITS,
parity=PARITY_NONE,
stopbits=STOPBITS_ONE,
timeout=None,
xonxoff=False,
rtscts=False,
write_timeout=None,
dsrdtr=False,
inter_byte_timeout=None,
exclusive=None,
**kwargs):
初始化通讯端口对象。如果给出了 port
,则该端口将立即打开。否则,将返回处于关闭状态的串行端口对象。
-
port
:设备名称,可以是None
- baudrate (int): Baud(波特率。可能值:50、75、110、134、150、200、300、600、1200、1800、2400、4800、9600、19200、38400、57600、115200。
-
bytesize:数据的 bit 数。可能值:
FIVEBITS
,SIXBITS
,SEVENBITS
,EIGHTBITS
-
parity:可以奇偶校验。可能值:
PARITY_NONE
,PARITY_EVEN
,PARITY_ODD
PARITY_MARK
,PARITY_SPACE
-
stopbits:停止位的个数。 可能值:
STOPBITS_ONE
,STOPBITS_ONE_POINT_FIVE
,STOPBITS_TWO
-
timeout (float):设定
read
的 timeout - xonxoff (bool):启动软件的流程控制
- rtscts (bool):启动硬件(RTS/CTS) 流程控制
- dsrdtr (bool):启动硬件(DSR/DTR) 流程控制
-
write_timeout (float): 设定
write
的 timeout -
inter_byte_timeout (float):内部字符的 timeout,
None
关闭该功能 (默认值). - exclusive (bool):设置独占访问 (仅 POSIX 支持)。如果端口已经以独占访问模式(exclusive access mode)打开,则不能以独占访问模式打开端口。
给定 port
后,将在创建对象时立即打开该端口。当 port
为 None
时,不会打开它,接下来需要调用 open()
打开。
port
是设备名称:取决于操作系统。例如,在 GNU/Linux 上为 /dev/ttyUSB0
,在 Windows 上为 COM3
。
控制 read()
行为的参数 timeout
的可能值:
-
timeout = None
: 永远等待/直到收到请求的字节数 -
timeout = 0
: 非阻塞模式(non-blocking mode),在任何情况下立即返回,返回零或多个,直到请求的字节数 -
timeout = x
: 如果请求的字节数可用,则将超时设置为 x 秒(允许使用float
)立即返回;否则,请等待直到超时到期,然后返回直到那时为止接收到的所有字节。
除非设置了 write_timeout
,否则默认情况下 write()
处于阻塞状态。有关可能的值,请参考上面的超时列表。
请注意,可能不支持同时启用两种流控制方法(xonxoff
和rtscts
)。通常一次使用一种方法,不能同时使用两种方法。并非所有平台都支持 dsrdtr
(已被忽略)。将其设置为 None
会导致其状态遵循 rtscts
。
属性相关函数:
-
rts
:set
/get
RTS 线路的状态。将RTS
线路设置为指定的逻辑电平(logic leve)。可以在打开串行端口之前分配该值,然后在open()
上应用该值(有限制,请参见open()
。 -
dtr
:set
/get
DTR 线路的状态。将DTR
线路设置为指定的逻辑电平(logic leve)。可以在打开串行端口之前分配该值,然后在open()
上应用该值(有限制,请参见open()
。 -
rs485_mode
:启用 RS485 模式并应用新设置,设置为“None
”以禁用。 -
name
:设备名称。
读取、写入函数:
-
read_until(expected=LF, size=None)
:读取直到找到期望的序列(默认为'\ n'
),超过大小或直到发生超时为止。expected
,即要搜索的字节字符串。size
为需要读取的字节数。 -
send_break(duration=0.25)
:duration
(float)–激活BREAK条件的时间。 -
break_condition
:get/set 当前 BREAK 状态
2 serialwin32.py
serialwin32.py
模块的后端是 Windows 系统,支持 32、64 位。
2.1 Serial
-
open
:使用当前设置打开端口。如果无法打开端口,则可能会引发SerialException
。 -
close()
关闭端口。 -
read(size=1)
:size
表示读取的字节数。返回 bytes。 -
write(data)
:将字节数据写入端口。 -
flush()
:清除文件一样的对象。在这种情况下,请等待所有数据写入。 -
in_waiting()
:返回当前在输入缓冲区中的字节数。 -
out_waiting()
:返回当前在输出缓冲区中的字节数。
还可以考虑使用函数 serial_for_url()
代替直接创建 Serial
实例。
3 serial.tools.list_ports
serial.tools.list_ports.grep
使用正则表达式搜索端口。搜索:端口名称,描述和硬件 ID。该函数返回一个可迭代的方法,该方法返回与 serial.tools.list_ports.comport()
相同的元组。
from serial.tools import list_ports
for dev in list_ports.grep('COM', include_links=True):
print(dev)
输出:
COM1 - 通信端口 (COM1)
COM3 - USB Serial Port (COM3)