前言:这个小项目是自己的毕设,做的比较简单,之前记录是pyqt的环境配置,说实话,今天突然看到自己也都忘得差不多了,看来还是要好好记录一下自己的知识。
这个项目分为了两个部分,其中下位机的数据采集是使用STM32L0系列的开发板作为了主控器,温度采集模块是DB18B20,还有一个GSM模块,用于发送短信,比较简单的项目。上位机部分也就是使用pyserial模块来进行数据的接收,使用matplotlib模块来进行绘图。
下位机部分的代码还在,但是用于时间关系,开发板等东西已经送人了,所以这篇博客主要就讲一下上位机的程序开发,但是为了和上一篇博客中实现的效果一样,我去找到了一个软件模拟下位机向PC端发送数据。
1.模拟软件向PC端发送数据–VSPD软件
找了一篇博客,包含VSPD使用教程,放上链接如下:
https://blog.csdn.net/qq_34202873/article/details/88391265
2.串口接收数据
今天准备把之前的代码拿来跑一下,但是发现出了一些小问题,这里也记载一下,被自己蠢哭的问题。
问题1:
pyserial模块的安装问题,换了环境,但是使用pip安装,以及在pycharm中进行安装,都没有成功,下载的包都是空的文件夹,其截图如下:
解决办法,去官网下载压缩包,然后解压到你的解释器的Lib/site-packages目录下,然后运行命令进行安装;
https://pypi.org/project/pyserial/#files
命令行安装
综上问题1解决
问题2(自己犯低级错误):
a.串口初始化部分
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
### 1. 画图
self.my_graph_1 = MyMplCanvas()
self.left1.addWidget(self.my_graph_1)
self.t = [] ### 储存计数
self.m = [] ### 储存接收的数据
self.i = 0 ### 计数值
### 2. 串口部分
# 串口初始化为None
self.ser = None
# 设置窗口名称
self.setWindowTitle("Temperature--Serial")
# 刷新一下串口的列表
# self.refresh()
# 波特率
self.comboBox_2.addItem('115200')
self.comboBox_2.addItem('57600')
self.comboBox_2.addItem('9600')
self.comboBox_2.addItem('4800')
self.comboBox_2.addItem('2400')
self.comboBox_2.addItem('1200')
# 实例化一个定时器
self.timer = QTimer(self)
# 定时器调用读取串口接收数据
self.timer.timeout.connect(self.recv)
# 打开串口按钮
self.pushButton.clicked.connect(self.open)
# 关闭串口
self.pushButton_2.clicked.connect(self.close)
# 波特率修改
self.comboBox_2.activated.connect(self.baud_modify)
# 串口号修改
self.comboBox.activated.connect(self.com_modify)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
b.数据接收及处理
# 串口接收数据处理
def recv(self):
print("recv")
data = self.ser.readline()
#print(type(data))
out_s = data.decode('iso-8859-1')
# 调试打印输出数据
print(data)
print(out_s)
float_data = float(out_s) # 数据转化为float
#print(out_s.strip('\n'))
# 存储获取的数据
self.i = self.i + 1.0
self.t.append(self.i)
self.m.append(float_data)
#self.m.append(1)
self.lineEdit.insert(out_s)
### 方法二 接收数据后调用画图函数
self.draw()
# 串口接收数据处理
def recv(self):
print("recv")
data = self.ser.readline()
#print(type(data))
out_s = data.decode('iso-8859-1')
# 调试打印输出数据
print(data)
print(out_s)
float_data = float(out_s) # 数据转化为float
#print(out_s.strip('\n'))
# 存储获取的数据
self.i = self.i + 1.0
self.t.append(self.i)
self.m.append(float_data)
#self.m.append(1)
self.lineEdit.insert(out_s)
### 方法二 接收数据后调用画图函数
self.draw()
# 波特率修改
def baud_modify(self):
if self.ser != None:
self.ser.baudrate = int(115200)
print("波特率修改\n")
# 串口号修改
def com_modify(self):
if self.ser != None:
self.ser.port = self.comboBox.currentText()
self.statusbar.showMessage("修改串口号")
print("串口号修改\n")
# 打开串口
def open(self):
print("打开串口\n")
print("true......")
# 开启定时器
self.timer.start(1000)
try:
self.ser = serial.Serial("com2", int(self.comboBox_2.currentText())) ### 为了方便使用软件发送的数据,
# 写死了串口com2口
## 测试
print(self.ser)
except:
print("没有可用的串口或当前串口被占用\n")
return None
self.statusbar.showMessage("打开串口")
print('open')
def close(self):
print("关闭串口\n")
# 关闭定时器,停止读取接收数据
# self.timer_send.stop()
self.timer.stop()
try:
# 关闭串口
self.ser.close()
except:
# QMessageBox.critical(self, 'pycom', '关闭串口失败')
return None
self.ser = None
self.statusbar.showMessage("关闭串口")
print('close!')
### 刷新串口的功能,在使用模拟软件发送数据时,关闭该功能
# def refresh(self):
# # 查询可用的串口
# plist = list(serial.tools.list_ports.comports())
# if len(plist) <= 0:
# print("No used com!");
# # self.statusBar.showMessage('没有可用的串口')
# self.statusbar.showMessage("没有可用串口")
# else:
# # 把所有的可用的串口输出到comboBox中去
# self.comboBox.clear()
# for i in range(0, len(plist)):
# plist_0 = list(plist[i])
# self.comboBox.addItem(str(plist_0[0]))
##绘制图形代码
def draw(self):
#print("IN draw\n")
if len(self.t) > 30: ### 储存的数据保持在 30 个,超过30个数据,就开始弹出数据,类似于队列的形式
self.t.pop(0)
self.m.pop(0)
self.my_graph_1.axes.cla()
self.my_graph_1.axes.plot(self.t,self.m, 'r')
self.my_graph_1.axes.set_xlabel('Times')
self.my_graph_1.axes.set_ylabel("Temperature")
self.my_graph_1.draw()1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
以上就是使用串口的部分,代码没有怎么优化,因为要期末考试啦,需要复习。。,请见谅
3. 使用绘图工具绘制图形
很简单,直接上代码啦,绘制图形的函数写在上面的类中,不是这个类,具体代码我也贴在上面
class MyMplCanvas(FigureCanvas): # 画布基类
"""这是一个窗口部件,即QWidget(当然也是FigureCanvasAgg)"""
def __init__(self, parent=None, width=100, height=50, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
FigureCanvas.__init__(self, fig)
self.setParent(parent)
self.axes.set_xlabel('Times')
self.axes.set_ylabel("Temperature")1
2
3
4
5
6
7
8
9
10
11
12
13
14
4. main方法中的调用
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())1
2
3
4
5
6
7
5.测试方法
1.运行pycharm代码
2.打开模拟软件
3.串口调试工具中手动发送数据(数据以\n\r结尾,具体看图中的标识)
4.观察生成的图形