手把手制作温湿度上位机(串口通信) 超详细代码 可远程部署

成品:

零基础制作串口工具RS485通讯接口 数码管温湿度 串口开发

main.py

# -*- coding: utf-8 -*-

import sys
import threading
import time
import PyQt5.QtWidgets as qw
import PyQt5.QtCore as qc
import serial.tools.list_ports

import uart_toolsUI
from tool import Tool

class myMainWindow(qw.QMainWindow,uart_toolsUI.Ui_MainWindow):
signal_recv_data = qc.pyqtSignal(str)

def __init__(self):
super().__init__()
self.k=1
self.setupUi(self)
self.temp_data="01 04 00 01 00 02"
self.port = ''
self.baud = 0
# 设置状态信息
self.statusbar.showMessage("SYBH")
# 加载配置文件
self.settings = qc.QSettings("config.ini", qc.QSettings.IniFormat)
self.settings.setIniCodec("UTF-8")


self.comboBox_uart.currentIndexChanged.connect(self.comboBox_uart_cb)
self.comboBox_baud.currentIndexChanged.connect(self.comboBox_baud_cb)


# self.comboBox_type.currentIndexChanged.connect(self.comboBox_type_cb)

self.btn_send.clicked.connect(self.btn_send_cb)
self.btn_stop.clicked.connect(self.stop)
self.btn_baud_set.clicked.connect(self.btn_baud_set_cb)
self.btn_send_address.clicked.connect(self.btn_send_address_cb)

self.lcdNumber_Temperature.setDecMode()
self.lcdNumber_Temperature.setSegmentStyle(self.lcdNumber_Temperature.Flat)

self.lcdNumber_humidity.setDecMode()
self.lcdNumber_humidity.setSegmentStyle(self.lcdNumber_Temperature.Flat)

# 识别串口
ls = list(serial.tools.list_ports.comports())
print(ls)
if len(ls) > 0:
for i in range(len(ls)):
self.comboBox_uart.addItem(ls[i][0])


self.serial_k = threading.Thread(target=self.kk, daemon=True)
self.serial_k.start()

def mudbus_crc_16(self,string):
# 从16进制数组转化为字节数组
data = bytearray.fromhex(string)
crc = 0xFFFF
for pos in data:
crc ^= pos
for i in range(8):
if ((crc & 1) != 0):
crc >>= 1
crc ^= 0xA001
else:
crc >>= 1
s = hex(((crc & 0xff) << 8) + (crc >> 8))[2:]
while len(s) < 4:
s = "0" + s
return string + s

def btn_baud_set_cb(self):
try:
baud = int(self.comboBox_baud.currentText())//100
baud =str(hex(baud))[2:]
while len(baud) <4:
baud="0"+baud

s = serial.Serial(self.port, self.baud, 8, 'N', 1)

temp_send = self.address + ' 06 00 01 ' +baud


print(temp_send)

# temp_send = l[i] + l[j] + "01 04 00 01 00 02"
temp_send = self.mudbus_crc_16(temp_send)
print(temp_send)
temp_send = bytes.fromhex(temp_send)

print(temp_send)

s.write(temp_send)
time.sleep(0.1)
buffer_data = s.in_waiting
print(buffer_data)
if buffer_data:
return_data = s.read(buffer_data)

# print('返回的数据2进制:', return_data)
# 二进制转换为16进制:010304010802307b79
return_data_hex = str(return_data.hex())
print('返回的数据转换为16进制:', return_data_hex)
self.baud = self.comboBox_baud.currentText()
print(self.baud)
else:
print("波特率修改失败")


except:
print("波特率修改失败")

def kk(self):
while 1:
if self.k == -1:

self.tool.uart.send_uart_data(self.address+" 04 00 01 00 02")
time.sleep(1)

def btn_send_cb(self):
self.k = self.k * -1
if self.k ==-1:
self.tool = Tool(self)

def stop(self):


try:
ls = [ 9600, 19200,38400, 57600, 115200, 128000]
l = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"]
# l = ["0", "1"]
k = 0
for h in ls:

try:

print((self.port, h, 8, 'N', 1))
self.serial = serial.Serial(self.port, h, 8, 'N', 1)
print("open serial success.")
time.sleep(0.1)
self.baud = h
# self.comboBox_baud.setCurrentText(h)


except:
print("open serial error!")


for i in range(len(l)):
for j in range(len(l)):
temp_send = l[i]+l[j]+" 04 00 00 00 01"
# temp_send = l[i] + l[j] + "01 04 00 01 00 02"
temp_send=self.mudbus_crc_16(temp_send)
print(temp_send)
temp_send = bytes.fromhex(temp_send)

print(temp_send)

self.serial.write(temp_send)
time.sleep(0.1)
buffer_data = self.serial.in_waiting
print(buffer_data)
if buffer_data:
self.temp_data = l[i]+l[j]+" 04 00 01 00 02"
self.address = l[i]+l[j]

self.textEdit_adress.setPlainText(l[i]+l[j])


return_data = self.serial.read(buffer_data)
return_data_hex = str(return_data.hex())
self.textEdit_type.setPlainText(return_data_hex[6:10])
self.comboBox_baud.setCurrentText(str(h))
k=1
break
if k ==1:
break
if k ==1:

break
except:
print("错误")

self.tool = Tool(self)

def btn_send_address_cb(self):
#
a = self.textEdit_adress.toPlainText()
while len(a) <4:
a = "0"+a
s = serial.Serial(self.port, self.baud, 8, 'N', 1)

temp_send = self.address + ' 06 00 00 ' +a

# temp_send = '01 04 00 01 00 01'
print(temp_send)

# temp_send = l[i] + l[j] + "01 04 00 01 00 02"
temp_send = self.mudbus_crc_16(temp_send)
print(temp_send)
temp_send = bytes.fromhex(temp_send)

print(temp_send)

s.write(temp_send)
time.sleep(0.1)
buffer_data = s.in_waiting
print(buffer_data)
if buffer_data:
return_data = s.read(buffer_data)

# print('返回的数据2进制:', return_data)
# 二进制转换为16进制:010304010802307b79
return_data_hex = str(return_data.hex())
print('返回的数据转换为16进制:', return_data_hex)
self.address = self.textEdit_adress.toPlainText()
# time.sleep(3)
else:
print("地址修改失败")

def comboBox_uart_cb(self):
self.port = self.comboBox_uart.currentText()
print(self.port)

def comboBox_baud_cb(self):
pass


def comboBox_address_cb(self):
pass

if __name__ == "__main__":
app = qw.QApplication(sys.argv)
w=myMainWindow()
w.show()
sys.exit(app.exec_())

tool.py

import sys
import threading
from time import sleep
from uart import Uart

class Tool(object):
def __init__(self,parent):
self.err = 0
self.parent = parent
print(122222222)
self.uart = Uart(self.parent.port,self.parent.baud)
self.start_listen_uart()

def start_listen_uart(self):
threading.Thread(target=self.listen_uart_data_thread,daemon=True).start()

def listen_uart_data_thread(self):
print("listen_uart_data_thread")
while(True):
# print("listening...")
# sleep(1)
if not self.uart.is_queue_recv_empty():
recv_data = self.uart.get_queue_recv()
self.parent.signal_recv_data.emit(recv_data[0])
self.parent.lcdNumber_Temperature.display(recv_data[1])
self.parent.lcdNumber_humidity.display(recv_data[2])

uart.py

import sys
import serial
import threading
from time import sleep
import queue

class Uart(object):
def __init__(self, port, baud):
self.err = 0
self.queue_recv = queue.Queue(10)
try:
self.serial = serial.Serial(port, baud, 8, 'N', 1)
print("open serial success.")

except:
print("open serial error!")
self.err = -1

# self.start_recv_thread()

def Close(self):
self.serial.close()
#接收线程
def uart_recv_threa(self):
print("start uart_recv_thread")

while(1):
try:

print(self.serial.in_waiting)
recv_data_raw = self.serial.readline()
data= "DEVICE--->PC "+ recv_data_raw.decode()
print(data)
print(123)
except:
print("接收失败")
break
def start_recv_thread(self):
thread = threading.Thread(target=self.uart_recv_threa,daemon=True)
thread.start()

def mudbus_crc_16(self,string):
# 从16进制数组转化为字节数组
data = bytearray.fromhex(string)
crc = 0xFFFF
for pos in data:
crc ^= pos
for i in range(8):
if ((crc & 1) != 0):
crc >>= 1
crc ^= 0xA001
else:
crc >>= 1
return string + hex(((crc & 0xff) << 8) + (crc >> 8))[2:]
#发送数据
def send_uart_data(self,data):
# temp_send = '01 04 00 01 00 02 20 0b'

temp_send=data
print(data)
print(type(data))
temp_send = self.mudbus_crc_16(temp_send)

temp_send = bytes.fromhex(temp_send)

print(temp_send)

self.serial.write(temp_send)
sleep(0.5)

buffer_data = self.serial.in_waiting
print(buffer_data)
if buffer_data:
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
return_data = self.serial.read(buffer_data)

# print('返回的数据2进制:', return_data)
# 二进制转换为16进制:010304010802307b79
return_data_hex = str(return_data.hex())
print('返回的数据转换为16进制:', return_data_hex)
# 对返回的数据进行解析,获取温度和湿度数据
print("当前温度为:", int(return_data_hex[6:10], 16) / 10)
print("当前湿度为:", int(return_data_hex[10:14], 16) / 10)
if self.queue_recv.full():
self.queue_recv.get()
self.queue_recv.put(["当前温度为:"+str(int(return_data_hex[6:10], 16) / 10)+"°C"+"\n"+
"当前湿度为:"+str(int(return_data_hex[10:14], 16) / 10)+"%"+"\n"+
return_data_hex+"\n",int(return_data_hex[6:10], 16) / 10,int(return_data_hex[10:14], 16) / 10])



#关闭串口
def uart_close(self):
self.serial.close()

def is_queue_recv_empty(self):
return self.queue_recv.empty()

def get_queue_recv(self):
return self.queue_recv.get()

#
# if __name__ == "__main__":
# myuart = Uart('/dev/tty.usbserial-130', 9600)
#
# if (0==myuart.err):
# print("Init uart Success")
#
# #如果打开成功,启动接收线程,准备实时接收数据
# # myuart.start_recv_thread()
#
#
# while(True):
# input_data = input("Please input data...")
#
#
# if (input_data == "quit"):
# myuart.uart_close()
# break
# else:
# #发送数据给设备
# print("数据已发送")
# myuart.send_uart_data(input_data)
# sleep(1)



# print("结束")#
 

uart_tools.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'uart_tools.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# 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_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(722, 255)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget)
self.groupBox_2.setGeometry(QtCore.QRect(10, 10, 241, 151))
self.groupBox_2.setObjectName("groupBox_2")
self.label_4 = QtWidgets.QLabel(self.groupBox_2)
self.label_4.setGeometry(QtCore.QRect(30, 30, 31, 16))
self.label_4.setObjectName("label_4")
self.comboBox_uart = QtWidgets.QComboBox(self.groupBox_2)
self.comboBox_uart.setGeometry(QtCore.QRect(80, 30, 104, 26))
self.comboBox_uart.setObjectName("comboBox_uart")
self.label_5 = QtWidgets.QLabel(self.groupBox_2)
self.label_5.setGeometry(QtCore.QRect(20, 60, 41, 16))
self.label_5.setObjectName("label_5")
self.comboBox_baud = QtWidgets.QComboBox(self.groupBox_2)
self.comboBox_baud.setGeometry(QtCore.QRect(80, 60, 104, 26))
self.comboBox_baud.setObjectName("comboBox_baud")
self.comboBox_baud.addItem("")
self.comboBox_baud.addItem("")
self.comboBox_baud.addItem("")
self.comboBox_baud.addItem("")
self.comboBox_baud.addItem("")
self.comboBox_baud.addItem("")
self.comboBox_baud.addItem("")
self.comboBox_baud.addItem("")
self.comboBox_baud.addItem("")
self.comboBox_baud.addItem("")
self.btn_send_address = QtWidgets.QPushButton(self.groupBox_2)
self.btn_send_address.setGeometry(QtCore.QRect(180, 90, 51, 21))
self.btn_send_address.setObjectName("btn_send_address")
self.textEdit_adress = QtWidgets.QTextEdit(self.groupBox_2)
self.textEdit_adress.setGeometry(QtCore.QRect(80, 90, 101, 21))
self.textEdit_adress.setObjectName("textEdit_adress")
self.label_6 = QtWidgets.QLabel(self.groupBox_2)
self.label_6.setGeometry(QtCore.QRect(30, 90, 41, 16))
self.label_6.setObjectName("label_6")
self.textEdit_type = QtWidgets.QTextEdit(self.groupBox_2)
self.textEdit_type.setGeometry(QtCore.QRect(80, 120, 101, 21))
self.textEdit_type.setObjectName("textEdit_type")
self.label_7 = QtWidgets.QLabel(self.groupBox_2)
self.label_7.setGeometry(QtCore.QRect(10, 120, 61, 20))
self.label_7.setObjectName("label_7")
self.lcdNumber_Temperature = QtWidgets.QLCDNumber(self.centralwidget)
self.lcdNumber_Temperature.setGeometry(QtCore.QRect(330, 50, 111, 61))
self.lcdNumber_Temperature.setObjectName("lcdNumber_Temperature")
self.lcdNumber_humidity = QtWidgets.QLCDNumber(self.centralwidget)
self.lcdNumber_humidity.setGeometry(QtCore.QRect(560, 50, 111, 61))
self.lcdNumber_humidity.setObjectName("lcdNumber_humidity")
self.label_10 = QtWidgets.QLabel(self.centralwidget)
self.label_10.setGeometry(QtCore.QRect(260, 60, 71, 51))
self.label_10.setObjectName("label_10")
self.label_11 = QtWidgets.QLabel(self.centralwidget)
self.label_11.setGeometry(QtCore.QRect(440, 60, 71, 51))
self.label_11.setObjectName("label_11")
self.label_12 = QtWidgets.QLabel(self.centralwidget)
self.label_12.setGeometry(QtCore.QRect(500, 60, 71, 51))
self.label_12.setObjectName("label_12")
self.label_13 = QtWidgets.QLabel(self.centralwidget)
self.label_13.setGeometry(QtCore.QRect(680, 60, 71, 51))
self.label_13.setObjectName("label_13")
self.btn_send = QtWidgets.QPushButton(self.centralwidget)
self.btn_send.setGeometry(QtCore.QRect(490, 140, 101, 41))
self.btn_send.setObjectName("btn_send")
self.btn_baud_set = QtWidgets.QPushButton(self.centralwidget)
self.btn_baud_set.setGeometry(QtCore.QRect(190, 70, 51, 21))
self.btn_baud_set.setObjectName("btn_baud_set")
self.btn_stop = QtWidgets.QPushButton(self.centralwidget)
self.btn_stop.setGeometry(QtCore.QRect(360, 140, 111, 41))
self.btn_stop.setObjectName("btn_stop")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 722, 24))
self.menubar.setObjectName("menubar")
self.menu = QtWidgets.QMenu(self.menubar)
self.menu.setObjectName("menu")
self.menu_2 = QtWidgets.QMenu(self.menubar)
self.menu_2.setObjectName("menu_2")
self.menu_3 = QtWidgets.QMenu(self.menubar)
self.menu_3.setObjectName("menu_3")
self.menu_4 = QtWidgets.QMenu(self.menubar)
self.menu_4.setObjectName("menu_4")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setObjectName("toolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.action_start = QtWidgets.QAction(MainWindow)
self.action_start.setObjectName("action_start")
self.action_pause = QtWidgets.QAction(MainWindow)
self.action_pause.setObjectName("action_pause")
self.action_stop = QtWidgets.QAction(MainWindow)
self.action_stop.setObjectName("action_stop")
self.action_clean = QtWidgets.QAction(MainWindow)
self.action_clean.setObjectName("action_clean")
self.menu.addAction(self.action_start)
self.menu.addAction(self.action_pause)
self.menu.addAction(self.action_stop)
self.menu.addAction(self.action_clean)
self.menubar.addAction(self.menu.menuAction())
self.menubar.addAction(self.menu_2.menuAction())
self.menubar.addAction(self.menu_3.menuAction())
self.menubar.addAction(self.menu_4.menuAction())
self.toolBar.addAction(self.action_start)
self.toolBar.addAction(self.action_pause)
self.toolBar.addAction(self.action_stop)
self.toolBar.addAction(self.action_clean)

self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)

def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.groupBox_2.setTitle(_translate("MainWindow", "串口设置"))
self.label_4.setText(_translate("MainWindow", "串口"))
self.label_5.setText(_translate("MainWindow", "波特率"))
self.comboBox_baud.setItemText(0, _translate("MainWindow", "2400"))
self.comboBox_baud.setItemText(1, _translate("MainWindow", "4800"))
self.comboBox_baud.setItemText(2, _translate("MainWindow", "9600"))
self.comboBox_baud.setItemText(3, _translate("MainWindow", "19200"))
self.comboBox_baud.setItemText(4, _translate("MainWindow", "38400"))
self.comboBox_baud.setItemText(5, _translate("MainWindow", "57600"))
self.comboBox_baud.setItemText(6, _translate("MainWindow", "115200"))
self.comboBox_baud.setItemText(7, _translate("MainWindow", "128000"))
self.comboBox_baud.setItemText(8, _translate("MainWindow", "256000"))
self.comboBox_baud.setItemText(9, _translate("MainWindow", "921600"))
self.btn_send_address.setText(_translate("MainWindow", "修改"))
self.label_6.setText(_translate("MainWindow", "地址"))
self.label_7.setText(_translate("MainWindow", "设备类型"))
self.label_10.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-size:18pt;\">🌡️温度:</span></p></body></html>"))
self.label_11.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-size:36pt;\">°C</span></p></body></html>"))
self.label_12.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-size:24pt;\">湿度:</span></p></body></html>"))
self.label_13.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-size:36pt;\">%</span></p></body></html>"))
self.btn_send.setText(_translate("MainWindow", "开始/停止"))
self.btn_baud_set.setText(_translate("MainWindow", "修改"))
self.btn_stop.setText(_translate("MainWindow", "搜索配置"))
self.menu.setTitle(_translate("MainWindow", "编辑"))
self.menu_2.setTitle(_translate("MainWindow", "显示"))
self.menu_3.setTitle(_translate("MainWindow", "工具"))
self.menu_4.setTitle(_translate("MainWindow", "帮助"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
self.action_start.setText(_translate("MainWindow", "开始"))
self.action_start.setShortcut(_translate("MainWindow", "F1"))
self.action_pause.setText(_translate("MainWindow", "暂停"))
self.action_pause.setShortcut(_translate("MainWindow", "F2"))
self.action_stop.setText(_translate("MainWindow", "停止"))
self.action_stop.setToolTip(_translate("MainWindow", "stop"))
self.action_stop.setShortcut(_translate("MainWindow", "F3"))
self.action_clean.setText(_translate("MainWindow", "清除"))
self.action_clean.setToolTip(_translate("MainWindow", "clean"))
self.action_clean.setShortcut(_translate("MainWindow", "F4"))

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-22 16:18:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-22 16:18:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-22 16:18:01       87 阅读
  4. Python语言-面向对象

    2024-03-22 16:18:01       96 阅读

热门阅读

  1. 解决okhttp无法调用HTTP协议的接口问题

    2024-03-22 16:18:01       48 阅读
  2. 子矩阵(十四届蓝桥杯python组A)

    2024-03-22 16:18:01       39 阅读
  3. 【LeetCode-22.括号生成】

    2024-03-22 16:18:01       44 阅读
  4. L1-5 不变初心数分数 15

    2024-03-22 16:18:01       44 阅读
  5. 从政府工作报告探计算机行业发展

    2024-03-22 16:18:01       47 阅读
  6. 【leetcode热题】颠倒二进制位

    2024-03-22 16:18:01       46 阅读
  7. Unity构建详解(1)——SBP介绍

    2024-03-22 16:18:01       46 阅读
  8. unity自动引用生成

    2024-03-22 16:18:01       45 阅读
  9. ChatGPT:如何利用人工智能写出高质量论文

    2024-03-22 16:18:01       42 阅读
  10. LeetCode刷题——347. 前 K 个高频元素

    2024-03-22 16:18:01       45 阅读