The essence of the problem: When you send a string of bytes through the serial port, 1 byte is lost. Moreover, ser.write(msg) leaves the correct line '\xff\xff\x00\x00' , and only 3 bytes of '\xff\x00\x00' are already accepted.
Detailed description of the problem: I am writing an application (Client) on PyQt5 that communicates through the virtual Com2Com bridge with the real device emulator (Server) written by me. The client starts a stream that listens to the Serial port. The server also listens to the Serial port over the bridge. Let's skip the data exchange protocol, everything works, but at a certain moment, after pressing the button in the Client, a request is sent to the Server to issue an image, it looks like this ':G\r' . The server parses the incoming command and sends the resolution of the future image in the format ':g1024&768\r' . The parsed image is parsed, the number of bytes that will need to be calculated to build the image is calculated (each pixel is in grayscale format, that is, this number is from 0 to 255), I will take the simplest - 2 x 2 pixels (therefore, 4 bytes must be obtained). After that, the Client sends the command ':F\r' Server and translates from the abstract command reading mode com_mode = 0 to the image com_mode = 1 mode com_mode = 1 - listens to the port until it com_mode = 1 required number of bytes. Here is the code:
if com_mode: try: byte = self.ser.read() print [byte] img_str += byte if len(img_str) >= 1: print len(img_str) self.img_loading.emit(len(img_str)) if len(img_str) == img_prbar: com_mode = 0 self.img_rcvd.emit() except serialutil.SerialException: self.com_conn_err_signal.emit('Error. Cant read IMAGE from serial port.') Signal img_loading for progress img_loading , do not pay attention to it. But then - compare the length of the received message with the required. If all the bytes have arrived, we transfer the stream to the command acceptance mode and generate a signal. So, when the Server receives the command ':F\r' it generates and sends the string byte:
def img_sender(self): global img_resp img_resp = True img_str = b'' img_b_num = w_img * h_img for i in range(img_b_num): if i < img_b_num / 2: img_str += pack('B', 255) else: img_str += pack('B', 0) self.comPortListenerThread.send(img_str) When transferring to the port, I display the values in the console:
def send(self, msg): global img_resp if com_conn and not img_resp: self.ser.write(msg + '\r') elif com_conn and img_resp: print len(msg) print [msg] self.ser.write(msg) img_resp = False so, these same
print len(msg) print [msg] issue the following:
4 ['\xff\xff\x00\x00'] everything is good - 2 white pixels, 2 black, however, in the Client, some kind of devilry happens. print [byte] and print len(img_str) from the first piece of code display the following:
['\xff'] 1 ['\x00'] 2 ['\x00'] 3 And everything, silent, progress bar shows 75%! If you press the button again, the ':F\r' command is sent again, to which the Server responds with the same ':g2&2\r' and in img_str added : which, in consequence, is translated to the number 58 :
[':'] 4 [[255 0] [ 0 58]] What to do - I can not imagine where the byte goes? How to deal with it? Moreover, if, when generating an image, to make a margin of 1 extra byte, then all the way ... how is that?