0

I'm implementing a GUI with PyQt5 and PyCharm IDE for one of my systems which communicates through a serial interface. When I send an appropriate command, the system starts a data stream with packets defined like the following:

| 0x01 | 0x00 | 0x00 | 0x02 | [...32 bytes...] | 0x03 |

The first, the fourth, and the last byte are just markers, the second and the third are control bytes, and the remaining 32 bytes are the information.

When I start the stream, the system receives the command but the GUI freezes. So I started to debug watching the variable which store the incoming values.

The simplified code is

def main():
app = QtGui.QApplication(sys.argv)

main = MainWindow()
main.show()
# app.connect(notifier, SIGNAL('activated(int)'), Update)

timer = QtCore.QTimer()
timer.timeout.connect(main.Update)
timer.start(2)

app.exec_()

def Update(self):
    if self.read == True:
        self.datain = self.SerPort.Take()
        # if self.datain == None:
        #     pass
        # else:
        self.dataList = list(self.datain)
        self.disp_chan_1.setText('%f' % (self.dataList[0] * 0.000535434481))
        self.disp_chan_2.setText('%f' % (self.dataList[1] * 0.000535694653))
        self.disp_chan_3.setText('%f' % (self.dataList[2] * 0.000537407175))
        self.disp_chan_4.setText('%f' % (self.dataList[3] * 0.000534853598))
        self.disp_chan_5.setText('%f' % (self.dataList[4] * 0.000536425262))
        self.disp_chan_6.setText('%f' % (self.dataList[5] * 0.000536408834))
        self.disp_chan_7.setText('%f' % (self.dataList[6] * 0.000536337893))
        self.disp_chan_8.setText('%f' % (self.dataList[7] * 0.000536237792))
    else:
        pass

def Take(self):
    rxtemp1 = self.ser.read(4)
    rxData = self.ser.read(32)
    rxtemp2 = self.ser.read(1)
    value = struct.unpack('f'*4, rxData)
    return value

and the output of the debugger for these variables is

rxData = {bytes}b'\xf2\xa4\xe7=\xc0Y\xc4=\xdc\x15\xdc=\xae\xf2\xed=\x9ai;>\xff\xc3\xfe=\xab\x0e\x13>\xebd:A'
rxtemp1 = {bytes}b'\x01\x00\x00\x02'
rxtemp2 = {bytes}b'\x03'

It shows that the rxtemp1 and rxtemp2 variables are correct (they collect the markers and the control bytes) and so the rxData variable which collects the information seems to be correct.

But the GUI freezes immediately and I have to kill the process.

What is causing this error?

SeeDerekEngineer
  • 770
  • 2
  • 6
  • 22
thoraz
  • 209
  • 1
  • 3
  • 14
  • Copy and past the debugger output. A screenshot is undesirable but certainly better than a picture of your physical screen. – Jonathon Reinhart Jul 28 '17 at 12:50
  • Do the same problems occur when running code *outside* of the IDE/debugger (i.e. in a console or command window)? – ekhumoro Jul 28 '17 at 13:11
  • @JonathonReinhart I changed the image with code – thoraz Jul 28 '17 at 13:15
  • Probably you are blocking waiting for data from the serial interface. I would try asynchronous I/O - sorry for not being more specific but it is hard to reproduce your setup in order to write a proper answer. Check out https://stackoverflow.com/questions/17553543/pyserial-non-blocking-read-loop – Paulo Scardine Jul 28 '17 at 13:27
  • @ekhumoro Yes. If I run the application it freezes. For this reason I'm using the debugger. – thoraz Jul 28 '17 at 13:34
  • 1
    I found the error. Thanks to @ekhumoro for making me think to launch the application in the console. PyCharm was set without output message and so I didn't see the error output. Mea culpa. – thoraz Jul 28 '17 at 13:39

1 Answers1

1

I found the solution. The application freeze because this line

value = struct.unpack('f'*4, rxData)

In rxData there are 32 bytes but the unpack command above wants 4 group of 4 bytes, 16 in all. The correct command is

value = struct.unpack('f'*8, rxData)

I haven't see the the output message error because my PyCharm was set wrong.

thoraz
  • 209
  • 1
  • 3
  • 14