在Python中如何从线程打开串行端口

2024-07-05 14:34:16 发布

您现在位置:Python中文网/ 问答频道 /正文

几个星期以来,我一直在思考如何从线程打开串行COM端口, 能够从另一个线程写入/读取它。在我的示例中,当我从另一个线程写入端口时,存在拒绝访问的情况。 当我从主GUI打开端口时,它工作得很好,我可以从线程中编写它,但我需要给用户选择COM编号的可能性。 这是我的代码,如果有人能帮我看看,那就太好了。。。在

class Connect(QThread): 
    connectResult = QtCore.pyqtSignal(str)  
    position1 = QtCore.pyqtSignal(str)
    actuPosResult = QtCore.pyqtSignal(str)
    def __init__(self, myvar, parent=None):
        QThread.__init__(self, parent)
        self.myvar = str(myvar) # value from spinbox
    def run(self):
        self.pserial = serial.Serial()
        try:
            COMnumber= self.myvar
            self.pserial = serial.Serial('COM'+COMnumber, 115200,timeout=None)
            r='COM '+COMnumber+' connected.'
            self.pserial.write("c".encode('ascii')+"\n".encode('ascii'))  
            incomingByte = self.pserial.read()
            decodedByte = incomingByte.decode("utf-8")
            if decodedByte == ('c'):
                r='Atmega On-Line'
                self.connectResult.emit(r)
                pos1='---'
                self.position1.emit(pos1)
            else :
                r='   No answer from Atmega.'
                self.connectResult.emit(r)
    def stop(self):
        self.terminate()
class ReadingEncoder(QThread):  
    actuPosResult = QtCore.pyqtSignal(str) 
    def __init__(self, mojazmienna, parent=None):
        QThread.__init__(self, parent)
        self.mojazmienna = str(mojazmienna)
    def run(self):
    Try:
          self.pserial = serial.Serial()
          self.pserial = serial.Serial('COM3', 115200,timeout=1)
           self.pserial.write("p".encode('ascii')+"\n".encode('ascii')) 
            incomingByte = self.pserial.read()
            decodedByte = incomingByte.decode("utf-8")
            actualPos = ''
         if decodedByte == ('a'):        
                while decodedByte != ('\n'):
                    incomingByte = self.pserial.read()
                  decodedByte = incomingByte.decode("utf-8")
                  actualPos = actualPos + decodedByte
                 pos= actualPos.rstrip('\n')# pozycja w formacie string
                 print(pos)
             self.actuPosResult.emit(pos)
        except (EOFError, OSError, IOError, ValueError, RuntimeError, BrokenPipeError, InterruptedError, TimeoutError): 
            print('Thread  readingEncoder error')
        self.pserial.close()

Tags: selfcominitdefserial线程parentstr
2条回答

你只需打开串行端口并启动线程。在

import atexit

class SerialPort(QThread):
    connectResult = QtCore.pyqtSignal(str)  
    position1 = QtCore.pyqtSignal(str)
    actuPosResult = QtCore.pyqtSignal(str)

    def __init__(self, port=None, baud=115200, timeout=1):
        super().__init__()

        self.ser = serial.Serial()
        self.ser.port = port
        self.ser.baudrate = baud
        self.ser.timeout = timeout
        self.running = False
        atexit.register(self.ser.close) # Make sure the serial port closes when you quit the program.

    def set_port(port_num):
        self.ser.port = "COM"+str(port_num)

    def start(self, *args, **kwargs):
        self.running = True
        self.ser.open()
        super().start()
        self.ser.write("c\n".encode("ascii"))

    def run(self):
        while self.running:
            try:
                incomingByte = self.ser.read()
                decodedByte = incomingByte.decode("utf-8")
                if decodedByte == ('c'):
                    r='Atmega On-Line'
                    self.connectResult.emit(r)
                    pos1=' -'
                    self.position1.emit(pos1)
                else:
                    r='   No answer from Atmega.'
                    self.connectResult.emit(r)
            except:
                pass
            # time.sleep(0.01) # You may want to sleep or use readline

通过让一个按钮调用start方法来使用这个类。在

^{pr2}$

通常只能打开一个串行端口一次,除非您知道您的两个端口都可用。在

串行端口存在于主线程上,并且一直存在。您不需要连续打开和关闭串行端口。所有的阅读都发生在线程中。要写只需调用serial.write(b"c\n")。你不应该让写作发生在线程中。在

要让用户选择com端口,只需使用QLineEdit。在

myserial = QtGui.QLineEdit("3")
myserial.textChanged.connect(serial.set_port)

你试图打开端口多次。在

而不是这样做,你有几个选择

  • 创建一个Serial对象,并将其传递给必须使用它的线程。在
  • 提供要使用的串行端口的名称,并让它打开该端口。在

在这两种情况下,请确保线程在退出时正确关闭端口!在

相关问题 更多 >