实现功能:
- 实时显示近3分钟温度随时间的变化曲线
- 实时显示当前温度、温度均值、温度波动
- 根据温度数据实时调整纵坐标轴范围
使用的工具:
- 硬件使用树莓派4B,烧录的是Raspberry Pi OS系统
- 使用Qt Creator软件中UI Designer工具设计界面
- 使用python语言编写逻辑,主要使用python中的pyqt5包以及其中的pyqtchart模块
程序原理:
- 下位机每0.1秒采集1次温度并实时上传
- 上位机创建0.1秒周期的定时器,定时检查收到的数据并处理,添加到显示序列后更新曲线
- 同时进行3分钟温度均值与波动的计算并显示。
下载QT creator,使用里面的UI designer工具创建界面,如下图:
下位机数据格式,ADC值加回车换行
使用pyqt自带工具将.ui文件转换为.py文件,转化后的py文件如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'widget.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_TemperatureDispaly(object):
def setupUi(self, TemperatureDispaly):
TemperatureDispaly.setObjectName("TemperatureDispaly")
TemperatureDispaly.resize(1024, 600)
self.gridLayout = QtWidgets.QGridLayout(TemperatureDispaly)
self.gridLayout.setObjectName("gridLayout")
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.pushButton = QtWidgets.QPushButton(TemperatureDispaly)
font = QtGui.QFont()
font.setPointSize(41)
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout_3.addWidget(self.pushButton)
self.TEMP = QtWidgets.QLineEdit(TemperatureDispaly)
font = QtGui.QFont()
font.setPointSize(44)
font.setBold(False)
self.TEMP.setFont(font)
self.TEMP.setObjectName("TEMP")
self.horizontalLayout_3.addWidget(self.TEMP)
spacerItem = QtWidgets.QSpacerItem(200, 100, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_3.addItem(spacerItem)
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.Average_label = QtWidgets.QLabel(TemperatureDispaly)
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(False)
font.setKerning(True)
self.Average_label.setFont(font)
self.Average_label.setAutoFillBackground(False)
self.Average_label.setObjectName("Average_label")
self.horizontalLayout.addWidget(self.Average_label)
self.Average_lineEdit = QtWidgets.QLineEdit(TemperatureDispaly)
font = QtGui.QFont()
font.setPointSize(17)
self.Average_lineEdit.setFont(font)
self.Average_lineEdit.setObjectName("Average_lineEdit")
self.horizontalLayout.addWidget(self.Average_lineEdit)
spacerItem1 = QtWidgets.QSpacerItem(150, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem1)
self.verticalLayout.addLayout(self.horizontalLayout)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.Fluctuate_label = QtWidgets.QLabel(TemperatureDispaly)
font = QtGui.QFont()
font.setPointSize(16)
self.Fluctuate_label.setFont(font)
self.Fluctuate_label.setObjectName("Fluctuate_label")
self.horizontalLayout_2.addWidget(self.Fluctuate_label)
self.Fluctuate_lineEdit = QtWidgets.QLineEdit(TemperatureDispaly)
font = QtGui.QFont()
font.setPointSize(17)
self.Fluctuate_lineEdit.setFont(font)
self.Fluctuate_lineEdit.setObjectName("Fluctuate_lineEdit")
self.horizontalLayout_2.addWidget(self.Fluctuate_lineEdit)
spacerItem2 = QtWidgets.QSpacerItem(150, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(spacerItem2)
self.verticalLayout.addLayout(self.horizontalLayout_2)
self.horizontalLayout_3.addLayout(self.verticalLayout)
self.verticalLayout_2.addLayout(self.horizontalLayout_3)
self.frame = QtWidgets.QFrame(TemperatureDispaly)
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.gridLayout_2 = QtWidgets.QGridLayout(self.frame)
self.gridLayout_2.setObjectName("gridLayout_2")
self.QgraphicsView = QChartView(self.frame)
self.QgraphicsView.setObjectName("QgraphicsView")
self.gridLayout_2.addWidget(self.QgraphicsView, 0, 0, 1, 1)
self.verticalLayout_2.addWidget(self.frame)
self.gridLayout.addLayout(self.verticalLayout_2, 0, 0, 1, 1)
self.retranslateUi(TemperatureDispaly)
self.pushButton.clicked.connect(TemperatureDispaly.close) # type: ignore
QtCore.QMetaObject.connectSlotsByName(TemperatureDispaly)
def retranslateUi(self, TemperatureDispaly):
_translate = QtCore.QCoreApplication.translate
TemperatureDispaly.setWindowTitle(_translate("TemperatureDispaly", "IKKEM-温度曲线"))
self.pushButton.setText(_translate("TemperatureDispaly", "退出"))
self.Average_label.setText(_translate("TemperatureDispaly", "3分钟温度均值"))
self.Fluctuate_label.setText(_translate("TemperatureDispaly", "3分钟温度波动"))
from PyQt5.QtChart import QChartView
编写逻辑代码如下:
#温度可视化展示
import sys, math, random
import numpy as np
import serial
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtChart import QChart, QLineSeries, QValueAxis,QChartView
from PyQt5 import QtGui, QtWidgets
from ui_widget import Ui_TemperatureDispaly
from PyQt5.QtGui import QPainter,QPen
from PyQt5.QtCore import Qt
from PyQt5.QtCore import QTimer
class QmyWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent) #调用父类构造函数,创建QWidget窗口
self.ui = Ui_TemperatureDispaly() # 创建UI对象
self.ui.setupUi(self) # 构造UI界面
self.timer = QTimer() # 初始化定时器
self.timer.timeout.connect(self.my_timer_cb)#将定时器连接到回调函数
self.chart = None # 图表
self.axisY = QValueAxis()
self.counter=0
self.createChart()#调用创建图标方法
self.timer.start(100)#定时器开始,400ms回调一次
self.ser = serial.Serial("/dev/ttyAMA0", 9600) # 打开串口,波特率9600
def createChart(self):
self.chart = QChart()
self.chart.legend().hide()
self.ui.QgraphicsView.setChart(self.chart)
self.ui.QgraphicsView.setRenderHint(QPainter.Antialiasing)
self.ui.QgraphicsView.setRubberBand(QChartView.RectangleRubberBand)
font1 = QtGui.QFont() # 创建字体对象font,用QFont类
font1.setPointSize(50) # 设置字体大小
font1.setBold(True) # 设置为粗体
self.ui.TEMP.setFont(font1)
self.ui.TEMP.setStyleSheet("color:blue")
self.ui.TEMP.setAlignment(Qt.AlignCenter)
self.ui.Average_lineEdit.setAlignment(Qt.AlignCenter)
self.ui.Fluctuate_lineEdit.setAlignment(Qt.AlignCenter)#居中对其
op = QtWidgets.QGraphicsOpacityEffect()
# 设置透明度的值,0.0到1.0,最小值0是透明,1是不透明
op.setOpacity(0)
self.ui.pushButton.setGraphicsEffect(op)#设置退出按钮透明
series = QLineSeries()
series.setUseOpenGL(True)
self.chart.addSeries(series)
pen = QPen(Qt.red)
pen.setStyle(Qt.SolidLine) # SolidLine, DashLine, DotLine, DashDotLine
pen.setWidth(2)
series.setPen(pen) # 序列的线条设置
font2 = QtGui.QFont() # 创建字体对象font,用QFont类
font2.setPointSize(11) # 设置字体大小
font2.setBold(True) # 设置为粗体
axisX = QValueAxis()
axisX.setRange(0, 3)
axisX.setLabelFormat("%.1f") # 标签格式
axisX.setLabelsFont(font2)
axisX.setTickCount(7) # 主分隔个数
axisX.setMinorTickCount(1)
axisX.setGridLineVisible(True)
axisX.setMinorGridLineVisible(True)
self.axisY.setLabelFormat("%.3f") # 标签格式
self.axisY.setLabelsFont(font2)
self.axisY.setTickCount(8)
self.axisY.setGridLineVisible(True)
self.axisY.setMinorGridLineVisible(False)
self.chart.addAxis(axisX, Qt.AlignBottom) # 坐标轴添加到图表,并指定方向
self.chart.addAxis(self.axisY, Qt.AlignLeft)
series.attachAxis(axisX) # 序列 series坐标轴
series.attachAxis(self.axisY)
def my_timer_cb(self, temp_average=None):
chart = self.ui.QgraphicsView.chart() # 获取chartView中的QChart对象
series = chart.series()[0] # 获取第1个序列,QLineSeries
received_data = self.ser.read() # 读取串口端口
data_left = self.ser.inWaiting() # 检查串口数据
received_data += self.ser.read(data_left)#将串口数据添加到变量里
if len(received_data)>9:#这里处理两个数据连接在一起的情况
re_data = int(received_data[-9:-1:1])
else:
re_data = int(received_data)
#标定后修改下一句代码
re_data = round((re_data * 4000 / 8388607-1000)/3.85, 4)#将AD值处理成温度
self.ui.TEMP.setText('%.4f' % re_data+"℃") #改变当前温度窗口数据
if self.counter < 3:
series.append(self.counter, re_data)
self.counter+=3/1800
else:
points = series.pointsVector()
for i in range(1800):
points[i].setY(points[i + 1].y())
points[-1].setY(re_data)
series.replace(points)
num=[]
p = series.pointsVector()
y_min = min(p, key=lambda point: point.y()).y()
y_max = max(p, key=lambda point: point.y()).y()
for i in range(len(p)):
num.append(p[i].y())
temp_average = np.average(num)
self.ui.Average_lineEdit.setText('%.4f' % temp_average)
self.ui.Fluctuate_lineEdit.setText('%.4f' % (y_max-y_min))
self.axisY.setRange(y_min, y_max)
if __name__ == "__main__": #用于当前窗体测试
app = QApplication(sys.argv) #创建GUI应用程序
form=QmyWidget() #创建窗体
form.showFullScreen() #全屏展示
form.show()
sys.exit(app.exec_())
实现功能:
文章来源:https://www.toymoban.com/news/detail-466985.html
文章来源地址https://www.toymoban.com/news/detail-466985.html
到了这里,关于温度采集数据可视化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!