readyRead signal not activating while using QSerialProt
-
wrote on 26 Feb 2025, 09:35 last edited by
Hello. I have this program here:
import sys from time import sleep from PySide6 import QtSerialPort as qts from PySide6 import QtCore as qtc class Serial_Port(): def __init__(self): self.port = qts.QSerialPort() self.port.setBaudRate(qts.QSerialPort.Baud38400) self.port.readyRead.connect(self.on_receive) self.port.errorOccurred.connect(self.on_error) qtc.QTimer.singleShot(0, self.program) def program(self): print(self.con_discon()) order = [0x86, 0x01] for o in order: self.send(o.to_bytes()) sleep(0.001) print("fin") def con_discon(self): if self.port.isOpen(): self.port.close() return False else: for port in qts.QSerialPortInfo.availablePorts(): if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433': self.port.setPort(port) break return self.port.open(qtc.QIODeviceBase.ReadWrite) def send(self, data): print("send: ", data) self.port.write(data) def on_receive(self): print('!') print("message: ", self.port.read(2)) def on_error(self, error): print("Serial port error:") print(error.name) exit() def main(): if not qtc.QCoreApplication.instance(): app = qtc.QCoreApplication(sys.argv) else: app = qtc.QCoreApplication.instance() Serial_Port() app.exec() if __name__ == '__main__': main()
It's supposed to send 0x86 and then 0x01 through serial port and get an answer from a device. I know the device is working correctly, because the answer is showing up with Termite and, interestingly, when I run this program without an event loop, which looks like this:
import sys from time import sleep from PySide6 import QtSerialPort as qts from PySide6 import QtCore as qtc class Serial_Port(): def __init__(self): self.port = qts.QSerialPort() self.port.setBaudRate(qts.QSerialPort.Baud38400) self.port.readyRead.connect(self.on_receive) self.port.errorOccurred.connect(self.on_error) def program(self): print(self.con_discon()) order = [0x86, 0x01] for o in order: self.send(o.to_bytes()) sleep(0.001) self.port.waitForReadyRead() print("fin") def con_discon(self): if self.port.isOpen(): self.port.close() return False else: for port in qts.QSerialPortInfo.availablePorts(): if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433': self.port.setPort(port) break return self.port.open(qtc.QIODeviceBase.ReadWrite) def send(self, data): print("send: ", data) self.port.write(data) def on_receive(self): print('!') print("message: ", self.port.read(2)) def on_error(self, error): print("Serial port error:") print(error.name) exit() def main(): sp = Serial_Port() sp.program() if __name__ == '__main__': main()
I don't know why it doesn't work nor why only without the event loop. With the event loop, after sending the data, it just does nothing. Please help.
-
Hello. I have this program here:
import sys from time import sleep from PySide6 import QtSerialPort as qts from PySide6 import QtCore as qtc class Serial_Port(): def __init__(self): self.port = qts.QSerialPort() self.port.setBaudRate(qts.QSerialPort.Baud38400) self.port.readyRead.connect(self.on_receive) self.port.errorOccurred.connect(self.on_error) qtc.QTimer.singleShot(0, self.program) def program(self): print(self.con_discon()) order = [0x86, 0x01] for o in order: self.send(o.to_bytes()) sleep(0.001) print("fin") def con_discon(self): if self.port.isOpen(): self.port.close() return False else: for port in qts.QSerialPortInfo.availablePorts(): if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433': self.port.setPort(port) break return self.port.open(qtc.QIODeviceBase.ReadWrite) def send(self, data): print("send: ", data) self.port.write(data) def on_receive(self): print('!') print("message: ", self.port.read(2)) def on_error(self, error): print("Serial port error:") print(error.name) exit() def main(): if not qtc.QCoreApplication.instance(): app = qtc.QCoreApplication(sys.argv) else: app = qtc.QCoreApplication.instance() Serial_Port() app.exec() if __name__ == '__main__': main()
It's supposed to send 0x86 and then 0x01 through serial port and get an answer from a device. I know the device is working correctly, because the answer is showing up with Termite and, interestingly, when I run this program without an event loop, which looks like this:
import sys from time import sleep from PySide6 import QtSerialPort as qts from PySide6 import QtCore as qtc class Serial_Port(): def __init__(self): self.port = qts.QSerialPort() self.port.setBaudRate(qts.QSerialPort.Baud38400) self.port.readyRead.connect(self.on_receive) self.port.errorOccurred.connect(self.on_error) def program(self): print(self.con_discon()) order = [0x86, 0x01] for o in order: self.send(o.to_bytes()) sleep(0.001) self.port.waitForReadyRead() print("fin") def con_discon(self): if self.port.isOpen(): self.port.close() return False else: for port in qts.QSerialPortInfo.availablePorts(): if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433': self.port.setPort(port) break return self.port.open(qtc.QIODeviceBase.ReadWrite) def send(self, data): print("send: ", data) self.port.write(data) def on_receive(self): print('!') print("message: ", self.port.read(2)) def on_error(self, error): print("Serial port error:") print(error.name) exit() def main(): sp = Serial_Port() sp.program() if __name__ == '__main__': main()
I don't know why it doesn't work nor why only without the event loop. With the event loop, after sending the data, it just does nothing. Please help.
wrote on 26 Feb 2025, 10:13 last edited by@Adar70
Maybe you are doing the above (mostly) in your first code, I looked initially at your second.Meanwhile, I am worried about your Python lifetime of the instance you create in first code via plain
Serial_Port()
call. You do not assign return result to any variable. If I am not mistaken, won't the createdSerial_Port
instance be destroyed immediately after return fromSerial_Port.__init__()
? Not certain whether theqtc.QTimer.singleShot(0, self.program)
will keep it alive. Even if it does, it may die before the reply bytes are received, at least with nowaitFor...()
. Verify if that is the case, do something to keep theSerial_Port
instance around? -
Hello. I have this program here:
import sys from time import sleep from PySide6 import QtSerialPort as qts from PySide6 import QtCore as qtc class Serial_Port(): def __init__(self): self.port = qts.QSerialPort() self.port.setBaudRate(qts.QSerialPort.Baud38400) self.port.readyRead.connect(self.on_receive) self.port.errorOccurred.connect(self.on_error) qtc.QTimer.singleShot(0, self.program) def program(self): print(self.con_discon()) order = [0x86, 0x01] for o in order: self.send(o.to_bytes()) sleep(0.001) print("fin") def con_discon(self): if self.port.isOpen(): self.port.close() return False else: for port in qts.QSerialPortInfo.availablePorts(): if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433': self.port.setPort(port) break return self.port.open(qtc.QIODeviceBase.ReadWrite) def send(self, data): print("send: ", data) self.port.write(data) def on_receive(self): print('!') print("message: ", self.port.read(2)) def on_error(self, error): print("Serial port error:") print(error.name) exit() def main(): if not qtc.QCoreApplication.instance(): app = qtc.QCoreApplication(sys.argv) else: app = qtc.QCoreApplication.instance() Serial_Port() app.exec() if __name__ == '__main__': main()
It's supposed to send 0x86 and then 0x01 through serial port and get an answer from a device. I know the device is working correctly, because the answer is showing up with Termite and, interestingly, when I run this program without an event loop, which looks like this:
import sys from time import sleep from PySide6 import QtSerialPort as qts from PySide6 import QtCore as qtc class Serial_Port(): def __init__(self): self.port = qts.QSerialPort() self.port.setBaudRate(qts.QSerialPort.Baud38400) self.port.readyRead.connect(self.on_receive) self.port.errorOccurred.connect(self.on_error) def program(self): print(self.con_discon()) order = [0x86, 0x01] for o in order: self.send(o.to_bytes()) sleep(0.001) self.port.waitForReadyRead() print("fin") def con_discon(self): if self.port.isOpen(): self.port.close() return False else: for port in qts.QSerialPortInfo.availablePorts(): if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433': self.port.setPort(port) break return self.port.open(qtc.QIODeviceBase.ReadWrite) def send(self, data): print("send: ", data) self.port.write(data) def on_receive(self): print('!') print("message: ", self.port.read(2)) def on_error(self, error): print("Serial port error:") print(error.name) exit() def main(): sp = Serial_Port() sp.program() if __name__ == '__main__': main()
I don't know why it doesn't work nor why only without the event loop. With the event loop, after sending the data, it just does nothing. Please help.
-
Hello. I have this program here:
import sys from time import sleep from PySide6 import QtSerialPort as qts from PySide6 import QtCore as qtc class Serial_Port(): def __init__(self): self.port = qts.QSerialPort() self.port.setBaudRate(qts.QSerialPort.Baud38400) self.port.readyRead.connect(self.on_receive) self.port.errorOccurred.connect(self.on_error) qtc.QTimer.singleShot(0, self.program) def program(self): print(self.con_discon()) order = [0x86, 0x01] for o in order: self.send(o.to_bytes()) sleep(0.001) print("fin") def con_discon(self): if self.port.isOpen(): self.port.close() return False else: for port in qts.QSerialPortInfo.availablePorts(): if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433': self.port.setPort(port) break return self.port.open(qtc.QIODeviceBase.ReadWrite) def send(self, data): print("send: ", data) self.port.write(data) def on_receive(self): print('!') print("message: ", self.port.read(2)) def on_error(self, error): print("Serial port error:") print(error.name) exit() def main(): if not qtc.QCoreApplication.instance(): app = qtc.QCoreApplication(sys.argv) else: app = qtc.QCoreApplication.instance() Serial_Port() app.exec() if __name__ == '__main__': main()
It's supposed to send 0x86 and then 0x01 through serial port and get an answer from a device. I know the device is working correctly, because the answer is showing up with Termite and, interestingly, when I run this program without an event loop, which looks like this:
import sys from time import sleep from PySide6 import QtSerialPort as qts from PySide6 import QtCore as qtc class Serial_Port(): def __init__(self): self.port = qts.QSerialPort() self.port.setBaudRate(qts.QSerialPort.Baud38400) self.port.readyRead.connect(self.on_receive) self.port.errorOccurred.connect(self.on_error) def program(self): print(self.con_discon()) order = [0x86, 0x01] for o in order: self.send(o.to_bytes()) sleep(0.001) self.port.waitForReadyRead() print("fin") def con_discon(self): if self.port.isOpen(): self.port.close() return False else: for port in qts.QSerialPortInfo.availablePorts(): if port.manufacturer() == 'STMicroelectronics' and port.serialNumber() == '0668FF505271754867083433': self.port.setPort(port) break return self.port.open(qtc.QIODeviceBase.ReadWrite) def send(self, data): print("send: ", data) self.port.write(data) def on_receive(self): print('!') print("message: ", self.port.read(2)) def on_error(self, error): print("Serial port error:") print(error.name) exit() def main(): sp = Serial_Port() sp.program() if __name__ == '__main__': main()
I don't know why it doesn't work nor why only without the event loop. With the event loop, after sending the data, it just does nothing. Please help.
wrote on 26 Feb 2025, 10:13 last edited by@Adar70
Maybe you are doing the above (mostly) in your first code, I looked initially at your second.Meanwhile, I am worried about your Python lifetime of the instance you create in first code via plain
Serial_Port()
call. You do not assign return result to any variable. If I am not mistaken, won't the createdSerial_Port
instance be destroyed immediately after return fromSerial_Port.__init__()
? Not certain whether theqtc.QTimer.singleShot(0, self.program)
will keep it alive. Even if it does, it may die before the reply bytes are received, at least with nowaitFor...()
. Verify if that is the case, do something to keep theSerial_Port
instance around? -
@Adar70
Maybe you are doing the above (mostly) in your first code, I looked initially at your second.Meanwhile, I am worried about your Python lifetime of the instance you create in first code via plain
Serial_Port()
call. You do not assign return result to any variable. If I am not mistaken, won't the createdSerial_Port
instance be destroyed immediately after return fromSerial_Port.__init__()
? Not certain whether theqtc.QTimer.singleShot(0, self.program)
will keep it alive. Even if it does, it may die before the reply bytes are received, at least with nowaitFor...()
. Verify if that is the case, do something to keep theSerial_Port
instance around?wrote on 26 Feb 2025, 11:01 last edited by@JonB Thanks for the reply. After putting the call to
Serial_Port()
in a variable likesp = Serial_Port()
in the code with event loop it worked. Sadly the amount of times the readyRead signal is emitted is unreliable. Sometimes it's two, sometimes it's three. I don't know how to make it more robust. Could you help with that? -
@JonB Thanks for the reply. After putting the call to
Serial_Port()
in a variable likesp = Serial_Port()
in the code with event loop it worked. Sadly the amount of times the readyRead signal is emitted is unreliable. Sometimes it's two, sometimes it's three. I don't know how to make it more robust. Could you help with that?@Adar70 said in readyRead signal not activating while using QSerialProt:
I don't know how to make it more robust
Don't rely on the number of times readyRead is emitted. Instead accumulate the received data until you received all you expect to receive.
-
1/5