PyQt5综合demo(QSerialPort QThread QWidget)

本系统通过PyQt5实现Fluke8845A仪表与LCC1设备的自动化测试,支持串口配置、电压输出、数据采集及CSV文件导出等功能,适用于自动化测试环境。
# !usr/bin/env python
# -*- coding:utf-8 -*-
import time, csv, sys
from PyQt5 import QtWidgets
from fluke8845A import Ui_MainWindow
from PyQt5.QtSerialPort import QSerialPort, QSerialPortInfo
from PyQt5.QtCore import QThread, pyqtSignal, QObject, QMutex
from PyQt5.QtWidgets import QMessageBox, QLCDNumber, QButtonGroup

# 全局变量
uart_name_list= list()
count = int(0)
uart_desc_list = list()

num_A = str(0)
num_B = str(0)

f = int(0)

mode = int(0)
cb_adc_mode = int(0)
cb_meter_mode = int(0)
lock1 = QMutex()
lock2 = QMutex()

data_dic = {
   
   'btn_count': 0, 'min_data': 0.0, 'max_data': 0.0,
			'volt_step': 0, 'time_dura': 0, 'dac_num': 0.0,
			'fp': 0, 'lcc1_num': 0, 'lcc1_flag': 1,
			'test_count': 0, 'adc': 0, 'meter': 0, 'fluke_num': 0,
			'channel': 0, 'read_count': 0}

# lcc1类
class write_work(QObject):
	lcc1_fluke_write = pyqtSignal()
	def __init__(self):
		super(write_work, self).__init__()
		self.run = True
		self.write_delay = 0.4

	def work(self):
		global data_dic
		while self.run:
			lock2.lock()
			self.lcc1_fluke_write.emit()
			time.sleep(float(self.write_delay))
			lock1.unlock()


# fluke8845A类
class read_work(QObject):
	lcc1_fluke_read = pyqtSignal()
	def __init__(self):
		super(read_work, self).__init__()
		self.run = True
		self.read_delay = 0.4

	def work(self):
		global data_dic
		while self.run:
			lock1.lock()
			self.lcc1_fluke_read.emit()
			time.sleep(float(self.read_delay))
			lock2.unlock()

# 主界面
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
	def __init__(self, parent = None):
		super(MainWindow, self).__init__(parent)
		self.setupUi(self)
		self.tab_uart()
		self.volt_display()
		self.my_write_thread = QThread()
		self.my_write_work = write_work()
		self.my_read_thread = QThread()
		self.my_read_work = read_work()
		self.four_checkbox_init()
		self.select_adc_meter()
		self.setSignalSlot()

	# 串口初始化
	def uart_init(self):
		global uart_name_list, uart_desc_list, count
		self.com1 = QSerialPort()
		self.com2 = QSerialPort()
		port_numb = QSerialPortInfo.availablePorts()
		for info in port_numb:
			if info.portName().count('COM', 0, len(info.portName())) != 0:
				uart_str_desc = info.description().split()
				# print("uart_str_desc= %s" % uart_str_desc)
				uart_str_name = info.portName().split()
				uart_name_list.append(uart_str_name[0])
				uart_desc_list.append(uart_str_desc[0])
				# print("uart_desc_list= %s" % uart_desc_list)
		else:
			# print("uart_desc_list = %s" % uart_desc_list)
			# print("uart_name_list = %s" % uart_name_list)
			count = str(uart_name_list).count('COM', 0, len(str(uart_name_list)))
			# print("count= %s" % count)
			if count > 256:
				QMessageBox.critical(self, '错误', '连接串口太多')
			else:
				self.fluke_com.clear()
				self.Lcc1_com.clear()
				for i in range(0, count):
					self.fluke_com.addItem(uart_name_list[i] + ' ' + uart_desc_list[i])
					self.Lcc1_com.addItem(uart_name_list[i] + ' ' + uart_desc_list[i])

	# 信号与槽
	def setSignalSlot(self):
		# 手动测试按键
		self.fluke_btn_open.clicked.connect(self.fluke_open_port)
		self.fluke_btn_close.clicked.connect(self.fluke_close_port)
		self.Lcc1_btn_open.clicked.connect(self.lcc1_open_port)
		self.Lcc1_btn_close.clicked.connect(self.lcc1_close_port)

		self.btn_dac_output.clicked.connect(self.transmit_A_volt)
		self.btn_dac_output.clicked.connect(self.meas_fluke_volt)

		self.btn_dac_output_2.clicked.connect(self.transmit_B_volt)
		self.btn_dac_output_2.clicked.connect(self.meas_fluke_volt)

		self.btn_dac_inc.clicked.connect(self.btn_A_inc)
		self.btn_dac_inc.clicked.connect(self.meas_fluke_volt)

		self.btn_dac_dec.clicked.connect(self.btn_A_dec)
		self.btn_dac_dec.clicked.connect(self.meas_fluke_volt)

		self.btn_dac_inc_2.clicked.connect(self.btn_B_inc)
		self.btn_dac_inc_2.clicked.connect(self.meas_fluke_volt)

		self.btn_dac_dec_2.clicked.connect(self.btn_B_dec)
		self.btn_dac_dec_2.clicked.connect(self.meas_fluke_volt)

		# 自动化测试按键
		self.btn_autotest_start.clicked.connect(self.autotest_start)

		# 自动化测试读写信号
		self.my_write_work.lcc1_fluke_write.connect(self.lcc1_fluke_write)
		self.my_read_work.lcc1_fluke_read.connect(self.lcc1_fluke_read)
		# 自动化thread
		self.my_write_work.moveToThread(self.my_write_thread)
		self.my_read_work.moveToThread(self.my_read_thread)
		self.my_write_thread.started.connect(self.my_write_work.work)
		self.my_read_thread.started.connect(self.my_read_work.work)
		# 关闭文件
		self.btn_autotest_stop.clicked.connect(self.stop_autotest)

	# fluke串口打开
	def fluke_open_port(self):
		global uart_desc_list, uart_name_list, count
		for i in range(0, count):
			if (uart_name_list[i] + ' ' + uart_desc_list[i]) == self.fluke_com.currentText():
				self.com1.setPortName(uart_name_list[i])
		self.com1.setBaudRate(QSerialPort.Baud115200)
		self.com1.setDataBits(QSerialPort.Data8)
		self.com1.setStopBits(QSerialPort.OneStop)
		self.com1.setParity(QSerialPort.NoParity)
		self.com1.open(QSerialPort.ReadWrite)
		if self.com1.isOpen():
			self.fluke_link_status.setText("已连接")
		else:
			QMessageBox.critical(self, '错误', '串口打开失败')
		tx_data = "SYST:REM\r"
		self.com1.write(tx_data.encode('ascii'))

	# fluke串口关闭
	def fluke_close_port(self):
		tx_data = "SYST:LOC\r"
		self.com1.write(tx_data.encode('ascii'))
		self.com1.close()
		self.fluke_link_status.setText("未连接")

	# lcc1串口打开
	def lcc1_open_port(self):
		global uart_desc_list, uart_name_list, count
		for i in range(0, count):
			if (uart_name_list[i] + ' ' + uart_desc_list[i]) == self.Lcc1_com.currentText():
				self.com2.setPortName(uart_name_list[i])
		self.com2.setBaudRate(QSerialPort.Baud115200)
		self.com2.setDataBits(QSerialPort.Data8)
		self.com2.setStopBits(QSerialPort.OneStop)
		self.com2.setParity(QSerialPort.NoParity)
		self.com2.open(QSerialPort.ReadWrite)
		if self.com2.isOpen():
			self.Lcc1_link_status.setText("已连接")
		else:
			QMessageBox.critical(self, '错误', '串口打开失败')

	# lcc1串口关闭
	def lcc1_close_port(self):
		self.com2.close()
		self.Lcc1_link_status.setText("未连接")

	# QTabWidget设置名称并初始化串口
	def tab_uart(self):
		self.tabWidget.setTabText(0, "Fluke")
		self.tabWidget.setTabText(1, "LCC1")
		self.uart_init()

	# A通道DAC值写入LCC1
	def transmit_A_volt(self):
		global num_A
		num_A = self.le_dac_A_Input.text()
		if len(num_A) == 0:
			QMessageBox.critical(self, '错误', '电压值不能为空')
		else:
			tx_data_A = 'SCA 1 %s\r' % num_A
			print(tx_data_A)
			self.com2.write(tx_data_A.encode('ascii'))

	def btn_A_inc(self):
		global num_A
		num = self.le_dac_A_Input.text()
		if len(num) == 0:
			QMessageBox.critical(self, '错误', '电压值不能为空')
		else:
			int_num = int(num)
			int_num += 1
			self.le_dac_A_Input.setText(str(int_num))
			self.transmit_A_volt()

	def btn_A_dec(self):
		global num_A
		num = self.le_dac_A_Input.text()
		if len(num) == 0:
			QMessageBox.critical(self, '错误', '电压值不能为空')
		else:
			int_num = int(num)
			int_num -= 1
			self.le_dac_A_Input.setText(str(int_num))
			self.transmit_A_volt()

	# B通道DAC值写入LCC1
	def transmit_B_volt(self):
		global num_B
		num_B = self.le_dac_B_Input.text()
		if len(num_B) == 0:
			QMessageBox.critical(self, '错误', '电压值不能为空')
		else:
			tx_data_B = 'SCA 2 %s\r' % num_B
			self.com2.write(tx_data_B.encode('ascii'))

	def btn_B_inc(self):
		global num_B
		num = self.le_dac_B_Input.text()
		if len(num) == 0:
			QMessageBox.critical(self, '错误', '电压值不能为空')
		else:
			int_num = int(num)
			int_num += 1
			self.le_dac_B_Input.setText(str(int_num))
			self.transmit_B_volt()

	def btn_B_dec(self):
		global num_B
		num = self.le_dac_B_Input.text()
		if len(num) == 0:
			QMessageBox.critical(self, '错误', '电压值不能为空')
		else:
			int_num = int(num)
			int_num -= 1
			self.le_dac_B_Input.setText(str(int_num))
			self.transmit_B_volt()

	# 读取LCC1返回的ADC电压值
	def receive_adc_volt(self):
		global data_dic
		rx_data = self.com2.readAll()
		if len(rx_data) == 0:
			print("no message\r\n")
		else:
			data = (float(rx_data) * 1000.0)
			self.adc_volt_show.display(data)

	# LCD初始化
	def volt_display(self):
		self.adc_volt_show.setDigitCount(8)
		self.adc_volt_show.setMode
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值