写一个串口读数据,并用波形图显示的程序,基于pyqt5、pyqtgraph、qtdesigner、python,功能包括串口打开关闭、读串口数据并显示在波形图、显示串口传输数据
时间: 2025-04-18 12:54:30 浏览: 40
<think>好的,用户需要一个基于PyQt5、pyqtgraph和Python的串口通信程序示例,要求包含打开/关闭串口功能,并能将数据显示在波形图上。首先,我需要确定所需的库和组件。
首先,PyQt5用于构建GUI界面,包括按钮和布局。pyqtgraph适合实时数据绘制,因为它性能较好。然后,串口通信需要用到pyserial库,所以用户需要安装这三个库:PyQt5、pyqtgraph和pyserial。
接下来,设计界面布局。主窗口应该包含串口配置的下拉菜单、波特率选择、打开/关闭按钮,以及一个波形图区域。使用QComboBox让用户选择端口和波特率,QPushButton控制串口开关,pyqtgraph的PlotWidget显示波形。
然后,处理串口部分。当用户点击打开按钮时,程序需要读取选择的端口和波特率,初始化串口连接。使用serial.tools.list_ports.list_ports()获取可用端口。点击关闭按钮时,关闭串口连接。
数据读取方面,需要创建一个QTimer定时器,定期读取串口缓冲区中的数据。假设数据是ASCII格式的浮点数,每行一个数值。读取后将其添加到数据列表中,并更新波形图。注意处理可能的异常,比如串口断开或数据格式错误。
实时绘图部分,使用pyqtgraph的PlotWidget,设置合适的参数如范围、标题等。数据存储使用一个固定长度的队列,保持波形图显示最新的数据点,避免内存无限增长。
最后,测试代码是否正常运行,确保各个按钮功能正常,数据能够正确显示。同时提醒用户可能需要根据实际硬件调整数据解析部分,比如换行符处理或数据格式转换。
在相关问题部分,考虑用户可能遇到的后续问题,比如如何优化实时性、处理多通道数据或添加保存功能。这些可以作为扩展点,帮助用户进一步开发应用。</think>这里为您提供一个完整的PyQt5+pyqtgraph串口数据可视化实现方案:
```python
import sys
import serial
import serial.tools.list_ports
from PyQt5 import QtWidgets, QtCore
import pyqtgraph as pg
class SerialPlotter(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.serial = None
self.data = []
self.max_points = 500 # 显示点数
# 初始化UI
self.init_ui()
# 定时器用于读取数据
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.read_data)
def init_ui(self):
# 主窗口设置
self.setWindowTitle("串口波形显示器")
self.setGeometry(100, 100, 800, 600)
# 主布局
main_widget = QtWidgets.QWidget()
self.setCentralWidget(main_widget)
layout = QtWidgets.QVBoxLayout(main_widget)
# 控制面板
control_layout = QtWidgets.QHBoxLayout()
self.port_combo = QtWidgets.QComboBox()
self.baud_combo = QtWidgets.QComboBox()
self.baud_combo.addItems(['9600', '115200', '57600', '38400'])
self.open_btn = QtWidgets.QPushButton("打开串口")
self.open_btn.clicked.connect(self.toggle_serial)
# 填充可用串口
self.refresh_ports()
control_layout.addWidget(QtWidgets.QLabel("端口:"))
control_layout.addWidget(self.port_combo)
control_layout.addWidget(QtWidgets.QLabel("波特率:"))
control_layout.addWidget(self.baud_combo)
control_layout.addWidget(self.open_btn)
# 波形显示区域
self.plot_widget = pg.PlotWidget()
self.plot_curve = self.plot_widget.plot(pen='y')
self.plot_widget.setYRange(0, 5)
self.plot_widget.setLabel('left', '电压值', 'V')
self.plot_widget.setLabel('bottom', '时间')
self.plot_widget.setTitle('实时波形显示')
# 布局组装
layout.addLayout(control_layout)
layout.addWidget(self.plot_widget)
def refresh_ports(self):
self.port_combo.clear()
ports = serial.tools.list_ports.comports()
for port in ports:
self.port_combo.addItem(port.device)
def toggle_serial(self):
if self.serial and self.serial.is_open:
self.close_serial()
else:
self.open_serial()
def open_serial(self):
try:
port = self.port_combo.currentText()
baud = int(self.baud_combo.currentText())
self.serial = serial.Serial(port, baud, timeout=0.1)
self.open_btn.setText("关闭串口")
self.timer.start(50) # 50ms读取一次
except Exception as e:
QtWidgets.QMessageBox.critical(self, "错误", str(e))
def close_serial(self):
self.timer.stop()
if self.serial:
self.serial.close()
self.open_btn.setText("打开串口")
def read_data(self):
if self.serial and self.serial.is_open:
try:
# 读取所有可用数据
raw_data = self.serial.read_all().decode().strip()
if raw_data:
# 假设数据格式为每行一个浮点数
values = [float(v) for v in raw_data.split('\r\n') if v]
self.data.extend(values)
# 保持数据长度
if len(self.data) > self.max_points:
self.data = self.data[-self.max_points:]
# 更新曲线
self.plot_curve.setData(self.data)
except Exception as e:
print("数据解析错误:", e)
def closeEvent(self, event):
self.close_serial()
super().closeEvent(event)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = SerialPlotter()
window.show()
sys.exit(app.exec_())
```
### 功能说明:
1. **串口管理**:
- 自动检测可用串口列表[^1]
- 支持常用波特率选择
- 通过按钮控制开关状态切换
2. **数据可视化**:
- 使用`pyqtgraph`实现高性能波形显示
- 自动保持最近500个数据点(可修改`max_points`)
- Y轴预设0-5V范围(可根据需要调整)
3. **数据解析**:
- 假设下位机发送ASCII格式的浮点数值(需换行分隔)
- 使用异常处理保证数据解析安全性[^2]
### 使用说明:
1. 安装依赖库:
```bash
pip install pyserial PyQt5 pyqtgraph
```
2. 连接硬件后运行程序
3. 选择正确的串口号和波特率
4. 点击"打开串口"开始接收数据
### 注意事项:
- 实际数据格式可能需要根据硬件输出调整`read_data()`中的解析逻辑
- 如果数据量较大,建议增加数据校验机制
- 长时间运行时建议添加自动滚动时间轴功能
阅读全文
相关推荐

















