3. 发送ASCII命令并接收响应
任务说明
本案例实现通过串口向设备发送ASCII格式命令(如 AT+VER?\r\n),并完整读取设备返回的响应数据。代码将自动处理串口打开、命令发送、响应接收与超时控制,最终在终端打印响应内容。
实现代码
import serial
import time
def send_ascii_command(port: str, command: str, baudrate: int = 9600,
timeout: float = 2.0) -> str:
"""
发送ASCII命令并读取响应
参数:
port: 串口号,如 'COM3' (Windows) 或 '/dev/ttyUSB0' (Linux)
command: ASCII命令字符串,如 'AT+VER?\\r\\n'
baudrate: 波特率,默认9600
timeout: 读取超时时间(秒),默认2秒
返回:
设备返回的响应字符串(已去除首尾空白)
"""
# 确保命令以回车换行结尾(若未包含)
if not command.endswith('\r\n'):
command += '\r\n'
# 打开串口
with serial.Serial(port, baudrate, timeout=timeout) as ser:
# 清空接收缓冲区,避免残留数据干扰
ser.reset_input_buffer()
# 发送ASCII命令(编码为bytes)
ser.write(command.encode('ascii'))
# 读取响应直到超时
response_lines = []
while True:
line = ser.readline()
if not line: # 超时无新数据,结束读取
break
try:
decoded = line.decode('ascii').strip()
except UnicodeDecodeError:
decoded = line.decode('ascii', errors='replace').strip()
if decoded:
response_lines.append(decoded)
return '\n'.join(response_lines)
if __name__ == '__main__':
# 示例:向设备查询版本号
# 请根据实际设备修改串口号与命令
PORT = 'COM3' # Linux下如 '/dev/ttyUSB0'
CMD = 'AT+VER?'
try:
resp = send_ascii_command(PORT, CMD)
print('设备响应:')
print(resp if resp else '(无响应)')
except serial.SerialException as e:
print(f'串口错误: {e}')
关键实现说明
- 命令格式处理:若传入命令未包含
\r\n,代码自动追加,兼容不同设备对行结束符的要求。 - 缓冲区清理:发送前调用
reset_input_buffer()丢弃历史残留数据,确保读取的是本次命令的响应。 - 响应读取策略:使用
readline()按行读取,直到超时(无新数据)为止,可完整捕获多行响应。 - 异常处理:捕获串口打开失败、设备不存在等
SerialException,给出明确提示。
运行与验证
- 安装依赖:
pip install pyserial - 修改配置:将代码中
PORT改为实际串口号,CMD改为设备支持的ASCII命令。 - 执行:
python send_ascii.py - 判定标准:程序打印出设备返回的文本内容,且内容与设备手册中该命令的预期响应一致,即验证通过。若打印
(无响应),请检查串口号、波特率、设备供电及命令格式。
验证要点
- 确认串口设备已连接且供电正常,串口号与代码中一致。
- 若设备需要特定波特率(如115200),修改
send_ascii_command调用时的baudrate参数。 - 部分设备响应前有延迟,可适当增大
timeout值(如5秒)以等待慢速设备。 - 命令必须为设备支持的ASCII指令集,否则设备可能返回错误码或静默无响应。