Update: see the bottom of this answer for an answer. TL DR: you set the baud rate (and, presumably, all other settings) after opening the port.
I believe this is a bug in implementing QSerialPort on Windows. I have not been able to narrow down the cause, but I have the following symptoms:
Download Arduino (Uno in my case, Leonardo can behave very differently) with an ASCII demo. Disconnect and replace the Arduino. Please note that the TX indicator does not light.
Connect to it using a Putty or Arduino monitor. This resets the Arduino and then prints the ASCII table. The TX indicator is lit continuously as expected.
Disconnect / replace Arduino and this time connect to it using the QSerialPort program. This time, despite opening the port, the TX indicator never lights up, and readyRead()
never fires. Also note that Arduino does not reset, because by default QSerialPort does not change the DTR. If you do QSerialPort::setDataTerminalReady(false);
, then pause for 10 ms, then set it to true
, it will reset Arduino as expected, but it still doesn't transmit.
Note that if you have an Arduino program that continuously transfers data (the ASCII example stops), if you open the port with putty to start the transfer, and then open it with QSerialPort without disconnecting the cable, it will work! However, once you disconnect the cable / cable, it will stop working again.
This makes me suspect that putty sets the serial port parameter, which is required for arduino and reset when reconnecting the cable. QSerialPort obviously does not change this value.
Here are the Putty settings, as far as I can tell:
dcb.fBinary = TRUE; dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.fDsrSensitivity = FALSE; dcb.fTXContinueOnXoff = FALSE; dcb.fOutX = FALSE; dcb.fInX = FALSE; dcb.fErrorChar = FALSE; dcb.fNull = FALSE; dcb.fRtsControl = RTS_CONTROL_ENABLE; dcb.fAbortOnError = FALSE; dcb.fOutxCtsFlow = FALSE; dcb.fOutxDsrFlow = FALSE; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; dcb.BaudRate = ...; dcb.ByteSize = ...;
And QSerialPort :
dcb.fBinary = TRUE; dcb.fDtrControl = unchanged! dcb.fDsrSensitivity = unchanged! dcb.fTXContinueOnXoff = unchanged! dcb.fOutX = FALSE; dcb.fInX = FALSE; dcb.fErrorChar = FALSE; dcb.fNull = FALSE; dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fAbortOnError = FALSE; dcb.fOutxCtsFlow = FALSE; dcb.fOutxDsrFlow = unchanged! dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; dcb.BaudRate = ...; dcb.ByteSize = ...;
Therefore, I think that this should be one of the immutable values, which makes Arduino think that it is not connected. From the DCB documentation I suspect fTxContinueOnXoff
.
Well, I will write a small program to read these settings and see what changes.
Update 1
Well, I wrote my program and made the following discovery. The differences after the putty was launched and my Qt program were as follows:
- BaudRate: THIS WASN'T INSTALLED BY QT !!!!!!! It turns out that you can set the baud rate only after opening the port. . Otherwise, it will remain at the previous value, which will be 0 when you first connect the cable.
- fDtrControl: Set the value 1 to Putty, remaining 0 to Qt.
- fOutX and fInX: both are also set to 1 by Putty and remain at 0 by Qt.
After moving all my calls to the set...()
function after opening it worked fine. I didn't have to bother with DtrControl or Out / InX. (Although I also set the DTR high manually.)
Update 2
When configuring all the parameters that, as I thought, it would be nice to set the skip for the error policy. DON'T DO IT! LEAVE IT ON IGNOR! Otherwise, he fucks everything and adds weird delays to all of your communications.