QSerialPort changing baudrate while operating.



  • Hi folks,

    I am a bit bored because of a problem nowadays. The problem I had is that, I need to communicate with a device which uses a serial protocol that works in a manner of request-response. For example:

    host: what is your id,
    device: my id is ....
    host: give me all logs
    device: ok, change your baud to ...., i will send all the logs at a higher baud rate than we are communicating at this moment.
    -> host needs to change baudrate at this step ***
    -> device is changing its baud automatically and sends

    So, I need to change the baudrate of host side at *** this step. I am using serialPort->setBaudRate(newBaud), also i am waiting for baudRateChanged signal in an event-loop. But the communication fails except a situation. The exception, if I wait let's say 200 ms using QThread::msleep before changing baudrate, the communication will success. In addition I am calling waitForBytesWritten after any write to the serial port.

    Is there any idea?

    Thanks.


  • Qt Champions 2018

    Hi @biomed12,

    • Which platform are you on? Some platforms may not allow changing the baudrate when the port is open
    • Which Qt version is that?
    • Are you running QtSerialPort in a thread? If not, please don't use the waitFor... functions, but rather signals&slots. Same applies for msleep(), rather use QTimer.

    But the communication fails except a situation.

    What does that mean?

    Regards



  • @aha_1980

    -Platform: Windows 10 64-bit Single Language
    -Qt 5.10+
    -Serial port is running in different than gui thread. So, it has its own.

    "But the communication fails except a situation." The exceptional situation:
    I am calling setBaudRate and waiting a bit about 200 ms, than communication is successful. But I need to change immediately when the device says "change your baud". The task is time critical.

    In my opinion, i need to guarantee the completion of baud change. I am sure that the platform allows baud changing while operating.

    Thanks.


  • Qt Champions 2018

    @biomed12

    The task is time critical.

    Then it's impossible to do on Windows. Dot.

    Let me ask some further questions:

    • is this your device or something you've got from a third party?
    • if third party, do they have example code?
    • is this a real RS-232, or some USB-232 converter?
    • which are the baud rates involved?
    • how long is the command string you send that executes: "give me all logs"
    • and how long is the time after the "give me all logs" command until the device sends the logs

    I think the last two question are the critical parts. As Windows has the same baud rate in both directions, you cannot change the receive baudrate before your command is completely sent out. As there may be several layers with buffers, that is a challenging task.

    Regards



  • @aha_1980

    This is my fault. I did not use the "time critical" term for its real meaning. Apologise for it.

    I found the problem. The device I am using has FTDI serial to usb convertor. So, according to my researchs, most of the serial convertor chips need to delay between baud switching. So, I compansated problem at this moment. But I do not know the exact solution. Maybe some serial interface functions in QSerialPort like "isDataTerminalReady" help me but I do not have any idea.

    how long is the command string you send that executes: "give me all logs": just 6 chars.
    and how long is the time after the "give me all logs" command until the device sends the logs - let's say 200 ms

    Thanks.


  • Qt Champions 2018

    @biomed12 said in QSerialPort changing baudrate while operating.:

    how long is the command string you send that executes: "give me all logs": just 6 chars.
    and how long is the time after the "give me all logs" command until the device sends the logs - let's say 200 ms

    You still didn't mention the baud rate before and after the switch... but Ok, even with a slow baud rate like 1200 this string is sent out in 50 milliseconds.

    But I do not know the exact solution. Maybe some serial interface functions in QSerialPort like "isDataTerminalReady" help me but I do not have any idea.

    Without more information about the hardware and the protocol - that's impossible to tell.

    Regards



  • @aha_1980

    The initial baud is 300. I am sending two messages at this baudrate. First one has 5 chars, second one has 6 chars. After that, I am switching baud to 9600.

    Thanks.

    Edit:

    I think, the occurence I had is not a problem. Thanks to the aha_1980, I realized that-I am not sure whether it is true or not- I need to wait until serial convertor chip completes the transfer. Let's say, I send the 6 bytes TX message in 300 baud using serial->write(message). If i change the current baud to 9600 immediately, the FTDI serial convertor chip changes the baud to he 9600 without waiting actual physical transfer complete. So, "in my opinion" this causes semi-corrupted message delivered to the target device. Because, 6 bytes of data takes about 200ms in 300 baud.

    Thanks.



  • If i change the current baud to 9600 immediately, the FTDI serial convertor chip changes the baud to he 9600 without waiting actual physical transfer complete.

    Of course, all Qt's QIODevice's derived classes by design implement the asynchronous I/O. Same with QSerialPort, the write() method just put a data to the internal buffer of QSerialPort. The data will be transferrd later, when a device descriptor becomes ready for that. You can use bytesWritten() signal to know that a data were transferred. But this is an 'indirect' assumption, because in reality the data can be in the transferring progress on the lowest layer (e.g. on hardware layer), when the bytesWritten() triggered. So, you can add a small delay with QTimer, after the bytesWritten() signal. Or to check how much bytes still in TX driver queue, after bytesWritten() signal, using system API (e.g. FIONWRITE flag wich ioctl() call on NIX, or ClearCommError() function with COMSTAT structure on Windows), and then to start QTimer in case the FIFO still has a bytes. For FTDI it should work, I assume.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.