0

I am trying to create a pyqtgraph that updates real time based on the values it receives from a pyserial connection. Currently I have two files: one that reads data from a pyserial connection and emits a signal when two values have changed, and a second file that interprets the signal and displays the two changed values. For some reason the values that are read from the pyserial connection are not being emitted to the second file. Pushing the start QPushButton starts the thread. I referenced this post but I can't figure out why there is an issue with the signal so any advice would be appreciated. Thanks ahead of time!

Here is the first file:

class PortCommunication(QThread):

    # Define signal for thread communication
    data_changed = pyqtSignal(float, float)

    def run(self):
        try:
            # Define port settings
            with serial.Serial(
                port = "COM4",
            baudrate = 9600,
            bytesize = 8,
            parity = serial.PARITY_NONE,
            stopbits = 1,
            timeout = 1,
                ) as self.ser:

                count = 0
                # test only 10 iterations 
                while count < 10:           
                    count += 1
      
                    self.ser.write(b"ADC0\r\n")

                    # Get device output (should be ['#,#,#'])
                    output = self.ser.read(size=20)
                    decoded_output = (output.decode('utf-8'))

                    # Turn the decoded_output from string to list
                    final_list = decoded_output.strip().split(',')
                   
                    # Torque is the first number in the ['#', '#', '#']
                    torque = float(final_list[0])
                    speed = float(final_list[1])
                    
                    # Emit torque and speed signal
                    #print(torque, speed)        
                    self.data_changed.emit(torque, speed)
                    time.sleep(3)
                    
        except serial.serialutil.SerialException:
            print("Couldn't open port.")

Here is the second file:

class MainWidget(QtGui.QWidget):

    def __init__ (self):                   
        super(MainWidget, self).__init__()       
        self.initializeSpace()
        
    def initializeSpace(self):        
        # Create and define buttons that will control the thread
        self.start = QtGui.QPushButton("Start")
        self.start.clicked.connect(self.startEvent)
        self.stop = QtGui.QPushButton("Stop")

        # Create Layout
        self.layout = QtGui.QGridLayout()
       
        # Add widgets to layout
        self.layout.addWidget(self.start, 0, 0)
        self.layout.addWidget(self.stop, 1, 0)

        # Set layout
        self.setLayout(self.layout)

    def startEvent(self):
        # Create a thread
        self.thread = PortCommunication()
        self.thread.start()
        # Connect signals & slots 
        self.thread.data_changed.connect(self.display_data)

    def display_data(self, torque, speed):
        print(torque, speed)
    
  • what is the output of `print(x_list, y_list, torque, speed)`? – eyllanesc Jul 22 '21 at 19:28
  • @eyllanesc the function `update_plot` isn't being processed for some reason. I doesn't return anything. Is this because the thread is continuous? – Gillian Grace Jul 22 '21 at 20:47
  • The problem is that you should not create 2 signals but only one that contains the data of both, change to: 1) add `data_changed = pyqtSignal(float, float)` 2) add `self.data_changed.emit(torque, speed)` and 3) add `self.thread.data_changed.connect(self.update_plot)` and 4) remove everything about `torque_changed` and `speed_changed` – eyllanesc Jul 22 '21 at 21:09
  • @eyllanesc Thank you for all of your advice. I tried containing both of a data values; however, the plot is still not plotting the points. I think this has something to do with the signal or how its being processed because even when I put a simple `QMessageBox.information(self, "Started!", "The thread has started.")` under `update_plot` and connect it to `startEvent` whenever I click the start button nothing happens. Do you have any idea what might be causing this? – Gillian Grace Jul 22 '21 at 21:34
  • @eyllanesc I created a breakpoint at `self.thread.start()` and I got a `NameError("name 'signalStatus' is not defined")` error. – Gillian Grace Jul 23 '21 at 15:19
  • I don't see that in the code you provide, are you sure that the code you provide is the same as you use? – eyllanesc Jul 23 '21 at 15:49
  • @eyllanesc the only changes I made were based on your suggestions up above. – Gillian Grace Jul 23 '21 at 16:17
  • Nowhere have I indicated that you use "signalStatus", probably your code before my comments already had that problem but when I made my corrections it became noticeable. Correct your real code, if you want help then provide a real [MRE]. Bye. – eyllanesc Jul 23 '21 at 16:20
  • I agree that this would need a minimal reproducible example. Also, the title is quite specific. Once you have a minimal example, we would not care this is for an RS232 connection. – Javier Gonzalez Jul 23 '21 at 16:32
  • one thing I thought, but then I thought "it can't be..." was to switch the order of starting the thread and making the connection. If there was an example I would have tried that myself before saying anything. – Javier Gonzalez Jul 23 '21 at 16:34
  • @JavierGonzalez Unfortunately, I get the same error when I switch the order. I will try to create a minimal reproducible example. – Gillian Grace Jul 23 '21 at 17:18

0 Answers0