在 Windows 中使用 PyQt 和 PySerial 实现串口数据读取
简介
串口通信在许多嵌入式和物联网项目中都是一个重要的组成部分。本博客将详细介绍如何使用 Python 的 PyQt 和 PySerial 库,通过创建一个简单的界面,在 Windows 操作系统下实现串口数据的读取,并在界面上实时显示导航模块的经纬度数据。
技术栈
- PyQt:用于创建桌面应用程序的强大 Python 框架。
- PySerial:用于串口通信的 Python 库。
- Python 3.x:我们使用 Python 3.x 版本。
环境搭建
在开始之前,请确保已经安装了 Python、PyQt 和 PySerial。你可以使用以下命令安装这两个库:
pip install pyqt5 pyserial
如果安装速度太慢,可以尝试国内源安装:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名
界面设计
首先,我们设计一个简单的用户界面,包括串口选择、波特率、数据位、停止位的设置,以及一个按钮用于开始和停止读取。
# 导入必要的库
import sys
import serial
import csv
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QComboBox, QVBoxLayout, QWidget, QLineEdit, QHBoxLayout
from serial.tools import list_ports
# ...(省略部分代码)
class SerialReader(QMainWindow):
def __init__(self):
super().__init__()
# 界面设计代码省略...
# 显示经度和纬度的文本框
self.longitude_label = QLabel("经度:")
self.longitude_display = QLineEdit(self)
self.longitude_display.setReadOnly(True)
self.latitude_label = QLabel("纬度:")
self.latitude_display = QLineEdit(self)
self.latitude_display.setReadOnly(True)
# 界面布局代码省略...
# ...(省略部分代码)
def handle_data_received(self, longitude, latitude):
# Update the displayed coordinates
self.longitude_display.setText(str(longitude))
self.latitude_display.setText(str(latitude))
串口数据读取
为了实现串口数据的读取,我们创建了一个继承自 QThread 的 SerialReaderThread 类。在这个类中,我们使用 PySerial 打开串口,并通过 struct 解析二进制数据。
import struct
class SerialReaderThread(QThread):
data_received = pyqtSignal(float, float)
def __init__(self, port, baudrate, databits, stopbits):
super().__init__()
self.port = port
self.baudrate = baudrate
self.databits = databits
self.stopbits = stopbits
self.serial = None
self.running = False
def run(self):
try:
with serial.Serial(self.port, self.baudrate, bytesize=self.databits, stopbits=self.stopbits, timeout=2) as ser:
self.running = True
while self.running:
# Assuming the data is a binary format, with two 4-byte floats (longitude and latitude)
data = ser.read(8) # Assuming each data point is 8 bytes (adjust accordingly)
if data:
# Unpack the binary data into two floats
longitude, latitude = struct.unpack('ff', data)
self.data_received.emit(longitude, latitude)
# Save data to CSV file
with open('gps_data.csv', 'a', newline='') as csvfile:
csv_writer = csv.writer(csvfile)
csv_writer.writerow([longitude, latitude])
except Exception as e:
print(f"串口读取错误:{str(e)}")
def stop(self):
self.running = False
self.wait()
主界面与线程连接
在主界面中,我们通过按钮连接了开始和停止串口读取的操作,并在串口数据接收时更新了界面上的经纬度数据。
class SerialReader(QMainWindow):
def __init__(self):
super().__init__()
# ...(省略部分代码)
# 开始和停止读取按钮的点击事件连接
self.start_button.clicked.connect(self.toggle_serial_reading)
# ...(省略部分代码)
def toggle_serial_reading(self):
if not self.serial_reader_thread or not self.serial_reader_thread.isRunning():
# Start reading
port = self.serial_port_combobox.currentText()
baudrate = int(self.baudrate_combobox.currentText())
databits = int(self.databits_combobox.currentText())
stopbits = float(self.stopbits_combobox.currentText())
self.serial_reader_thread = SerialReaderThread(port, baudrate, databits, stopbits)
self.serial_reader_thread.data_received.connect(self.handle_data_received)
self.serial_reader_thread.start()
self.start_button.setText("停止读取")
else:
# Stop reading
self.serial_reader_thread.stop()
self.start_button.setText("开始读取")
效果展示:
总结
通过结合 PyQt 和 PySerial,我们成功实现了一个串口数据读取的应用程序。这个应用程序可以在 Windows 操作系统中选择串口、设置通信参数,并实时显示导航模块的经纬度数据。这为处理实时定位信息提供了一个简单而强大的工具。
在实际应用中,你可能需要根据你的项目需求进一步调整界面设计和串口通信的细节。希望这篇博客能够帮助你入门串口通信的 Python 编程,并激发你进一步探索这个领域的兴趣。