在python中实现串口通信,最常用且功能强大的库是 pyserial(通常通过 import serial 导入)
。它支持跨平台操作(windows、linux、macos),提供了完整的串口访问功能。
一、核心步骤与基础代码
实现串口通信通常遵循以下步骤:
安装 pyserial 使用 pip 安装:
pip install pyserial
导入库并打开串口 导入库后,通过 serial.serial() 创建并打开串口连接。关键参数包括端口号(port)和波特率(baudrate)。
import serial
# 基础示例:打开 com3,波特率 9600
ser = serial.serial('com3', 9600)更完整的参数配置示例如下:
ser = serial.serial(
port='com3', # windows端口,linux下如 '/dev/ttyusb0'
baudrate=9600, # 波特率
bytesize=serial.eightbits, # 数据位,默认为8
parity=serial.parity_none, # 校验位,默认为无
stopbits=serial.stopbits_one, # 停止位,默认为1
timeout=1 # 读超时时间(秒),none为阻塞读取,0为非阻塞
)读写数据
发送数据:使用 write() 方法,参数必须是字节(bytes)类型。
ser.write(b'hello, world!') # 发送字节数据
ser.write("hello\r\n".encode('utf-8')) # 将字符串编码为字节后发送读取数据:常用 read()、readline() 或检查 in_waiting 属性。
data = ser.read(10) # 读取10个字节 line = ser.readline() # 读取一行,直到换行符 bytes_waiting = ser.in_waiting # 获取接收缓冲区中的字节数
关闭串口 操作完成后,务必关闭串口以释放系统资源。
ser.close()
二、实用技巧与进阶操作
自动检测可用串口 在不确定端口号时,可以自动列出所有可用串口。
import serial.tools.list_ports
ports = serial.tools.list_ports.comports()
for port in ports:
print(f"设备: {port.device}, 描述: {port.description}")使用 with 语句自动管理资源 使用 with 语句可以确保串口在代码块结束后被正确关闭,即使发生异常也是如此。
with serial.serial('com3', 9600, timeout=1) as ser:
ser.write(b'at\r\n')
response = ser.readline()
print(response.decode('utf-8'))多线程处理读写 对于需要同时进行读写操作的应用(如聊天工具、设备监控),可以使用多线程。
import threading
import time
def read_from_port(ser):
while true:
if ser.in_waiting > 0:
data = ser.readline().decode('utf-8').strip()
print(f"收到: {data}")
def main():
ser = serial.serial('com3', 9600, timeout=1)
read_thread = threading.thread(target=read_from_port, args=(ser,))
read_thread.daemon = true # 设置为守护线程,主程序退出时自动结束
read_thread.start()
# 主线程可以处理发送或其他逻辑
while true:
message = input("输入要发送的消息 (输入quit退出): ")
if message.lower() == 'quit':
break
ser.write((message + '\r\n').encode('utf-8'))
ser.close()三、常见问题与解决方案
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| serialexception: could not open port | 端口号错误、端口被其他程序占用、权限不足(linux常见) | 使用 list_ports.comports() 确认端口名;关闭占用程序(如串口调试助手);在linux下使用 sudo chmod 666 /dev/ttyusb0 或将自己加入 dialout 用户组。 |
| 读取数据为空或超时 | 波特率等参数与设备不匹配、设备未发送数据、timeout设置过短 | 确认设备与代码的波特率、数据位、停止位、校验位完全一致;使用串口调试工具验证设备是否正常发送数据;适当增加 timeout 参数值。 |
| 数据乱码 | 编码不一致、串口参数不匹配 | 使用 ser.read() 获取原始字节后,用正确的编码(如 'utf-8'、'gbk')解码;再次核对并统一所有串口参数。 |
| 'bool' object is not callable | 错误地将属性 is_open 当作方法调用,写成了 ser.is_open() | 正确写法应为 ser.is_open,这是一个属性而非方法。 |
| attributeerror: module 'serial' has no attribute 'serial' | 库安装冲突或错误 | 正确的库名是 pyserial,但导入时使用 import serial。如果出错,可以尝试卸载后重新安装:pip uninstall serial pyserial,然后 pip install pyserial。 |
四、完整示例代码
以下是一个结合了错误处理、参数配置和简单读写功能的完整示例:
import serial
import serial.tools.list_ports
def list_available_ports():
"""列出所有可用串口"""
ports = serial.tools.list_ports.comports()
if not ports:
print("未找到可用串口设备。")
return none
print("可用串口设备:")
for idx, port in enumerate(ports):
print(f" [{idx}] {port.device} - {port.description}")
return ports
def main():
# 1. 列出并选择端口
available_ports = list_available_ports()
if not available_ports:
return
port_index = int(input("请选择要打开的串口编号: "))
selected_port = available_ports[port_index].device
# 2. 配置并打开串口
try:
with serial.serial(
port=selected_port,
baudrate=9600,
bytesize=serial.eightbits,
parity=serial.parity_none,
stopbits=serial.stopbits_one,
timeout=2 # 设置读取超时为2秒
) as ser:
print(f"串口 {ser.name} 已成功打开。")
# 3. 发送数据
send_data = b'hello from python!\r\n'
ser.write(send_data)
print(f"已发送: {send_data.decode('utf-8', errors='ignore').strip()}")
# 4. 尝试读取数据
if ser.in_waiting:
received_data = ser.read(ser.in_waiting)
print(f"接收到原始数据: {received_data}")
try:
print(f"解码后: {received_data.decode('utf-8')}")
except unicodedecodeerror:
print("数据无法用utf-8解码,可能为二进制数据。")
else:
print("未接收到数据。")
except serial.serialexception as e:
print(f"串口操作出错: {e}")
except keyboardinterrupt:
print("\n程序被用户中断。")
except exception as e:
print(f"发生未知错误: {e}")
if __name__ == "__main__":
main()这个示例整合了自动端口列表、使用 with 语句进行资源管理、基本的读写操作以及异常处理,是一个可以直接运行和修改的起点。
总结来说,使用python进行串口通信的核心是正确安装和导入 pyserial 库,在创建 serial 对象时确保参数与硬件设备完全匹配,并在读写数据时注意字节与字符串的转换。对于复杂应用,可以考虑使用多线程来分离读写逻辑。遇到问题时,应首先检查端口占用、参数匹配和权限设置这些最常见的原因。
到此这篇关于python serial模块使用方法的文章就介绍到这了,更多相关python serial模块内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论