发新帖本帖赏金 3.00元(功能说明)我要提问
1234
返回列表
打印

【一起玩】用python34+qt4实现串口,想玩上位机的快来,首发

[复制链接]
楼主: nixianmin
手机看帖
扫描二维码
随时随地手机跟帖
61
nixianmin|  楼主 | 2017-2-24 11:55 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
YDCMAN 发表于 2017-2-20 16:00
红字部分是改动过的,仅供学习参考

你在linux下用?我在window下玩的,现在加了串口号的搜索,不再是直接填串口号了


有空可以交流,我的qq:1755116896,备注写下

使用特权

评论回复
62
YDCMAN| | 2017-3-2 09:12 | 只看该作者
nixianmin 发表于 2017-2-24 11:55
你在linux下用?我在window下玩的,现在加了串口号的搜索,不再是直接填串口号了

赞一个!
我也是在windows下测试的,python2.7.9

使用特权

评论回复
63
大舌头| | 2017-5-4 08:29 | 只看该作者
改了PyQt5

# -*- coding: utf-8 -*-
__author__ = 'nixianmin'
__name__ = '__main__'


from PyQt5 import QtCore, QtGui, QtWidgets
#from PyQt5.QtWidgets import QDialog, QApplication, QMainWindow
from matplotlib.figure import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import numpy as np
import re

import sys, struct, sci_tool, serial, time, threading
import serial
import serial.tools.list_ports


#数据位
SERIAL_DATABIT_ARRAY = (serial.EIGHTBITS, serial.SEVENBITS, serial.SIXBITS, serial.FIVEBITS)
#停止位
SERIAL_STOPBIT_ARRAY = (serial.STOPBITS_ONE, serial.STOPBITS_ONE_POINT_FIVE, serial.STOPBITS_TWO)
#校验位
SERIAL_CHECKBIT_ARRAY = (serial.PARITY_NONE, serial.PARITY_EVEN, serial.PARITY_ODD , serial.PARITY_MARK, serial.PARITY_SPACE)

#matplot画图类
class MplCanvas(FigureCanvas):
    def __init__(self):
        self.fig = Figure()
        self.ax = self.fig.add_subplot(111)
        self.fig.subplots_adjust(left=0.06, right=0.99, top=0.9, bottom=0.1)
        FigureCanvas.__init__(self, self.fig)
        FigureCanvas.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)
        self.databuflimit = 500
        self.line1, = self.ax.plot([],[],color = 'blue')
        self.plotdatabuf =[]
        self.ax.grid()
        self.ax.hold(False)

    def matplot_updatabuf(self, newdata):
        if len(self.plotdatabuf) >= self.databuflimit:
            del self.plotdatabuf[0]
            try:
                self.plotdatabuf[self.databuflimit] = newdata
            except:
                self.plotdatabuf.append(newdata)
        else:
            self.plotdatabuf.append(newdata)

class Sci_UiCtl(sci_tool.Ui_MainWindow):
    def __init__(self,MainWindow):
        super(sci_tool.Ui_MainWindow, self).__init__()
        self.__index = 0
        self.setupUi(MainWindow)#display sci tool menu

        self.portstatus_flag = False#端口使能标志
        self._serial = serial.Serial()#init serial class
        
        #@QtCore.pyqtSlot(int)
        #self.connect(self.OpenButton,SIGNAL("clicked()"),self.OpenSerial)
        #self.OpenButton.clicked.connect(lambda: self.OpenSerial())

        #将按键单击操作和对应的函数关联起来,这个是Qt里的写法
        self.sciopenButton.clicked.connect(lambda:self.SciOpenButton_Click())#self.sciopenButton, QtCore.SIGNAL('clicked()'), self.SciOpenButton_Click)#connect button click func
        self.clrcontentbutton.clicked.connect(lambda:self.ClrButtonProcess())#self.clrcontentbutton, QtCore.SIGNAL('clicked()'), self.ClrButtonProcess)
        self.mainsend_Button.clicked.connect(lambda:self.MainSendButtonProcess())#self.mainsend_Button, QtCore.SIGNAL('clicked()'), self.MainSendButtonProcess)
        self.sendclr_Button.clicked.connect(lambda:self.ClrSendButtonProcess())#self.sendclr_Button, QtCore.SIGNAL('clicked()'), self.ClrSendButtonProcess)
        self.clrcntbutton.clicked.connect(lambda: self.ClrCntButtonProcess())#self.clrcntbutton, QtCore.SIGNAL('clicked()'), self.ClrCntButtonProcess )
        self.cmd1sned_Button.clicked.connect(lambda:self.Cmd1SendButtonProcess())#self.cmd1sned_Button, QtCore.SIGNAL('clicked()'), self.Cmd1SendButtonProcess)
        self.cmd2sned_Button.clicked.connect(lambda: self.Cmd2SendButtonProcess())#self.cmd2sned_Button, QtCore.SIGNAL('clicked()'), self.Cmd2SendButtonProcess)
        self.cmd3sned_Button.clicked.connect(lambda:self.Cmd3SendButtonProcess())#self.cmd3sned_Button, QtCore.SIGNAL('clicked()'), self.Cmd3SendButtonProcess)
        self.cmd4sned_Button.clicked.connect(lambda:self.Cmd4SendButtonProcess())#self.cmd4sned_Button, QtCore.SIGNAL('clicked()'), self.Cmd4SendButtonProcess)
        self.cmd5sned_Button.clicked.connect(lambda:self.Cmd5SendButtonProcess())#self.cmd5sned_Button, QtCore.SIGNAL('clicked()'), self.Cmd5SendButtonProcess)
        self.savecontentbutton.clicked.connect(lambda:self.SaveRecButtonProcess())#self.savecontentbutton, QtCore.SIGNAL('clicked()'), self.SaveRecButtonProcess)
        self.x1save_button.clicked.connect(lambda:self.X1SaveButtonProcess())#self.x1save_button, QtCore.SIGNAL('clicked()'), self.X1SaveButtonProcess)
        self.x1clr_button.clicked.connect(lambda:self.X1ClrButtonProcess())#self.x1clr_button,  QtCore.SIGNAL('clicked()'), self.X1ClrButtonProcess)
        self.x2save_button.clicked.connect(lambda:self.X2SaveButtonProcess())#self.x2save_button, QtCore.SIGNAL('clicked()'), self.X2SaveButtonProcess)
        self.x2clr_button.clicked.connect(lambda:self.X2ClrButtonProcess())#self.x2clr_button,  QtCore.SIGNAL('clicked()'), self.X2ClrButtonProcess)
        self.x3save_button.clicked.connect(lambda:self.X3SaveButtonProcess())#self.x3save_button, QtCore.SIGNAL('clicked()'), self.X3SaveButtonProcess)
        self.x3clr_button.clicked.connect(lambda:self.X3ClrButtonProcess())#self.x3clr_button,  QtCore.SIGNAL('clicked()'), self.X3ClrButtonProcess)
        self.plotnum_Slider.valueChanged.connect(self.PlotNumValueChange)

        #用来实现波形的显示,画图
        self.matplot = MplCanvas()
        self.debug_matplot_layout.addWidget(self.matplot)
        self.matplot.databuflimit = self.plotnum_Slider.value()#得到plot的初始化最大值


        self.recstr = str#串口接收字符串
        self.recdatacnt = 0#数据接收计数
        self.senddatacnt = 0#数据发送是计数

        #用定时器每个一定时间去扫描有没数据收到,只要在打开串口才开始即使
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.SciReadData)
        self.portcomtext.addItems(self.Port_List())
        
     #获取COM号列表  
    def Port_List(self):   
        Com_List=[]
        port_list = list(serial.tools.list_ports.comports())
        for port in port_list:
            Com_List.append(port[0])
        return Com_List

    #打开串口操作
    def SciOpenButton_Click(self):
         clickstatus = self.sciopenButton.isChecked()
         if clickstatus:
                #得到串口的设置参数
            #comread = int(self.portcomtext.currentText())
            bandrate = int(self.baudratecombo.currentText())
            databit = SERIAL_DATABIT_ARRAY[self.databitcombo.currentIndex()]
            stopbit = SERIAL_STOPBIT_ARRAY[self.stopbitcombo.currentIndex()]
            checkbit = SERIAL_CHECKBIT_ARRAY[self.checkbitcombo.currentIndex()]

            #打开串口
            try:
                self._serial = serial.Serial(self.portcomtext.currentText())
                self._serial.baudrate = bandrate
                self._serial.bytesize = databit
                self._serial.parity = checkbit
                self._serial.stopbits = stopbit
            except (OSError, serial.SerialException):
                QtGui.QMessageBox.warning(None, '端口警告',"端口无效或者不存在", QtGui.QMessageBox.Ok)

            if self._serial.isOpen():#打开串口后失效一些可以设置的窗口
                self.timer.start(30)#30ms刷新一次界面
                self.sciopenButton.setText("关闭")
                self.baudratecombo.setEnabled(False)
                self.checkbitcombo.setEnabled(False)
                self.databitcombo.setEnabled(False)
                self.stopbitcombo.setEnabled(False)
                self.portcomtext.setEnabled(False)
                self.portstatus_flag = True
                self.SciOpenDebugDataMenuDeal()
            else:
                self.sciopenButton.setChecked(False)
         else:#关闭串口这使能各个窗口
            self._serial.close()
            self.timer.stop()
            self.sciopenButton.setText("打开")
            self.baudratecombo.setEnabled(True)
            self.stopbitcombo.setEnabled(True)
            self.databitcombo.setEnabled(True)
            self.checkbitcombo.setEnabled(True)
            self.portcomtext.setEnabled(True)
            self.portstatus_flag = False
            self.SciCloseDebugDataMenuDeal()

    #对填写的数据做判断,看是否有问题
    def SciOpenDebugDataMenuDeal(self):
        if self.x1_checkBox.isChecked() == True:
            try:
                self.x1_low = float(self.x1_low_line.text())
                self.x1_high = float(self.x1_high_line.text())
                if self.x1_low > self.x1_high:
                     QtGui.QMessageBox.warning(None, '错误',"X1填写数据出错", QtGui.QMessageBox.Ok)
                     self.x1_checkBox.setChecked(False)
            except :
                 QtGui.QMessageBox.warning(None, '错误',"X1填写数据出错", QtGui.QMessageBox.Ok)
                 self.x1_checkBox.setChecked(False)

        if self.x2_checkBox.isChecked() == True:
            try:
                self.x2_low = float(self.x2_low_line.text())
                self.x2_high = float(self.x2_high_line.text())
                if self.x2_low > self.x2_high:
                     QtGui.QMessageBox.warning(None, '错误',"X2填写数据出错", QtGui.QMessageBox.Ok)
                     self.x2_checkBox.setChecked(False)
            except :
                 QtGui.QMessageBox.warning(None, '错误',"X2填写数据出错", QtGui.QMessageBox.Ok)
                 self.x2_checkBox.setChecked(False)

        if self.x3_checkBox.isChecked() == True:
            try:
                self.x3_low = float(self.x3_low_line.text())
                self.x3_high = float(self.x3_high_line.text())
                if self.x3_low > self.x3_high:
                     QtGui.QMessageBox.warning(None, '错误',"X3填写数据出错", QtGui.QMessageBox.Ok)
                     self.x3_checkBox.setChecked(False)
            except :
                 QtGui.QMessageBox.warning(None, '错误',"X3填写数据出错", QtGui.QMessageBox.Ok)
                 self.x3_checkBox.setChecked(False)

        self.x1_checkBox.setEnabled(False)
        self.x1_low_line.setEnabled(False)
        self.x1_high_line.setEnabled(False)
        self.x2_checkBox.setEnabled(False)
        self.x2_low_line.setEnabled(False)
        self.x2_high_line.setEnabled(False)
        self.x3_checkBox.setEnabled(False)
        self.x3_low_line.setEnabled(False)
        self.x3_high_line.setEnabled(False)

    def SciCloseDebugDataMenuDeal(self):
        self.x1_checkBox.setEnabled(True)
        self.x1_low_line.setEnabled(True)
        self.x1_high_line.setEnabled(True)
        self.x2_checkBox.setEnabled(True)
        self.x2_low_line.setEnabled(True)
        self.x2_high_line.setEnabled(True)
        self.x3_checkBox.setEnabled(True)
        self.x3_low_line.setEnabled(True)
        self.x3_high_line.setEnabled(True)



    def ClrButtonProcess(self):#接收窗口清楚数据
        if self.distext.currentIndex() == 0:
            self.dishex.clear()
        elif self.distext.currentIndex() == 1:
            self.distring.clear()
        else:
            self.disprotocol.clear()

    def ClrSendButtonProcess(self):#清除发送窗口数据
        self.mainsend_Edit.clear()
        self.cmd1_Edit.clear()
        self.cmd2_Edit.clear()
        self.cmd3_Edit.clear()
        self.cmd4_Edit.clear()
        self.cmd5_Edit.clear()

    def ClrCntButtonProcess(self):#清计算窗口
        self.senddatacnt = 0
        self.recdatacnt = 0
        self.sendnum_lineEdit.setText(str(self.senddatacnt))
        self.recnumlineEdit.setText(str(self.recdatacnt))

    def HexShow(self,strargv):#转换陈十六进制格式显示
        restr = ''
        slen = len(strargv)
        for i in range(slen):
            restr += hex(strargv[i])+' '
        return restr

    def SerialSend(self,sdata):
        try:
            self.senddatacnt += self._serial.write(sdata)
        except:
             QtGui.QMessageBox.warning(None, 'Error',"数据格式错误", QtGui.QMessageBox.Ok)

        self.sendnum_lineEdit.setText(str(self.senddatacnt))


    def MainSendButtonProcess(self):
        if self.portstatus_flag == True:
            if self.char_radioButton.isChecked():
                self.SerialSend(self.mainsend_Edit.toPlainText().encode())
            else:
                sendstr = self.mainsend_Edit.toPlainText()
                try:
                    self.SerialSend(bytearray.fromhex( sendstr.replace('0x','')))
                except:
                    QtGui.QMessageBox.warning(None, 'Error',"数据格式错误", QtGui.QMessageBox.Ok)


    def Cmd1SendButtonProcess(self):
        if self.portstatus_flag == True:
            sendstr = self.cmd1_Edit.text()
            try:
                self.SerialSend(bytearray.fromhex( sendstr.replace('0x','')))
            except:
                QtGui.QMessageBox.warning(None, 'Error',"数据格式错误", QtGui.QMessageBox.Ok)

    def Cmd2SendButtonProcess(self):
        if self.portstatus_flag == True:
            sendstr = self.cmd2_Edit.text()
            try:
                self.SerialSend(bytearray.fromhex( sendstr.replace('0x','')))
            except:
                QtGui.QMessageBox.warning(None, 'Error',"数据格式错误", QtGui.QMessageBox.Ok)

    def Cmd3SendButtonProcess(self):
        if self.portstatus_flag == True:
            sendstr = self.cmd3_Edit.text()
            try:
                self.SerialSend(bytearray.fromhex( sendstr.replace('0x','')))
            except:
                QtGui.QMessageBox.warning(None, 'Error',"数据格式错误", QtGui.QMessageBox.Ok)

    def Cmd4SendButtonProcess(self):
        if self.portstatus_flag == True:
            sendstr = self.cmd4_Edit.text()
            try:
                self.SerialSend(bytearray.fromhex( sendstr.replace('0x','')))
            except:
                QtGui.QMessageBox.warning(None, 'Error',"数据格式错误", QtGui.QMessageBox.Ok)

    def Cmd5SendButtonProcess(self):
        if self.portstatus_flag == True:
            sendstr = self.cmd5_Edit.text()
            try:
                self.SerialSend(bytearray.fromhex( sendstr.replace('0x','')))
            except:
                QtGui.QMessageBox.warning(None, 'Error',"数据格式错误", QtGui.QMessageBox.Ok)

    def SaveRecButtonProcess(self):
        filename = QtGui.QFileDialog.getSaveFileName(self.savecontentbutton, 'Save File', '.',"Text file(*.txt);;All file(*.*)")
        fname = open(filename, 'w')
        if self.distext.currentIndex() == 0:
            fname.write(self.dishex.toPlainText())
        elif self.distext.currentIndex() == 1:
            fname.write(self.distring.toPlainText())
        elif  self.distext.currentIndex() == 2:
             fname.write(self.disprotocol.toPlainText())

        fname.close()

    #思想数据的区分
    def DebugDataSelecDeal(self, p_str):
        rec_array = re.split('\n|,| |\r',p_str)#将数据按各种符号去分隔,得到需要的数据
        for num in rec_array:
            try:
                readdigital = float(num)
            except:
                continue

            if self.x1_checkBox.isChecked() == True:
                if readdigital >= self.x1_low and readdigital < self.x1_high:
                    self.x1_plainTextEdit.appendPlainText(str(round(readdigital, 7)))

                    if self.x1_plainTextEdit.toPlainText().__len__() > 10000:
                        self.x1_plainTextEdit.clear()

                    if self.x1selec_radio.isChecked() == True:
                        self.matplot.matplot_updatabuf(readdigital)

            if self.x2_checkBox.isChecked() == True:
                if readdigital >= self.x2_low and readdigital < self.x2_high:
                    self.x2_plainTextEdit.appendPlainText(str(round(readdigital, 7)))

                    if self.x2_plainTextEdit.toPlainText().__len__() > 10000:
                        self.x2_plainTextEdit.clear()

                    if self.x2selec_radio.isChecked() == True:
                      self.matplot.matplot_updatabuf(readdigital)


            if self.x3_checkBox.isChecked() == True:
                if readdigital >= self.x3_low and readdigital < self.x3_high:
                    self.x3_plainTextEdit.appendPlainText(str(round(readdigital, 7)))

                    if self.x3_plainTextEdit.toPlainText().__len__() > 10000:
                        self.x3_plainTextEdit.clear()

                    if self.x3selec_radio.isChecked() == True:
                        self.matplot.matplot_updatabuf(readdigital)

        #判断是否刷新画图区域
        if self.x1selec_radio.isChecked() == True or self.x2selec_radio.isChecked() == True or self.x3selec_radio.isChecked() == True:
            self.Multiplot_Refresh()

    def X1ClrButtonProcess(self):
        self.x1_plainTextEdit.clear()

    def X1SaveButtonProcess(self):
        filename = QtGui.QFileDialog.getSaveFileName(self.x1save_button, 'Save File', '.',"Text file(*.txt);;All file(*.*)")
        fname = open(filename, 'w')
        fname.write(self.x1_plainTextEdit.toPlainText())
        fname.close()

    def X2ClrButtonProcess(self):
        self.x2_plainTextEdit.clear()

    def X2SaveButtonProcess(self):
        filename = QtGui.QFileDialog.getSaveFileName(self.x2save_button, 'Save File', '.',"Text file(*.txt);;All file(*.*)")
        fname = open(filename, 'w')
        fname.write(self.x2_plainTextEdit.toPlainText())
        fname.close()

    def X3ClrButtonProcess(self):
        self.x3_plainTextEdit.clear()

    def X3SaveButtonProcess(self):
        filename = QtGui.QFileDialog.getSaveFileName(self.x3save_button, 'Save File', '.',"Text file(*.txt);;All file(*.*)")
        fname = open(filename, 'w')
        fname.write(self.x3_plainTextEdit.toPlainText())
        fname.close()

    def HexMatplotDisplay(self,p_str):
        for num in p_str:
            self.matplot.matplot_updatabuf(num)
        self.Multiplot_Refresh()

    def Multiplot_Refresh(self):
        if len(self.matplot.plotdatabuf) < self.matplot.databuflimit:
            self.matplot.line1.set_xdata(np.arange(len(self.matplot.plotdatabuf)))
            self.matplot.line1.set_ydata(self.matplot.plotdatabuf)
        else:
            self.matplot.line1.set_xdata(np.arange(self.matplot.databuflimit))
            self.matplot.line1.set_ydata(self.matplot.plotdatabuf[:self.matplot.databuflimit])
        #更新数据后去刷新matplot界面
        self.matplot.ax.relim()
        self.matplot.ax.autoscale_view()
        self.matplot.draw()

    def PlotNumValueChange(self):
        self.plotnum_lineEdit.setText(str(self.plotnum_Slider.value()))
        self.matplot.databuflimit = self.plotnum_Slider.value()

    ###############################################
    #数据接收
    def SciReadData(self):#deal sci data
        if self.portstatus_flag == True:
            try:
                bytesToRead = self._serial.inWaiting()#读取缓冲区有多少数据
            except:
                self.sciopenButton.setChecked(False)#出现异常,则关闭串口
                self.SciOpenButton_Click()
                bytesToRead = 0

            if bytesToRead > 0:#大于0 ,则取出数据
                self.recstr = self._serial.read(bytesToRead)#读取串口数据
                self.recdatacnt += bytesToRead
                self.recnumlineEdit.setText(str(self.recdatacnt))
                self.SciWinReFresh()#根据选择,来判断数据在那个窗口刷新

使用特权

评论回复
64
大舌头| | 2017-5-4 08:30 | 只看该作者
    def SciWinReFresh(self):
        if self.distext.currentIndex() == 0:
            self.dishex.appendPlainText(self.HexShow(self.recstr))#把数据按十六进制显示
            if self.hexselec_radio.isChecked() == True:
                self.HexMatplotDisplay(self.recstr)

            if self.dishex.toPlainText().__len__() > 100000:
                self.dishex.clear()
        elif self.distext.currentIndex() == 1:
            self.distring.appendPlainText(self.recstr.decode("utf-8"))
            if self.x1_checkBox.isChecked() == True or self.x2_checkBox.isChecked() == True or self.x2_checkBox.isChecked() == True:
                self.DebugDataSelecDeal(self.recstr.decode("utf-8"))

            if self.distring.toPlainText().__len__() > 20000:
                self.distring.clear()
        else:
            pass



if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Sci_UiCtl(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
####接上贴

##改了串口在系统中自动查找,并列表选择

使用特权

评论回复
评论
liuna111 2018-6-29 10:15 回复TA
您改了后觉得有错误么 P_str 那里很疑惑 
65
大舌头| | 2017-5-4 08:33 | 只看该作者
编译环境 Python3.53+PyQt5+Eric6

pip list
cycler (0.10.0)
gl (0.2.36)
matplotlib (2.0.1)
numpy (1.12.1)
pip (9.0.1)
py2exe (0.9.2.2)
pyinstall (0.1.4)
pyparsing (2.2.0)
pyqtgraph (0.10.0)
pyserial (3.3)
python-dateutil (2.6.0)
pytz (2017.2)
QScintilla (2.10)
setuptools (28.8.0)
sip (4.19.2)
six (1.10.0)

使用特权

评论回复
66
大舌头| | 2017-5-4 09:00 | 只看该作者
        #将按键单击操作和对应的函数关联起来,这个是Qt里的写法
        self.sciopenButton.clicked.connect(lambda:self.SciOpenButton_Click())#self.sciopenButton, QtCore.SIGNAL('clicked()'), self.SciOpenButton_Click)#connect button click func

这里也改了

使用特权

评论回复
67
YDCMAN| | 2017-5-23 14:43 | 只看该作者
,赞一个!

使用特权

评论回复
68
wg88719| | 2017-6-8 22:56 | 只看该作者
大舌头 发表于 2017-5-4 09:00
#将按键单击操作和对应的函数关联起来,这个是Qt里的写法
        self.sciopenButton.clicked.con ...

舌头哥。 我在21ic论坛上看到您修改了pyqt的串口GUI到PYQT5的版本,请问是否可以把源文件发给小弟一份?
我刚刚开始学这个,自己建的工程,有蛮多错误。想参考一下。
具体应该是需要您改好的:
sci_main.py
sci_tool.py
还有 setup.py

多谢啦

使用特权

评论回复
69
苏山人家| | 2017-6-12 08:05 | 只看该作者
python是个好东西。我现在写上位机全部都是python还有一些平时用的脚本。

使用特权

评论回复
70
conepoint| | 2017-9-2 03:46 | 只看该作者
感谢楼主分享的菩萨精神,阿弥陀佛。

使用特权

评论回复
71
liuna111| | 2018-6-6 21:40 | 只看该作者
你好 我现在也在用pyqt5做上位机 也用到了串口 要实时显示波形,还要实现上位机对下位机的控制,该怎么做

使用特权

评论回复
72
liuna111| | 2018-6-6 21:42 | 只看该作者
你好 我现在也在用pyqt5做上位机 也用到了串口 要实时显示波形,还要实现上位机对下位机的控制,该怎么做

使用特权

评论回复
评论
nixianmin 2018-7-2 07:53 回复TA
@liuna111 :socket只是网络通讯的一部分,你用socket可以研究twisted,还有你需要自己定义自己的通讯怎么解析 
liuna111 2018-6-20 19:58 回复TA
@liuna111 :您好 通信协议看socket模块可以么 现在只能找到关于socket的网络通信的资料 您有什么要推荐的关于通信协议的资料么 谢谢 做毕设,已经焦头烂额了 
liuna111 2018-6-13 15:53 回复TA
@nixianmin :好的 谢谢 
nixianmin 2018-6-12 14:05 回复TA
串口调通了,做通讯协议,显示波形可以用matplot库,或者其他库 
73
110xia| | 2019-8-14 15:52 | 只看该作者
hao hao xue xi

使用特权

评论回复
74
wcf88123310| | 2019-9-12 10:22 | 只看该作者

使用特权

评论回复
发新帖 本帖赏金 3.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则